11

After I mine the following contract giving the array [true, true, true] as _bools I would expect [true, true, true] to be returned by getBools().

Instead [false, true, true] is returned.

Is there something obviously wrong I'm doing?

contract Broken {

    address creator;
    uint public aInt;
    bool[3] bools;

    function Broken(uint _aInt, bool[3] _bools) public {
        creator = msg.sender;
        aInt = _aInt;
        bools = _bools;
    }

    function getBools() constant returns (bool[3]) {
        return bools;
    }

    function kill() {
        if (msg.sender == creator) suicide(creator);
    }

}

UPDATE:

Here is the script I'm using to run the contract: http://pastebin.com/h6588DXh

And the output I'm getting:

loadScript("broken.js")
I0404 11:32:43.290351    8448 xeth.go:1026] Tx(0xf66606023ae787621534949a7da16b04b3a26213a532deb16ab9bbd7c2e0bc43) created: 0x1f7099dd0c58678883e89066a95f313d4b4f40d1
I0404 11:32:43.291519    8448 miner.go:119] Starting mining operation (CPU=4 TOT=5)
I0404 11:32:43.298410    8448 worker.go:569] commit new work on block 54 with 1 txs & 0 uncles. Took 6.013736ms
I0404 11:32:43.437366    8448 worker.go:348]   Mined block (#54 / 755c7ff9). Wait 5 blocks for confirmation
I0404 11:32:43.437721    8448 worker.go:569] commit new work on block 55 with 0 txs & 0 uncles. Took 312.353µs
I0404 11:32:43.437750    8448 worker.go:447]    Mined 5 blocks back: block #49
I0404 11:32:43.923513    8448 worker.go:348]   Mined block (#55 / 1218fc33). Wait 5 blocks for confirmation
I0404 11:32:43.924200    8448 worker.go:569] commit new work on block 56 with 0 txs & 0 uncles. Took 322.033µs
I0404 11:32:43.924442    8448 worker.go:447]    Mined 5 blocks back: block #50
I0404 11:32:43.925031    8448 worker.go:569] commit new work on block 56 with 0 txs & 0 uncles. Took 256.09µs
I0404 11:32:44.335605    8448 worker.go:569] commit new work on block 56 with 0 txs & 0 uncles. Took 582.985µs
true
> Contract mined!
Bools given: true,true,true
Bools stored: false,true,true

Moreover if the constructor instead has the following signature:

function Broken(bool[3] _bools, uint _aInt) public

everything behaves as expected.

q9f
  • 32,913
  • 47
  • 156
  • 395
Ivan
  • 113
  • 4
  • What was the message that you sent to create the contract? – Loi.Luu Apr 04 '16 at 03:20
  • I suspect that your first true value is being used to initialise the uint _aInt parameter. You should be able to test out by trying the following: 1) the values [true, false, true] should return false, true, false; and 2) adding a fourth value [1, false, false, false] should return false, false, false. – BokkyPooBah Apr 04 '16 at 15:15
  • @BokkyPooBah 1) Confirmed with pure solidity code: [t,f,t] => [f,t,f]. 2) [t,f,f,f] => [f,t,f,f]. The byte array is shifted right. Is this expected behaviour? If so, where to learn more about it? – Denis Apr 04 '16 at 15:27
  • 3
    Looks like a bug to me. 'getBools' will return the correct values if you create a 'setBools' function and set it that way. – Andreas Olofsson Apr 05 '16 at 07:10
  • 1
    It's a bug. https://github.com/ethereum/solidity/issues/485 – q9f Apr 07 '16 at 20:00

1 Answers1

4

It's a critical bug in solc.

Ref: https://github.com/ethereum/solidity/issues/485

q9f
  • 32,913
  • 47
  • 156
  • 395