I have developed the following smart contract and try to test it via the truffle js console:
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);
}
}
I'm able to get an instance of the contract and call the method rateAddress. Also I can retrieve an object of ratings mapping. However, I don't know how to read the attributes of the returned Rating struct.
Whatever I try returns undefined e.g. ratingsObj1, ratingsObj['average'], ratingsObj.average
Also, it seems that the mapping within the struct does not to work, although it compiles…
Any hint is appreciated!
P.S.: Suggestions how to make this contract more efficient are very welcome.
Best Answer
The problem, is that your
struct Rating
contains amapping
. Solidity cannot return mapping from functions, as it has no idea how large it is. It can, however return the individual entries the keys are provided. You should probably keep track of whether an address has rated an address in another way. Here's how I would do it: