How can I call contract methods from python using my private key? I want to connect to Rinkeby Test Network and then send a transaction that I signed with my private key. Is there any ways to perform it using Python?
-
I'd recommend subscribing to updates on this: github.com/pipermerriam/web3.py/issues/430 Once that's included, web3py will have a convenient way to do what you want. It's possible to get it working using custom middleware in the v4 beta now, if you need to hack something right away.– carverNov 21, 2017 at 17:06
2 Answers
To perform these actions, you would use web3.py, which is a Python implementation of web3.js.
You can perform exactly what you're asking for with the example code on the README.md
file in the repository.
Lines to note are as follows:
w3 = Web3(TestRPCProvider())
Here is where you would define the network you are on, such as Rinkeyby.
-
i think this will work as well... 'w3 = Web3(Web3.WebSocketProvider('ws://127.0.0.1:8546'))' -> 'web3py.readthedocs.io/en/stable/…' Jan 3, 2019 at 5:11
You don't need a key at all to "call contract methods". You can simply specify the address that you'd like the call to come from. So I'm assuming you mean you want to send a transaction that invokes a contract method.
That is now available using buildTransaction()
and w3.eth.account.signTransaction()
like so:
>>> from ethtoken.abi import EIP20_ABI
>>> from web3.auto import w3
>>> unicorns = w3.eth.contract(address="0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359", abi=EIP20_ABI)
>>> nonce = w3.eth.getTransactionCount('0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E')
# Build a transaction that invokes this contract's function, called transfer
>>> unicorn_txn = unicorns.functions.transfer(
... '0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359',
... 1,
... ).buildTransaction({
... 'chainId': 1,
... 'gas': 70000,
... 'gasPrice': w3.toWei('1', 'gwei'),
... 'nonce': nonce,
... })
>>> unicorn_txn
{'value': 0,
'chainId': 1,
'gas': 70000,
'gasPrice': 1000000000,
'nonce': 0,
'to': '0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359',
'data': '0xa9059cbb000000000000000000000000fb6916095ca1df60bb79ce92ce3ea74c37c5d3590000000000000000000000000000000000000000000000000000000000000001'}
>>> private_key = b"\xb2\\}\xb3\x1f\xee\xd9\x12''\xbf\t9\xdcv\x9a\x96VK-\xe4\xc4rm\x03[6\xec\xf1\xe5\xb3d"
>>> signed_txn = w3.eth.account.signTransaction(unicorn_txn, private_key=private_key)
>>> signed_txn.hash
HexBytes('0x4795adc6a719fa64fa21822630c0218c04996e2689ded114b6553cef1ae36618')
>>> signed_txn.rawTransaction
HexBytes('0xf8a980843b9aca008301117094fb6916095ca1df60bb79ce92ce3ea74c37c5d35980b844a9059cbb000000000000000000000000fb6916095ca1df60bb79ce92ce3ea74c37c5d359000000000000000000000000000000000000000000000000000000000000000125a00fb532eea06b8f17d858d82ad61986efd0647124406be65d359e96cac3e004f0a02e5d7ffcfb7a6073a723be38e6733f353cf9367743ae94e2ccd6f1eba37116f4')
>>> signed_txn.r
7104843568152743554992057394334744036860247658813231830421570918634460546288
>>> signed_txn.s
20971591154030974221209741174186570949918731455961098911091818811306894497524
>>> signed_txn.v
37
>>> w3.eth.sendRawTransaction(signed_txn.rawTransaction)
# When you run sendRawTransaction, you get the same result as the hash of the transaction:
>>> w3.toHex(w3.sha3(signed_txn.rawTransaction))
'0x4795adc6a719fa64fa21822630c0218c04996e2689ded114b6553cef1ae36618'
~ from the docs (feature and docs weren't written at the time of the question)
Note that this example connects to mainnet, so you would have to connect to Rinkeby explicitly, as @shane mentioned.