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:
The following script fetches blocks and filters transactions to/from the given address. You can modify it to suit your needs.
#!/usr/bin/python
import argparse
import json
import web3
from web3 import Web3
from hexbytes import HexBytes
# Exports transactions to a JSON file where each line
# contains the data returned from the JSONRPC interface
provider = Web3.HTTPProvider('https://mainnet.infura.io/')
w3 = Web3(provider)
parser = argparse.ArgumentParser()
parser.add_argument('addr', type=str, help='Address to print the transactions for')
parser.add_argument('-o', '--output', type=str, help="Path to the output JSON file", required=True)
parser.add_argument('-s', '--start-block', type=int, help='Start block', default=0)
parser.add_argument('-e', '--end-block', type=int, help='End block', default=w3.eth.blockNumber)
def tx_to_json(tx):
result = {}
for key, val in tx.items():
if isinstance(val, HexBytes):
result[key] = val.hex()
else:
result[key] = val
return json.dumps(result)
def __main__():
args = parser.parse_args()
start_block = args.start_block
end_block = args.end_block
address_lowercase = args.addr.lower()
ofile = open(args.output, 'w')
for idx in range(start_block, end_block):
print('Fetching block %d, remaining: %d, progress: %d%%'%(
idx, (end_block-idx), 100*(idx-start_block)/(end_block-start_block)))
block = w3.eth.getBlock(idx, full_transactions=True)
for tx in block.transactions:
if tx['to']:
to_matches = tx['to'].lower() == address_lowercase
else:
to_matches = False
if tx['from']:
from_matches = tx['from'].lower() == address_lowercase
else:
from_matches = False
if to_matches or from_matches:
print('Found transaction with hash %s'%tx['hash'].hex())
ofile.write(tx_to_json(tx)+'\n')
ofile.flush()
if __name__ == '__main__':
__main__()
Best Answer
The question could be a bit clearer. This snippet should be good to iterate over your list
I would suggest watching a Python tutorial before delving deeper into your project.