61
pragma solidity ^0.4.8;

library Library {
  struct data {
     unit val;
   }
}

contract Array{
    using Library for Library.data;
    mapping(address => Library.data) clusterContract;
    
    function addCluster(address id) returns(bool){
        if (clusterContract[id] == address(0)) {  // error occurs!
            clusterContract[id] = list;
            return true;
        }
        return false; 
    }
}

Following comparission if (clusterContract[id] == address(0)) gives the following error:

Operator == not compatible with types struct Library.data storage ref and address
E               if(clusterContract[id] == address(0)) {...

How could I fix this error?

2 Answers 2

59

You can't directly find out if any key exists in a mapping, ever, because they all exist.

mapping(key => value) name;

creates a namespace in which all possible keys exist, and values are initialized to 0/false.

If you want to check that a value was explicitly set, and not merely the default (0), then you have to program something. In some cases, value > 0 is enough, but if 0 has meaning in your application, then another struct member can help ... bool isValue;, for example.

library Library {
  struct data {
     uint val;
     bool isValue;
   }
}

contract Array{
    
    using Library for Library.data;
    mapping(address => Library.data) clusterContract;

    function addCluster(address id) returns(bool){
        if(clusterContract[id].isValue) throw; // duplicate key
        // insert this 
        return true; 
    }
}

I noticed "addCluster" has the appearance of a contract factory (in progress), so you probably intend to keep track of contracts created as you go.

I assembled a little summary of different ways of organizing common data patterns in Solidity. It might be helpful to take a look here: Blog: Simple Storage Patterns in Solidity

Hope it helps.

4
  • Under // insert this I have to put clusterContract[id].isValue=true so when same id is provided on the next function call, it will enter into throw; right? And thank you for the the design patterns I will work on them. @RobHitchens.
    – alper
    Mar 13, 2017 at 16:06
  • 1
    Yes. Exactly. You explicitly mark it in a way that leaves no doubt about the data being "real". I just figured you were planning to press on and create a contract and then you would need a way to store the address ... or similar. Mar 13, 2017 at 16:22
  • Could you explain (or potentially point me to a resource) that explains this idea of creates a namespace in which all possible keys exist, and values are initialized to 0/false. What are the memory implications of this? Does it dynamically instantiate a struct when I try to access it?
    – Olshansky
    Jul 31, 2017 at 0:30
  • I took a stab at explaining mappings here. medium.com/@robhitchens/solidity-crud-part-1-824ffa69509a Jul 31, 2017 at 3:16
3

This solution seems working, but I am open to any advices.

In C following should not work since clusterContract[id].flag does not exist in the first call to create map for id. But in this example clusterContract[id].flag != 1 returns true at initial step to create map from id. After clusterContract[id].flagassigned to 1 clusterContract[id].flag != 1 returns false.

pragma solidity ^0.4.8;

library Library {
  struct data {
     uint val;
     uint8 flag;
   }
}

contract Array{
    using Library for Library.data;
    mapping(address => Library.data) clusterContract;

    function addCluster(address id) returns(bool){
        if(clusterContract[id].flag != 1 ){ 
            clusterContract[id] = list;
            clusterContract[id].flag = 1;
            return true;
        }
        return false; 
    }
}
3
  • Yes, it does exist and it defaults to false, so != 1/true. It doesn't need someone to set it in order to exist. In a mapping, all possible keys exist and corresponding values have zeroish defaults. Mar 13, 2017 at 16:41
  • Are you trying to track structs for entities that have predetermined addresses, such as users who enroll, or are you trying to create new contracts on demand? Or maybe a little bit of both? Mar 13, 2017 at 16:47
  • I am trying to do first one, like you said students who enroll. If the same user try to enroll again, contract should not allow since it has enrolled already. @RobHitchens
    – alper
    Mar 14, 2017 at 5:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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