Wie liest man die Werte des Struct in Solidity-Vertrags?

Ich habe den folgenden Smart Contract entwickelt und versuche ihn über die truffle js-Konsole zu testen:

pragma solidity ^0.4.2;

contract AddressRatings {

struct Rating {
    mapping ( address => uint8 ) ratings;
    uint256 amtOfRatings;
    uint256 sumOfRatings;
    uint8 average;
}

mapping ( address => Rating ) public ratings;

function rateAddress (address _addr, uint8 _rating) external {
    require(_rating > 0 && _rating < 6); // only ratings from 1 to 5 are allowed
    require(ratings[_addr].ratings[msg.sender] == 0); // a sender can rate someone else only once
    ratings[_addr].ratings[msg.sender] = _rating;
    ratings[_addr].amtOfRatings++;
    ratings[_addr].sumOfRatings += _rating;
    ratings[_addr].average = uint8(ratings[_addr].sumOfRatings/ratings[_addr].amtOfRatings);
}

}

Ich kann eine Instanz des Vertrags abrufen und die Methode rateAddress aufrufen. Außerdem kann ich ein Objekt der Bewertungszuordnung abrufen. Ich weiß jedoch nicht, wie ich die Attribute der zurückgegebenen Rating-Struktur lesen soll.

Was auch immer ich versuche, gibt undefinierte Ergebnisse zurück, zB ratingsObj 1 , ratingsObj['average'], ratingsObj.average

Geben Sie hier die Bildbeschreibung ein

Außerdem scheint das Mapping innerhalb der Struktur nicht zu funktionieren, obwohl es kompiliert ...

Jeder Hinweis ist willkommen!

PS: Vorschläge, wie dieser Vertrag effizienter gestaltet werden kann, sind sehr willkommen.

Antworten (2)

Das Problem ist, dass Ihr struct Ratingeine mapping. Solidity kann kein Mapping von Funktionen zurückgeben, da es keine Ahnung hat, wie groß es ist. Es kann jedoch die einzelnen Einträge zurückgeben, die den Schlüsseln zur Verfügung gestellt werden. Sie sollten wahrscheinlich verfolgen, ob eine Adresse eine Adresse auf andere Weise bewertet hat. So würde ich es machen:

pragma solidity ^0.4.23;

contract AddressRatings {

    struct Rating {
        uint256 amtOfRatings;
        uint256 sumOfRatings;
        uint8 average;
    }

    mapping(address => mapping(address => uint8)) public ratingsPerAddress;

    mapping (address => Rating ) public ratings;

    function rateAddress (address _addr, uint8 _rating) external {
        require(_rating > 0 && _rating < 6); // only ratings from 1 to 5 are allowed
        require(ratingsPerAddress[_addr][msg.sender] == 0); // a sender can rate someone else only once

        ratingsPerAddress[_addr][msg.sender] = _rating;

        ratings[_addr].amtOfRatings++;
        ratings[_addr].sumOfRatings += _rating;
        ratings[_addr].average = uint8(ratings[_addr].sumOfRatings/ratings[_addr].amtOfRatings);
    }

}
Danke für deinen Vorschlag! Ich kann die Werte aus den Zuordnungen immer noch nicht über die Javascript-Konsole abrufen (siehe Screenshot). Hast du dazu einen Rat?
Sie sollten app.ratingsso aufrufen, wenn Sie das erste Element für das erste Konto abrufen möchten:app.ratings(web3.eth.accounts[0], 0)

Die Verwendung eines Versprechens zum Abrufen eines Bewertungsobjekts ermöglichte mir den Zugriff auf die Attribute mit einem Index. Die toNumber-Funktion gibt schließlich den Wert zurück :)

Geben Sie hier die Bildbeschreibung ein