1

I want to have a mapping where it is only possible to add values when they are UNIQUE. It must not be possible to add duplicate keys, but I cannot get it working.

The code:

contract test {
    mapping(string => address) values;

    function AddValue(string randomValue) {
        require(values[randomValue] == 0x0);

        //execute transaction if randomValue doesn't exist
        //cancel transaction - payout if the randomValue exists 
    }
}

In this example I am trying to check whether the values[randomValue] is empty - doesn't exist. If it doesn't exist the code after may execute. If it DOES exist, the code must stop. However, I am unable to find a solution.

  • Working fine for me. You need to add a line like values[randomValue] = 0x1; (or whatever address) after the require() statement. Once you've done that it behaves exactly as you'd expect. – benjaminion Sep 8 '17 at 11:53
  • Thanks for reply :) & I do add msg.sender afterwards but left it out here. Also, I keep track of the length with a counter, which counts the length of the mapping. Everytime I add a randomValue that is already inside the mapping I get a metamask screen to confirm, I submit, it gets mined and the count increases. I have no idea what I am missing ;s ;s It seems like the require is doing nothing @benjaminion – guest7630763 Sep 8 '17 at 12:06
1

I've noticed in your example you use a string for key. Solidity uses the keccack256(key) as lookup value. So there's the case you have two different string mapping to the same value. (This is rare because it will mean you have found a collition of sha3).

If you have a mapping to a struct I'd use a boolean field to indicate an entry is used. An empty entry will such fields initially set to false.

struct Entry {
    bytes32 id;
    uint balance;
    bool used;
}

mapping (address => Entry) public collection;

function AddEntry(bytes32 _id, uint _balance) public {
    require(!collection[msg.sender].used);
    collection[msg.sender] = Entry(_id, _balance, true);
}

If you have a mapping to a value like address, you can check directly against an special value like address(0).

mapping (bytes32 => address) public users;

function AddUser(bytes32 id) public {
    require(users[id] != address(0));
    users[id] = msg.sender;
}
  • Thanks for your answer :) My problem was a malfunction with TestRPC or webpack (not sure yet, which of the two) I have the frequent issue where the new or edited code does not seem to be compiled and pushed correctly. In this case, I just have to relaunch TestRPC, delete the build folder and compile - migrate the contracts again. However, this example remains a best practice on the issue I created :) +1 – guest7630763 Sep 18 '17 at 8:35

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.