Solidity: Struct with three string fields is not stored in a private blockchain

Created on 18 May 2016  路  11Comments  路  Source: ethereum/solidity

This is similar to #381, but I'm not using sha3 for the mapping, just directly an uint.

The contract does work with two strings fields, but it will fail with three strings fields. Also tried with an array of three strings, and another struct with three strings, they also fail.

contract test {
    struct data {
        bool used;
        string data1;
        string data2;
        string data3;
    }
    mapping(uint => data) public store;
    function write(uint id, string data1, string data2, string data3) public {
        store[id].used = true;
        store[id].data1 = data1;
        store[id].data2 = data2;
        store[id].data3 = data3;
    }
    function read(uint id) public returns (string, string, string) {
        return (store[id].data1, store[id].data2, store[id].data3);
    }
}
  • With two strings fields: After mining test.write.sendTransaction(1,"marco","polo",{from:eth.accounts[0]}) then test.store.call(1) it will return [true, "marco", "polo"].
  • With three strings fields: after mining test.write.sendTransaction(1,"marco","polo", "extra",{from:eth.accounts[0]}). When trying to retrieve it with test.store.call(1) it will return [false, "", "", ""].

This does happen with the latest version of geth and solc running in Ubuntu xenial, in a private network.

$ geth version
Geth
Version: 1.4.3-stable
Protocol Versions: [63 62 61]
Network Id: 1
Go Version: go1.6.1
OS: linux
GOPATH=
GOROOT=/usr/lib/go-1.6
$ solc --version
solc, the solidity compiler commandline interface
Version: 0.3.2-0/Release-Linux/g++/Interpreter

Most helpful comment

The issue was that the transaction didn't have enough gas and failed.

All 11 comments

I was not able to reproduce this in browser-solidity. My guess is that the transaction data is not encoded correctly. Can you try to inspect the network traffic and post the actual transaction data here?

Do you have to use a specific tool for this or a tcpdump should be ok?

Here are the files I have used to test this https://gist.github.com/ismaelbej/2d9ca7ad0ec3dff61a235fb53df43b1f

The capture with tcpdump of the write call
tcpdump.zip

Data looks good. I think remix is not yet ready to process geth vm traces, but that could be worth a try.

Ok, I will try to get traces from geth.

Here is the trace

trace.zip

I've also tested the contract with EthereumJ (https://github.com/ethereum/ethereumj), and the result is the same write seems to work but read returns empty strings.

I kind of found a workaround. It does work when I split the write function into a pair write1/write2, each writing at most two string.

struct data {
        bool used;
        string data1;
        string data2;
        string data3;
        string data4;
}
mapping(uint => data) public store;
function write1(uint id, string data1, string data2) public {
        store[id].used = true;
        store[id].data1 = data1;
        store[id].data2 = data2;
}
function write2(uint id, string data3, string data4) public {
        store[id].data3 = data3;
        store[id].data4 = data4;
}

The issue appears when I try to modify more than two string fields from the same public function.

Sorry, I should have been more specific: The trace you generated is a go-internal trace. What I would need is an ethereum vm trace.

@chriseth have you tried to reproduce this issue on your side?

I've deployed in the testnet, and there it works!.

Here is the transaction with the write('marco','polo','extra') operation
http://testnet.etherscan.io/tx/0x3131f8e3470cac76b115b479b01089e09b6eac4caf50ab8e860395dc8890ac51

So it seems to be a problem with my private testnet. Here is my genesis.json

{
  "nonce": "0xdeadbeefdeadbeef",
  "timestamp": "0x00",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x686f727365",
  "gasLimit": "0x8000000",
  "difficulty": "0x0400",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x3333333333333333333333333333333333333333",
  "alloc": {
    "0xdaf4d67ce026ac29302325916d97a27b880a45db": {
      "balance": "10000000000000000000"
    },
    "0xe90c480fe05b41ee0c3d921d2cf3c214c69a395f": {
      "balance": "1606938044258990275541962092341162602522202993782792835301376"
    }
  }
}

I will generate a new private testnet, and try again. One of the reasons to use a private testnet is to automate deployment and testing.

The issue was that the transaction didn't have enough gas and failed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

axic picture axic  路  3Comments

chriseth picture chriseth  路  3Comments

madvas picture madvas  路  3Comments

chriseth picture chriseth  路  3Comments

chriseth picture chriseth  路  4Comments