I have written some Solidity code, with a setter method createId
to write a name-value pair to contract storage, and a getter method getPermissions
to get the value associated with a particular name. It works correctly in browser-solidity (In screenshot below, createId
was called before getPermissions
).
Then, I used the web3 Javascript API from a NodeJS app to send a contract-deploying transaction to a Parity (Ethcore) node, connected to a private chain. That transaction gets mined. Using the JSON RPC API eth_getTransactionReceipt
, I can get the transaction receipt, which has the contract address. However, when I send a JSON RPC API eth_getCode
request with the contract address, all I get is: { "jsonrpc": "2.0", "result": "0x", "id": 1 }
To test whether it is just the eth_getCode
not working correctly, I used the JSON RPC API eth_call
to call the setter (which has no return value) to set a value, but calling the getter returns an empty result, too. The screenshot shows that the correct value was returned by the getter in browser-solidity.
Is there something I am missing? Thanks a lot for your help.
EDIT: Some additional information. I compiled and deployed the following Solidity code:
contract test { function double(int a) returns(int) { return 2*a; } }
In this case, eth_getCode
returned the compiled code, given the contract address. Also, I invoked the double(int)
method twice (with 2 different input values) using eth_call
JSON RPC API, and got the correct return value in both cases.
Does that mean there is something wrong with the other contract's code (which is more complex than this test contract), even though it works correctly in browser-solidity? Are there any known issues in browser-solidity which would cause this? Does this give a hint about what problem in that contract could be?
The Solidity source, which works correctly in browser-solidity:
pragma solidity ^0.4.7;
contract owned {
address owner;
function owned() {
owner = msg.sender;
}
}
contract mortal is owned {
function kill() {
if (msg.sender == owner) selfdestruct(owner);
}
}
contract IdMgmt is mortal {
struct acl {
string dataType;
string permissions;
}
mapping (address => acl) public aclOf;
function IdMgmt() { }
function createId(address _user, string _dataType, string _permissions) {
aclOf[_user].dataType = _dataType;
aclOf[_user].permissions = _permissions;
}
function getPermissions(address _user, string _dataType) constant
returns (string userPermissions) {
if (stringsEqual(aclOf[_user].dataType, _dataType)) {
userPermissions = aclOf[_user].permissions;
}
else {
userPermissions = "NO DATA";
}
}
function stringsEqual(string _a, string _b) internal returns (bool) {
bytes memory a = bytes(_a);
bytes memory b = bytes(_b);
if (a.length != b.length) {
return false;
}
for (uint i = 0; i < a.length; i ++) {
if (a[i] != b[i]) return false;
}
return true;
}
}
eth_getCode
does not return any code at the contract address. However, when a much simpler contract was deployed,eth_getCode
does return the deployed code. So there is possibly some issue in the contract code, even though the deployment transaction gets mined and receipt shows a contract address. The root cause is not related toeth_call
eth_getCode
returning deployed code correctly for a much simpler contract that I thought the problem could be in the Solidity code.