0

I am trying to create a leaderboard depending upon who has received maximum votes. I have implemented the following code:

function dashboard(bytes32[] candidateListNew) public returns(bytes32[])
        { for(uint i = 0; i < candidateListNew.length; i++){
        for(uint j = i+1; j < candidateListNew.length; j++){
            if(votesReceived[candidateListNew[i]] > votesReceived[candidateListNew[j]]){
                uint8 temp = votesReceived[candidateListNew[j]];
                votesReceived[candidateListNew[j]] = votesReceived[candidateListNew[i]];
                votesReceived[candidateListNew[i]] = temp;
        }
      }
    }
    return votesReceived[candidateListNew]; //gives me conversion type error
 } 

struct voter {
     bytes32 votedFor;
     bool hasVoted;
  }

  mapping (bytes32 => uint8) public votesReceived;
  // Mapping for persons who have already voted
  mapping (bytes32 => voter) public voters;

  bytes32[] public candidateList;
  bytes32[] public candidateListNew;

I am able to sort the values but I am having difficulty sorting the keys(candidate names) based on the values.

Any help would be appreciated. Thank you!!

  • return votesReceived[candidateListNew]; the type error is obvious. Your mapping goes from bytes32 to uint8 and you are using candidateListNew as index, which is an array of bytest32 and not a bytes32 as expected. – Briomkez Jul 31 '18 at 15:46
  • I am aware of that. but i am unable to map values to the keys. Is there some way to loop over mappings??? – softwareDeveloperInProgress Jul 31 '18 at 15:49
  • 1
    I think it is not possible, the only way is to keep a list of keys as explained here: ethereum.stackexchange.com/questions/12145/… – Briomkez Jul 31 '18 at 16:13
1

This is almost certainly a bad idea.

It's not a matter of sorting out trivial type conversions or choosing between bubble sort or some more efficient approach. It's more fundamental.

Here's the problem. No matter what you do, there is a list size n at which point iteration (or recursion) will result in a gas price over the block gasLimit. This is the point at which the contract will fail. In other words, the process will not scale because the number of operations increases with the size of the set to sort. You can possibly move the limit and reduce the rate at which you approach it by a more efficient sort. Doing so doesn't change the fact that the system will fail at a certain size.

To ensure scalability, you need to restrict yourself to stable process with exactly 1 operation at any scale, sometimes written as O(1).

You didn't describe the use-case so it's not possible to offer more specific guidance. The process needs to be re-imagined in a way that externalizes the sorting concern. There is seldom a good reason for sorting to be an on-chain concern. In the rare case that it might be on on-chain concern, consider linked lists or a similar process that can be implemented with a fixed maximum gas cost of each insertion. By "fixed", I mean the worst case gas cost must be the same at any scale, no matter how many records exist.

This situation is fairly routine. I wrote about over here: https://blog.b9lab.com/the-joy-of-minimalism-in-smart-contract-design-2303010c8b09

Hope it helps.

0

On your conversion type error , your return argument type must be uint8[] .

function dashboard(bytes32[] candidateListNew) public returns(uint8[])

Or you can cast to bytes32.

unsigned integers are convertible to bytes of a similar or larger size, but not vice-versa.

Example:

function toBytes(uint8 x) returns (bytes b) {  
    b = new bytes(32);  
    assembly {   
  mstore(add(b, 32), x)  
    }  
}

On specific to your second question, It is difficult to sort key on mapping in solidity. unless you know the exact key, you cannot range based on upper and lower bound of the key.
We always be careful on loop in solidity. In your specific problem key is bytes32 and now this may make serious problem due to gas cost and gas limit of the system and nature of EVM, ultimately transaction cannot be execute properly or may halt the system.

  • is there a way to display the votes in decreasing/increasing order?? – softwareDeveloperInProgress Jul 31 '18 at 18:47
  • there might be possible way but I have no idea that we implement in solidity. Comparing one to another and make a loop which directly halt the system this is not good idea for contract developer. – Gopal ojha Aug 1 '18 at 5:58

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.