25
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 an error. The error I am facing is:

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

[Q] How could I fix this error?

27

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 help to take a look here: Blog: Simple Storage Patterns in Solidity

Hope it helps.

  • 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 '17 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. – Rob Hitchens Mar 13 '17 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? – Olshansk Jul 31 '17 at 0:30
  • I took a stab at explaining mappings here. medium.com/@robhitchens/solidity-crud-part-1-824ffa69509a – Rob Hitchens Jul 31 '17 at 3:16
1

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; 
    }
}
  • 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. – Rob Hitchens Mar 13 '17 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? – Rob Hitchens Mar 13 '17 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 '17 at 5:28

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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