1

Here is the contract, function being called is voteForCharacter:

pragma solidity ^0.4.19;


contract CharacterEveryDay {

event CharacterSelected(uint8 _character, uint64[256] characterVotes, uint64 day);

uint64[256] public characterVotes;

uint8 public winningCharacter;
uint64 public day; 
uint256 public winningCharacterVotes;
uint256 public timeOfLastVote;

mapping (uint256 => bool) addressVotedToday;

constructor (uint8 _character) public {
    day = 0;
    winningCharacterVotes = 0;
    timeOfLastVote = now;
    voteForCharacter(_character);
}

modifier onlyCharacter(uint256 _character) {
    require(_character < 256);
    _;
}

function voteForCharacter(uint256 _character) public onlyCharacter(_character) {
    if ((now - timeOfLastVote) > 1 days) {
        selectCharacter(winningCharacter);
    }

    uint256 todaysAddressHash = uint(keccak256(abi.encodePacked(day, msg.sender)));
    require(addressVotedToday[todaysAddressHash] == false);

    characterVotes[_character]++;
    if (characterVotes[_character] > winningCharacterVotes) {
        winningCharacter = uint8(_character);
        winningCharacterVotes = characterVotes[_character];
    }
    addressVotedToday[todaysAddressHash] = true;
    timeOfLastVote = now;
}

function getCharacterVotes() external view returns (uint64[256]) {
    return characterVotes;
}

function selectCharacter (uint8 _winningCharacter) private {
    day += uint64((now - timeOfLastVote) / 1 days);
    emit CharacterSelected(_winningCharacter, characterVotes, day);
    delete characterVotes;
    delete winningCharacter;
    delete winningCharacterVotes;
}
}

FROM WEB3:

When I run it for the first time in a day, when the require passes:

require(addressVotedToday[todaysAddressHash] == false);

the gas estimate on MetaMask is reasonable and the functions succeeds: 0.000294 eth ($.05)

If I run it again in the same day with the same address, which means the require will fail, the gas cost becomes unreasonable: 2850000 eth ($500 millionish)

If I use a different address on the same day, the gas estimate becomes reasonable.

FROM REMIX:

The gas estimate stays reasonable, but after the first vote the function will fail not because the require fails, but because it runs out of gas.

  • The very high cost is likely a limitation/bug of MetaMask. There wasn't an standard way to determine the exact cause of failure of a transaction, so most interfaces will show "out of gas" as a wildcard. Now there's the possibility of passing a message when require will fail, but it is not widely implemented yet. – Ismael Sep 11 '18 at 15:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.