3

This question is related to question

How can I modify bytes32 result to uint?

I'm trying to pass result to variable AA, but AA's value is always 0. Function getTest1 shows the right answer, but I can't pass that answer to variable AA.

contract Test {
    bytes32 lastblockhashused;
    uint lastblocknumberused;
    uint AA;

    function test() {
        lastblocknumberused = (block.number-1)  ;               
        lastblockhashused = block.blockhash(lastblocknumberused);
    }

    function getTest1() constant returns (uint) {
        return uint(lastblockhashused) & 0xfff;
    }

    function Test2() {
        AA=(uint(lastblockhashused) & 0xfff);
        return; 
    }

    function getTest2AA() constant returns (uint) {
        return AA;
    }
}
Matias
  • 1,109
  • 1
  • 10
  • 16

1 Answers1

4

Summary

The reason why your original example does not work is because:

  • The class is named class Test (with an uppercase T).
  • Your constructor function is named function test() (with a lowercase t), and will not be treated as the class constructor by the Solidity compiler.
  • The function function test(), not being the class constructor, does not get called when this contract is inserted into the blockchain, and the values of lastblocknumberused and lastblockhashused are initialised to the values of 0 and "0x0000...0000" respectively.
  • When calling the function Test2(), AA is calculated from the "0x0000...0000" value of lastblockhashused, and the result is 0.



The Non-Working Version

Here's the original code where the constructor function test() has a different name from the class class Test. The member variables have been made public to trace the problem.

This example does NOT work as expected.

contract Test {
    bytes32 public lastblockhashused;
    uint public lastblocknumberused;
    uint public AA;

    function test() {
        lastblocknumberused = (block.number-1)  ;               
        lastblockhashused = block.blockhash(lastblocknumberused);
    }

    function getTest1() constant returns (uint) {
        return uint(lastblockhashused) & 0xfff;
    }

    function Test2() {
        AA=(uint(lastblockhashused) & 0xfff);
        return; 
    }

    function getTest2AA() constant returns (uint) {
        return AA;
    }
}

Here's what I executed:

var testSource='contract Test { bytes32 public lastblockhashused; uint public lastblocknumberused; uint public AA; function test() { lastblocknumberused = (block.number-1) ;  lastblockhashused = block.blockhash(lastblocknumberused); } function getTest1() constant returns (uint) { return uint(lastblockhashused) & 0xfff;  } function Test2() { AA=(uint(lastblockhashused) & 0xfff); return;  } function getTest2AA() constant returns (uint) { return AA; }}'

var testCompiled = web3.eth.compile.solidity(testSource);

var testContract = web3.eth.contract(testCompiled.Test.info.abiDefinition);
var test = testContract.new({
    from:web3.eth.accounts[0], 
    data: testCompiled.Test.code, gas: 2000000}, 
    function(e, contract) {
      if (!e) {
        if(!contract.address) {
          console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined...");
        } else {
          console.log("Contract mined! Address: " + contract.address);
          console.log(contract);
        }
    }
})

Waited for:

Contract mined! Address: 0x75774a4837e268ea63ba5544160c9a56f96da558

Confirming that the call to the constructor test() DID NOT RUN :

> test.lastblocknumberused()
0
> test.lastblockhashused()
"0x0000000000000000000000000000000000000000000000000000000000000000"
> test.AA()
0



The Working Version

Here is the modified code where the constructor function Test() has the exact same name as the class name class Test. The member variables have been made public to trace the problem. This example works as expected:

contract Test {
    bytes32 public lastblockhashused;
    uint public lastblocknumberused;
    uint public AA;

    function Test() {
        lastblocknumberused = (block.number-1)  ;               
        lastblockhashused = block.blockhash(lastblocknumberused);
    }

    function getTest1() constant returns (uint) {
        return uint(lastblockhashused) & 0xfff;
    }

    function Test2() {
        AA = (uint(lastblockhashused) & 0xfff);
    }

    function getTest2AA() constant returns (uint) {
        return AA;
    }
}

Here is what I executed:

> var testSource='contract Test { bytes32 public lastblockhashused; uint public lastblocknumberused; uint public AA; function Test() { lastblocknumberused = (block.number-1) ;  lastblockhashused = block.blockhash(lastblocknumberused); AA = 1; } function getTest1() constant returns (uint) { return uint(lastblockhashused) & 0xfff; } function Test2() { AA = (uint(lastblockhashused) & 0xfff); } function getTest2AA() constant returns (uint) { return AA; }}'

> var testCompiled = web3.eth.compile.solidity(testSource);

> var testContract = web3.eth.contract(testCompiled.Test.info.abiDefinition);
var test = testContract.new({
    from:web3.eth.accounts[0], 
    data: testCompiled.Test.code, gas: 2000000}, 
    function(e, contract) {
        if (!e) {
            if(!contract.address) {
              console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined...");
        } else {
            console.log("Contract mined! Address: " + contract.address);
            console.log(contract);
        }
    }
})

Waited for:

Contract mined! Address: 0x307001bf417b42433e0c8d08ef73f08a3dd874c6

Confirming that the call to the constructor Test() ran :

> test.lastblocknumberused()
9875
> test.lastblockhashused()
"0x20de2b012e7f7fe9fbce0d87a2b2565c8152e91106ed22306eb5318b394ad8dd"
> test.AA()
1

Ran Test2():

> test.Test2(eth.accounts[0], {
  from:web3.eth.accounts[0], 
  data: testCompiled.Test.code,
  gas: 1000000
});
"0x76fcaf7784ea002cf4b89e65b016c5954e9fa3f0baf1a40f1782e775eb481667"

> test.lastblocknumberused()
9875
> test.lastblockhashused()
"0x20de2b012e7f7fe9fbce0d87a2b2565c8152e91106ed22306eb5318b394ad8dd"
> test.AA()
2269
BokkyPooBah
  • 40,274
  • 14
  • 123
  • 193