[Ethereum] Execute a contract from bash or inside a python script

go-ethereummistpython

I have a Mist wallet and a contract (with its address) that i execute from mist GUI "manually".
I was wondering how i can execute it from command line (bash not geth) or call that execution from a python script.
If this is possible could you provide a toy example or a roadmap?
Thanks in advance!

Best Answer

All of this has already been explored in the comments but I'll summarise as an answer!

Executing/calling from bash

This is explained pretty thoroughly in the Homestead Guide to Accessing Contracts and Transactions.

From the very basics, Ethereum has an RPC (Remote procedure call) interface, as explained excellently by the Wikipedia RPC page. Ethereum's RPC interface uses a subset of the JSON-RPC 2.0 spec, with the following caveats:

  • Numbers are hex encoded.
  • If the RPC method takes a block number, you can submit either an actual number, or one of the following strings: "earliest", "latest", "pending".

Commands with bash

Using the RPC interface, we can execute commands such as eth_coinbase, which returns your ETH address:

> curl --data '{"jsonrpc":"2.0","method":"eth_coinbase", "id":1}' localhost:8545

Which prints:

{"id":1,"jsonrpc":"2.0","result":["0xeb85a5557e5bdc18ee1934a89d8bb402398ee26a"]}

Interacting with deployed contracts with bash

Functions from pre-deployed contracts are interacted with through their function signature, which is found by taking the first 4 bytes of the output of sha3('functionName(functionParameterTypes)'). This can be computed from inside geth with, for example,

> web3.sha3("multiply(uint256)").substring(0, 8)
"c6888fa1"

A helpful note here is that even if you've used uint or int within your contract, you'll have to use the real deal like eg uint256.

You pad your input (encoded in hex) with zeros, like the following, for an example input of 6:

0000000000000000000000000000000000000000000000000000000000000006

You do this so the length is a multiple of 32 bytes, but usually I just copy the example and change the end so as not to have to hit the 0 button 8 billion times.

Now quoting straight from the docs, we have:

Combining the function selector and the encoded argument our data will be:

0xc6888fa10000000000000000000000000000000000000000000000000000000000000006

Lets try it:

> curl --data '{"jsonrpc":"2.0","method": "eth_sendTransaction", "params": [{"from": "0xeb85a5557e5bdc18ee1934a89d8bb402398ee26a", "to": "0x6ff93b4b46b41c0c3c9baee01c255d3b4675963d", "data": "0xc6888fa10000000000000000000000000000000000000000000000000000000000000006"}], "id": 8}' localhost:8545
{"id":8,"jsonrpc":"2.0","result":"0x759cf065cbc22e9d779748dc53763854e5376eea07409e590c990eafc0869d74"}

Since we sent a transaction we got the transaction hash returned. You can have way more exciting examples that return results of function calls.

Calling with Python scripts

I haven't tested a single one of these, but from the comments, links to explore include:

Related Topic