6

I am defining a contract and I want to ensure a particular member variable can only be modified by me. So, specifically I want to ensure that if someone else deploys one of my contracts, then they will not be able to modify this variable.

To do this I tried to hard-code my address, and test against msg.sender in the setter

contract Sample {
  address constant public myAddress = 0xe0f5206bbd039e7b0592d8918820024e2a7437b9;
  uint public vari;
  function setVari(uint a) {
    if(msg.sender == myAddress) {
      vari = a;
    }
  }  
}

When I compile this, I get the following error

Warning: This looks like an address but has an invalid checksum. If this is not used as an address, please prepend '00'.
      address constant public myAddress = 0xe0f5206bbd039e7b0592d8918820024e2a7437b9;
                                          ^----------------------------------------^

And when I try to modify this variable within geth using

myInstance.setVari.sendTransaction(22, {from: eth.accounts[0]})

the value of "vari" is not updated. (Where eth.accounts[0] is the hardcoded address in the source.)

However, if I remove the protection within setVari(), everything works as expected.

This implies to me that everything I'm doing is correct, except the hard-coding of my address.

Can anyone help? How do I hard code my account into a contract?

Thanks!


Note: the address included is one I'm using on a private test network, so you won't be able to find it in the public network. However, I got the same compiler warning when I tried hard-coding one of my real accounts addresses.

9

Enter your address in https://etherscan.io/ and copy the uppercase/lowercase checksummed version and paste it into your solidity code.

contract Sample {
  address constant public myAddress = 0xE0f5206BBD039e7b0592d8918820024e2a7437b9;
  uint public vari;
  function setVari(uint a) {
    if(msg.sender == myAddress) {
      vari = a;
    }
  }  
}

And the warning message will disappear. The compiler checks the checksummed address for validity.

But I just checked your code with the checksummed address in Remix and I get a new warning message:

Untitled4:4:39: Warning: Initial value for constant variable has to be compile-time constant. This will fail to compile with the next breaking version change.
  address constant public myAddress = 0xE0f5206BBD039e7b0592d8918820024e2a7437b9;
                                      ^----------------------------------------^

This second error will disappear if you remove the constant modifier.

  • 1
    This worked. Thank you. A quick follow on question: Do you know how to define a compile-time constant (as presumably this would be preferable to removing the constant modifier)? – ianinini Jun 2 '17 at 8:26
  • 1
    This presents as non-intuitive. An address literal should by definition be constant and not run-time variable. An issue has been raised on the Solidity GH repo – o0ragman0o Jun 22 '17 at 4:42
  • o0ragma0o: thanks for reporting this. I see the issue you raised is now closed. I wasn't clear on the conclusion. Does that mean we can expect it to be fixed in a subsequent release? – ianinini Jun 24 '17 at 22:04
  • You can use Oracle to create compilation-time variable then used to send ether or create address with some clear for nodes algorithm that will create the same result on every node. Otherwise random address could stop all network because all nodes running your code result with different result and cannot go to consensus. – Xawery Wiśniowiecki Jul 22 '18 at 11:29

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.