I have the following use case. There's a smart contract based game where everyone can award 1 point to a color. At the end of the game, the smart contract reveals which color is the most popular/has gained the most points. Take the following Solidity code:
struct Color{
string colorName;
uint256 awardedPoints;
uint256 colorID;
}
mapping(uint256 => Color) private colorsMapping;
function awardPoint(uint256 colorID) public {
colorsMapping[colorID].awardedPoints++;
}
Of course, the mapping is marked with the "private" keyword, but that doesn't really stop determined people from revealing the content. Besides, everyone can count the calls for function awardPoint(colorID)
and deduce partial results.
What would be the best way of solving this with minimal changes to the code?
What I thought about:
function awardPoint(colorID)
, colorIDs are randomly shuffled. However, they are tied to the mapping already, so I don't really see a wait of implemnting this in Solidity. Besides, it wouldn't really solve the issue of someone revealing the data of the colorsMapping private variable.What approach would be the best?
My suggestion is to have everyone submit the hash of [colorid, secret]. When everyone has submitted answers, everyone reveals their chosen colorid and secret.
function submitHash(bytes hash) public {
hashes[msg.sender] = hash;
}
function submitAnswer(uint256 colorid, uint256 secret) public {
require(votesIn, "votes are not all in");
require(keccak256(abi.encodePacked(colorId, secret)) == hashes[msg.sender], "invalid response");
votes[colorId] += 1;
}