I have 3 admins in my ethereum contract and voting system. Any admin can start a new voting, for example for changing admin addresses, allowing to transfer tokens from main wallet (by default they are locked), and few more. When 2 admins vote for yes, vote will proceed, if no, voting will be cancelled. If one admin will vote yes, other no, and third won't do anything, others can vote for cancel the current voting. There can be only one active voting at once (vote cancelling is an exception).

For now it's working, but it's, I guess, expensive. For each start voting I made a different function, for example:

function startVoteForChangeBuySellPrice(uint buyPrice, uint buyAddUnits, uint sellPrice, uint sellAddUnits, bool ignoreSecurityLimits) external onlyAdmin
    uint sellTotalPrice = sellAddUnits * sellPrice;
    require(voteType == VoteType.NONE);
    require(buyPrice >= sellPrice);
    require(sellTotalPrice <= weiFromExchange);
    voteType = VoteType.CHANGE_BUY_SELL_PRICE;
    voteReturnData[0].uintData = buyPrice;
    voteReturnData[1].uintData = buyAddUnits;
    voteReturnData[2].uintData = sellPrice;
    voteReturnData[3].uintData = sellAddUnits;
    voteReturnData[0].boolData = ignoreSecurityLimits;
    voteId = voteId.add(1);

As you can see, for storing variables I made a mapping of increasing uint and struct, which holds uint, address, bool and string.

Later in the code, if voting is succeeded with 2/3, data is being read like this:

    else if(voteType == VoteType.CHANGE_BUY_SELL_PRICE)
        internalChangeBuySellPrice(va.uintData, voteReturnData[1].uintData, voteReturnData[2].uintData, voteReturnData[3].uintData, voteReturnData[0].boolData);

As I said, it's working as expected, but I want to make it more efficient with replacing VoteReturnData with single bytes array which will hold entire current voting data. How can I hold multiple types of multiple variables in one single bytes array and later, when I execute voting, get them from bytes array?

  • How did you declare voteReturnData and the struct you are using? Your struct seems needlessly verbose. And also, if you know the range of all that uint value, you can specify the bytes, and make good use of struct packing. See how storage layout works: solidity.readthedocs.io/en/v0.4.24/… – viz May 27 '18 at 23:40
  • You can of course use custom defined bytes to save your states, but in usual cases it's no worth. If you really need it, you can use bit masking or assembly to combine/separate those values. – viz May 27 '18 at 23:44
  • It's ` struct VoteReturnData { address addressData; uint uintData; string stringData; bool boolData; }` And: mapping(uint=>VoteReturnData) private voteReturnData; – Radeg May 28 '18 at 7:10
  • Why doing that? You could just declare something like struct ChangeBuySellPriceVote {uint8 buyPrice; uint8 buyAddUnits; uint8 sellPrice; uint8 sellAddUnits; bool ignoreSecurityLimits} and then ChangeBuySellPriceVote[] voteData – viz May 28 '18 at 10:15
  • Thanks viz, I just did that and the gas cost for executing contract has drastically dropped! – Radeg May 29 '18 at 8:20

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.