February 2018. : this post explores how to send requests to a node in order to create raw transactions. The goal is to understand and see what is going on in the background when using a high level library such as or . Goal JSON-RPC Geth web3py web3js Also I am not interested in . If anything goes wrong it will . This post is indented to be educational only. For production, consider using . handling errors and exceptions fail loudly web3py : we will deploy and interact (calling functions and reading variables) with a smart contract on a private network using only HTTP requests. Transactions are signed and only then sent to a geth node for processing. Summary public offline For this guide I am using a private network. If you would like to create such a network I invite you to read my . Otherwise using (previously called TestRPC) or any Ethereum is totally fine. Therefore I am not gonna cover anything about setting up a network here as the focus is using to send HTTP requests to a Geth node. Proof-of-Authority previous post Ganache network python If you just wanna see the full code, jump at the last Chapter. Prerequisite Having access to a Ethereum network over IPC or RPC (might it be public, private, or a simulator like Ganache). Having python 3 installed. Personally I like the . Anaconda distribution Install the latest version of . web3py 1. Sending a simple request to Geth Let’s warm up by sending a very simple request to Geth. Like asking the network id. The first step is to . The method we need is called and is described . read the doc net_version here My Geth node URL and Port are: . If you’re using Ganache with default value, the URL is probably . http://localhost:8501 http://localhost:7545 I am using the to make my HTTP requests. Enough talking. Requests python library import requests # create persistent HTTP connectionsession = requests.Session() # as defined in method = 'net_version'params = []payload= {"jsonrpc":"2.0","method":method,"params":params,"id":1} https://github.com/ethereum/wiki/wiki/JSON-RPC#net_version headers = {'Content-type': 'application/json'} response = session.post(' , json=payload, headers=headers)print('raw json response: {}'.format(response.json()))print('network id: {}'.format(response.json()['result'])) http://localhost:8501' prints: raw json response: {'id': 1, 'jsonrpc': '2.0', 'result': '1515'}network id: 1515 Goob job ! From there we are ready to deploy and transact with a contract. Better build on good foundations. 1515 is the network id of my private Blockchain as defined in the genesis file. Everything looks great. With Ganache you should get 5777 for the network id. But before being able to sign and send a transaction, we need an address, a private key and some ether. 2. Creating a private-public key pair and getting some ether The web3py (release 4) library will help us create a key pair. import web3 w3 = web3.Web3() myAccount = w3.eth.account.create('put some extra entropy here')myAddress = myAccount.addressmyPrivateKey = myAccount.privateKey print('my address is : {}'.format(myAccount.address))print('my private key is : {}'.format(myAccount.privateKey.hex())) in my case, I get: my address is : 0xF464A67CA59606f0fFE159092FF2F474d69FD675my private key is: 0x94cb9f766ef067eb229da85213439cf4cbbcd0dc97ede9479be5ee4b7a93b96f Please ! I do it here because it is a local private development network that I am destroying and reboot a few times a day. I am not using this key pair on any public network. NEVER SHARE YOUR PRIVATE KEY Now to get some ether to this address there are multiple ways: 1. A very simple way is to add this address in your file and to start a new network. From my , here is my genesis file that includes the address (remove ) we have just created. genesis.json previous guide 0x {"config": {"chainId": 1515,"homesteadBlock": 1,"eip150Block": 2,"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000","eip155Block": 3,"eip158Block": 3,"byzantiumBlock": 4,"clique": {"period": 5,"epoch": 30000}},"nonce": "0x0","timestamp": "0x5a722c92","extraData": "0x000000000000000000000000000000000000000000000000000000000000000008a58f09194e403d02a1928a7bf78646cfc260b087366ef81db496edd0ea2055ca605e8686eec1e60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","gasLimit": "0x8000000","difficulty": "0x1","mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000","coinbase": "0x0000000000000000000000000000000000000000","alloc": {"08a58f09194e403d02a1928a7bf78646cfc260b0": {"balance": "0x200000000000000000000000000000000000000000000000000000000000000"},"87366ef81db496edd0ea2055ca605e8686eec1e6": {"balance": "0x200000000000000000000000000000000000000000000000000000000000000"},"F464A67CA59606f0fFE159092FF2F474d69FD675": {"balance": "0x200000000000000000000000000000000000000000000000000000000000000"}},"number": "0x0","gasUsed": "0x0","parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"} 2. If you have a mining node or ganache, open a and create a transaction by hand Geth Javascript Console $ geth attach ipc:'http://localhost:8501' // 7545 for ganacheWelcome to the Geth JavaScript console! instance: Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9coinbase: 0x87366ef81db496edd0ea2055ca605e8686eec1e6at block: 1585 (Wed, 14 Feb 2018 11:46:04 CET)modules: eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0 > eth.sendTransaction({'from':eth.coinbase, 'to':'0xF464A67CA59606f0fFE159092FF2F474d69FD675', 'value':1000000000000000000000})"0xdbc86acbe3644ac2cdb68132bbeecda40733c10f07ca16d87a2e5001e50eec4c"> exit here I am sending 1000 ether from to my address . (1 followed by 18 zeros). The . 0x87366... 0xF464A... 1 ether is 1e18 wei unit of the [value](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sendtransaction) field is wei 3. On public testnets, use a faucet. 3 Deploy and Transact with a Smart Contract Great, now that we have an address with some ether (to pay for the gas cost) we can create our transaction offline, sign it, and send it to a node with a raw JSON-RPC HTTP request. We are gonna use the that takes as inputs the signed of a . send_rawTransaction method parameters transaction The python code is looking for the json file containing the contract abi and bytecode that truffle creates when compiling a smart contract. Before testing the python code, create a truffle workspace and compile the dummy contract . AdditionContract.sol $ truffle init// add the smart contract in contracts/$ truffle compile then update the python code with the URL of your geth node, and the path to the truffle workspace and your genesis file (don’t forget to replace my userName with yours in the path). Everything else is in the code and should be self-explanatory. I kept everything dead simple to ease modification and experimentation. Have fun :)