I have found a very interesting behaviour of the EVM and probably a missing check in solidity compilation.
Consider the following code:
contract RootContract { Simple public s; string public data; function RootContract() { s= new Simple();} function getSimpleData() constant returns(string out) { s.fillData(this); out=data; } function setData(string d) {data=d;} } contract Simple { string public data; function setData(string d ){data=d;} function fillData(RootContract r) public {r.setData(data);} }
The function getSimpleData is "constant" and therefore should not allow to modify any state data. But it calls Simple.fillData, that in turns call RootContract.setData.
But it compiles, and it works, except that the root contract data is not set, but the Simple contract data gets returned by the getSimpleData constant function.
> var comp=eth.compile.solidity("import '/Users/guenole/Ethereum/sources/Simple.sol';")
> var root=comp['/Users/xxx/sources/Simple.sol:RootContract']
> var RContract=contract(root.info.abiDefinition)
> var RContract=eth.contract(root.info.abiDefinition)
> var R=RContract.new( {from: eth.coinbase, data: root.code, gas:1000000})
> R.address // after mining
"0x51ecec3c403159dafc05538dc0783559772874d9"
> R.s()
"0x92f2700514a8ab3ac026d1d3119ab2677d1d083a"
> var simple=comp['/Users/xxx/sources/Simple.sol:Simple']
> var SContract=eth.contract(simple.info.abiDefinition)
> var S = SContract.at(R.s())
> S.setData("un test de chaine", {from: eth.coinbase, gas:100000})
> S.data() // after mining
"un test de chaine"
> R.getSimpleData() // without mining
"un test de chaine"
> R.data() // the data of R is not set
""
So this is actually odd. Anyone has a view that justify such behaviour? Now, the funny thing is that it tricks the EVM that is not able to have in RootContract a function like
function getSimpleData() constant returns(string) { return s.data(); // fails with usual Error: Return argument type inaccessible dynamic type is not implicitly convertible to expected type (type of first return variable) string memory }