Currently trying to create and listen to contracts, testing on Rinkeby
Please include any of the following that are applicable:
`from web3 import Web3, HTTPProvider, IPCProvider
web3 = Web3(HTTPProvider('https://rinkeby.infura.io'))
web3.personal.unlockAccount("[address]","[psw]")`
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".../py3/lib/python3.5/site-packages/web3/personal.py", line 93, in unlockAccount
[account, passphrase, duration],
File ".../py3/lib/python3.5/site-packages/web3/manager.py", line 93, in request_blocking
response = self._make_request(method, params)
File ".../py3/lib/python3.5/site-packages/web3/manager.py", line 76, in _make_request
return request_func(method, params)
File ".../py3/lib/python3.5/site-packages/web3/middleware/attrdict.py", line 20, in middleware
response = make_request(method, params)
File ".../py3/lib/python3.5/site-packages/web3/middleware/formatting.py", line 25, in middleware
response = make_request(method, params)
File ".../py3/lib/python3.5/site-packages/web3/providers/rpc.py", line 52, in make_request
**self.get_request_kwargs()
File ".../py3/lib/python3.5/site-packages/web3/utils/compat/compat_requests.py", line 22, in make_post_request
response.raise_for_status()
File ".../py3/lib/python3.5/site-packages/requests/models.py", line 935, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 405 Client Error: Method Not Allowed for url: https://rinkeby.infura.io/
This is the important part of that error:
Method Not Allowed for url: https://rinkeby.infura.io/
Infura does not support private keys stored on their server (which is a good thing, that would be a gaping security hole). On mainnet, do not send your private keys or passwords to any remote service! If you do accidentally, you should empty the account and never use it again, and change the password.
In Web3 v3, sending transactions to Infura is a bit cumbersome. One needs to sign the transaction locally, and send with w3.eth.sendRawTransaction. Either use a local geth/parity/etc node, or upgrade to the beta v4, which has some convenience tools for signing transactions locally.
There is an ongoing project to sign transactions locally using middleware that will handle this logic of signing locally before sending as a raw transaction, but it will probably be at least a couple weeks until it is released. #493
Thanks! So to confirm, there is no way to create contracts from scratch in python?
Thanks! So to confirm, there is no way to create contracts from scratch in python?
There are several ways, but not any good ones that use web3.py v3 and infura.
So the best option I can think of are to:
Really appreciate your help here and on Stack Overflow!
So, from the documentation and code examples I still haven't been able to fully piece together how to do it;
Would I start a contract like this
http://web3py.readthedocs.io/en/latest/quickstart.html#simple-contract-example
Turn it into a transaction like this
http://web3py.readthedocs.io/en/latest/contracts.html#web3.contract.Contract.buildTransaction
sign it offline (presumably giving an account number and password), then send?
Thanks
Really appreciate your help here and on Stack Overflow!
Sure thing, I'm happy to help. There's still so many docs to write and infrastructure to build! Which brings me to...
I still haven't been able to fully piece together how to do it...
I am now realizing that there is no good documentation or public API for deploying a contract with a private key. buildTransaction() won't work for you for deploying the contract. That means web3 should probably add a new method. In the meantime, you can do this using a non-public method (_encode_constructor_data()), like so:
contract_interface with the quickstart instructions you found.# build contract_interface
from web3.auto import w3
contract = w3.eth.contract(abi=contract_interface['abi'], bytecode=contract_interface['bin'])
data = contract._encode_constructor_data(any_args, you_have, in_the_constructor)
transaction = {'data': data, 'gas':...)
from web3 import Account
acct = Account.privateKeyToAccount(your_private_key)
signed = acct.signTransaction(transaction)
w3.eth.sendRawTransaction(signed.rawTransaction)
Note that the private key signing in w3.eth.account has not yet been audited, it's in beta, use at your own risk.
I've successfully done a "transaction" with myself now (thanks!)
https://ropsten.etherscan.io/address/0xaa08901e5673593c51ee4439b8ff9639a09fe892
But a contract was not created. I guess something I am confused about is, when creating the 'transaction' dictionary, what should the 'to' field be? From creating contracts normally I see that a contract has its own address, but I don't know how to generate that address
The 'to' field should be empty when creating a contract.
When I was trying that, I got an error that impied that all of the fields, including 'to', were required.
Also, I'm now trying to call a method on a contract and am getting this bug:
ValueError: The value HexBytes('0xd783010800846765746887676f312e392e32856c696e75780000000000000000c1c60624ec24ed6b621324b8d4db5d844b39cc5eae1154db90ef0760f75b298239
c5b831d08c94bb7ab811d014bad3af21ef5e39121bd4860df9c9002ccd4c7501') is 97 bytes, but should be 32
...
ValueError: Could not format value '0xd783010800846765746887676f312e392e32856c696e75780000000000000000c1c60624ec24ed6b621324b8d4db5d844b39cc5eae1154db90ef0760f75b29
8239c5b831d08c94bb7ab811d014bad3af21ef5e39121bd4860df9c9002ccd4c7501' as field 'extraData'
My code is:
contract_address = 'insert address'
abi = None
with open('contract-abi.json', 'r') as abi_definition:
abi = json.load(abi_definition)
contract = w3.eth.contract(address=contract_address, abi=abi)
contract.transact({'from': w3.eth.accounts[0]}).provideKey(2, 13)
From looking at the documentation I unfortunately wasn't able to figure it out. It seems that I don't have to sign with a private key?
Once again, I really appreciate all of the help you've given me. Is there an ethereum address where I can donate to you and/or the rest of the web3.py team?
Ended up being able to do it on Ropsten (instead of Rinkeby), and adding --rpcapi="db,eth,net,web3,personal,web3" to my geth console flags
@carver , hi carver, there is something confusing on me about the new features you mentioned, could you please give me a favor? is the middleware with the functionality that could sign the private key with the transaction supported on the tag v4.0.0beta9? and how to use it? a demo example will be appreciated. hope to get you reply asp, thank you advanced!
@whysear "How do I do X?" questions are best asked on StackExchange, in case someone else has asked the question. FYI, that middleware project stalled a bit. Not sure when it would come out. In general, these docs should get you started: http://web3py.readthedocs.io/en/latest/web3.eth.account.html
@carver , OK, thanks, actually, I have made a solution working well, but it is not so elegant. cause when I want to get the return value of such as the balanceOf method of an instance of contract conform to ERC20, what I did is adding a balanceOf event, then get the rich log from the receipt after the sendRawTransation invoked. I hope there is or will be a solution to meet this requirement better.
i think you should websocket " wss: rinkeby.infura.io/ws"
Most helpful comment
This is the important part of that error:
Infura does not support private keys stored on their server (which is a good thing, that would be a gaping security hole). On mainnet, do not send your private keys or passwords to any remote service! If you do accidentally, you should empty the account and never use it again, and change the password.
In Web3 v3, sending transactions to Infura is a bit cumbersome. One needs to sign the transaction locally, and send with
w3.eth.sendRawTransaction. Either use a local geth/parity/etc node, or upgrade to the beta v4, which has some convenience tools for signing transactions locally.There is an ongoing project to sign transactions locally using middleware that will handle this logic of signing locally before sending as a raw transaction, but it will probably be at least a couple weeks until it is released. #493