JSON RPC – How to Get ‘data’ for JSON RPC eth_call

contract-invocationjson-rpc

Is there a more convenient way to construct the value of data for an eth_call JSON-RPC API call, than the "regular" way of first 4 bytes of web3.sha3 of canonical function signature followed by encoded and padded arguments? I know that the web3 Javascript getData method can be used but, if access via web3 is available, then one could just as well call the function directly, instead of just getting data and using JSON-RPC API. Suppose that only JSON-RPC API access is available in some situation. Is constructing data by hand for a contract function call the only option?

EDIT (6/21/2017): It occurred to me that browser-solidity might display the data for an eth_call or eth_sendTransaction, since it does display compiled contract bytecode and interface. That could have been copy-pasted. However, I checked and do not see the data needed for a function call displayed when I call a function in the right panel.

EDIT #2 (6/21/2017): Maybe my question was not clear as posted above. I will try putting it differently. Say, we have the following Solidity contract (named simple) deployed at some address, e.g. at 0xfbb5fa2ea8c5fc6f492c0795564352f262f49f50

pragma solidity ^0.4.9;

contract owned {
    address owner;
    function owned() {
        owner = msg.sender;
    }
    function getOwner() constant returns(address) {
        return owner;
    }
}

contract simple is owned {
    function twice(int a) constant returns(int) {
        return 2*a;
    }
}

The function twice can be called from Javascript code, using web3.js, as follows:

var simple = eth.contract(<ABI>).at(0xfbb5fa2ea8c5fc6f492c0795564352f262f49f50);
var result = simple.twice(7);

However, to call this function using JSON-RPC, an HTTP post request needs to be sent to the RPC port of a node, with the following body:

{
    "jsonrpc": "2.0",
    "method": "eth_call",
    "params": [
        {
            "from": "0xccf9d7d2f8be1f821cb8d9ec9553ffa92aa8fc4d",
            "to": "0xfbb5fa2ea8c5fc6f492c0795564352f262f49f50",
            "data": "0x6ffa1caa0000000000000000000000000000000000000000000000000000000000000007"
        },
        "latest"
    ],
    "id": 1
}

The value of data element is calculated as first 4 bytes of { the Keccak hash of [ the ASCII encoding of ( a canonical form of the function signature ) ] } followed by the arguments encoded in a particular way, as specified at https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI. NOTE: Added 3 types of brackets to remove ambiguity 🙂 (This is a very simple function with only 1 int argument but this can quickly get very nasty and error-prone with more complex arguments.

There is a way to easily obtain the appropriate value of data for a function call using a web3.js function, as follows:

var callData = simple.twice.getData(7);

But suppose the function is to be called from a remote machine and also that Javascript is not an option. Is there a convenient way, (i.e. not manually doing so as per the complex rules in the wiki linked above) to compute the correct value of the data element of the JSON-RPC API request?

Best Answer

I found just the tool that I was looking for - ethabi from Parity.

https://github.com/paritytech/ethabi