From 9fe557012eba5b1623738090d31a4404f6c7e008 Mon Sep 17 00:00:00 2001 From: lauws Date: Tue, 5 Apr 2022 23:28:23 +0800 Subject: [PATCH 1/4] Update Greeter example to sign the transaction locally --- docs/contracts.rst | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/docs/contracts.rst b/docs/contracts.rst index cd5cedf513..98e431084a 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -76,15 +76,27 @@ You should now be set up to run the contract deployment example below: >>> abi = contract_interface['abi'] # web3.py instance + >>> provider = Web3.EthereumTesterProvider() >>> w3 = Web3(Web3.EthereumTesterProvider()) - # set pre-funded account as sender - >>> w3.eth.default_account = w3.eth.accounts[0] + # Obtain the pre-funded private key and public address as signer + >>> my_private_key = provider.ethereum_tester.backend.account_keys[0] + >>> my_account = w3.eth.account.from_key(private_key) + # Get nonce for the account + >>> nonce = w3.eth.get_transaction_count(my_account.address) + + # Create web3 contract >>> Greeter = w3.eth.contract(abi=abi, bytecode=bytecode) - # Submit the transaction that deploys the contract - >>> tx_hash = Greeter.constructor().transact() + # Build the transaction parameters that deploys the contract to be signed + >>> tx_params = Greeter.constructor().buildTransaction({ + 'nonce': nonce + }) + + # Sign and send the raw signed transaction + >>> signed_transaction = my_account.signTransaction(tx_params) + >>> tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) # Wait for the transaction to be mined, and get the transaction receipt >>> tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) @@ -97,7 +109,12 @@ You should now be set up to run the contract deployment example below: >>> greeter.functions.greet().call() 'Hello' - >>> tx_hash = greeter.functions.setGreeting('Nihao').transact() + >>> nonce = w3.eth.get_transaction_count(my_account.address) + >>> tx_params = greeter.functions.setGreeting('Nihao').buildTransaction({ + 'nonce': nonce + }) + >>> signed_transaction = my_account.signTransaction(tx_params) + >>> tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) >>> tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) >>> greeter.functions.greet().call() 'Nihao' From 00c2042bb2623cce8f8dfc884824e4d65dce59a7 Mon Sep 17 00:00:00 2001 From: lauws Date: Wed, 6 Apr 2022 00:12:11 +0800 Subject: [PATCH 2/4] Update all transact function and add construct,sign and send raw middleware --- docs/contracts.rst | 166 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 146 insertions(+), 20 deletions(-) diff --git a/docs/contracts.rst b/docs/contracts.rst index 98e431084a..eae3999284 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -35,7 +35,7 @@ After ``py-solc-x`` is installed, you will need to install a version of ``solc`` >>> from solcx import install_solc >>> install_solc(version='latest') -You should now be set up to run the contract deployment example below: +You should now be set up to run the contract deployment example below : .. code-block:: python @@ -83,6 +83,9 @@ You should now be set up to run the contract deployment example below: >>> my_private_key = provider.ethereum_tester.backend.account_keys[0] >>> my_account = w3.eth.account.from_key(private_key) +Using we can use ``send_raw_transaction`` to create the contract : +.. code-block:: python + # Get nonce for the account >>> nonce = w3.eth.get_transaction_count(my_account.address) @@ -119,6 +122,38 @@ You should now be set up to run the contract deployment example below: >>> greeter.functions.greet().call() 'Nihao' +or we can set up ``construct_and_sign_middleware`` and let the middleware signs the transaction: + +.. code-block:: python + # Get nonce for the account + >>> w3.middleware_onion.add(construct_sign_and_send_raw_middleware(my_account)) + >>> w3.eth.default_account = my_account.address + + # Create web3 contract + >>> Greeter = w3.eth.contract(abi=abi, bytecode=bytecode) + + # Build the transaction parameters that deploys the contract + >>> tx_params = Greeter.constructor().buildTransaction() + + # Send the transaction and let the middleware signs it + >>> tx_hash = w3.eth.send_transaction(tx_params) + + # Wait for the transaction to be mined, and get the transaction receipt + >>> tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) + + >>> greeter = w3.eth.contract( + ... address=tx_receipt.contractAddress, + ... abi=abi + ... ) + + >>> greeter.functions.greet().call() + 'Hello' + + >>> tx_params = greeter.functions.setGreeting('Nihao').buildTransaction() + >>> tx_hash = w3.eth.send_transaction(tx_params) + >>> tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) + >>> greeter.functions.greet().call() + 'Nihao' Contract Factories ------------------ @@ -256,8 +291,14 @@ Each Contract Factory exposes the following methods. .. code-block:: python - >>> deploy_txn = token_contract.constructor(web3.eth.coinbase, 12345).transact() - >>> txn_receipt = web3.eth.get_transaction_receipt(deploy_txn) + >>> my_account = web3.eth.account.from_key(PRIVATE_KEY) + >>> nonce = w3.eth.get_transaction_count(my_account.address) + >>> tx_params = token_contract.constructor(web3.eth.coinbase, 12345).buildTransaction({ + 'nonce': nonce + }) + >>> signed_transaction = my_account.signTransaction(tx_params) + >>> tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) + >>> txn_receipt = web3.eth.get_transaction_receipt(tx_hash) >>> txn_receipt['contractAddress'] '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318' @@ -706,8 +747,13 @@ Taking the following contract code as an example: .. doctest:: arrayscontract >>> ArraysContract = w3.eth.contract(abi=abi, bytecode=bytecode) - - >>> tx_hash = ArraysContract.constructor([b'b']).transact() + >>> my_account = web3.eth.account.from_key(PRIVATE_KEY) + >>> nonce = w3.eth.get_transaction_count(my_account.address) + >>> tx_params = ArraysContract.constructor([b'b']).buildTransaction({ + 'nonce': nonce + }) + >>> signed_transaction = my_account.signTransaction(tx_params) + >>> tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) >>> tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) >>> array_contract = w3.eth.contract( @@ -717,12 +763,24 @@ Taking the following contract code as an example: >>> array_contract.functions.getBytes2Value().call() [b'b\x00'] - >>> array_contract.functions.setBytes2Value([b'a']).transact({'gas': 420000, 'gasPrice': Web3.toWei(1, 'gwei')}) - HexBytes('0xc5377ba25224bd763ceedc0ee455cc14fc57b23dbc6b6409f40a557a009ff5f4') + >>> nonce = w3.eth.get_transaction_count(my_account.address) + >>> tx_params = array_contract.functions.setBytes2Value([b'a']).buildTransaction({ + ... 'gas': 420000, + ... 'gasPrice': Web3.toWei(1, 'gwei'), + ... 'nonce': nonce, + ... }) + >>> signed_transaction = my_account.signTransaction(tx_params) + >>> tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) + >>> w3.eth.wait_for_transaction_receipt(tx_hash) + AttributeDict({...}) >>> array_contract.functions.getBytes2Value().call() [b'a\x00'] >>> w3.enable_strict_bytes_type_checking() - >>> array_contract.functions.setBytes2Value([b'a']).transact() + >>> nonce = w3.eth.get_transaction_count(my_account.address) + >>> tx_params = array_contract.functions.setBytes2Value([b'a']).buildTransaction({ + 'nonce': nonce + }) + >>> w3.eth.send_raw_transaction(signed_transaction.rawTransaction) Traceback (most recent call last): ... ValidationError: @@ -964,7 +1022,14 @@ For example: .. code-block:: python myContract = web3.eth.contract(address=contract_address, abi=contract_abi) - tx_hash = myContract.functions.myFunction().transact() + + my_account = web3.eth.account.from_key(PRIVATE_KEY) + nonce = w3.eth.get_transaction_count(my_account.address) + tx_params = myContract.functions.myFunction().buildTransaction({ + 'nonce': nonce + }) + signed_transaction = my_account.signTransaction(tx_params) + tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) receipt = web3.eth.get_transaction_receipt(tx_hash) myContract.events.myEvent().processReceipt(receipt) @@ -982,7 +1047,14 @@ For example: .. code-block:: python - >>> tx_hash = contract.functions.myFunction(12345).transact({'to':contract_address}) + >>> my_account = w3.eth.account.from_key(PRIVATE_KEY) + >>> nonce = w3.eth.get_transaction_count(my_account.address) + >>> tx_params = contract.functions.myFunction(12345).buildTransaction({ + 'to':contract_address, + 'nonce': nonce, + }) + >>> signed_transaction = my_account.signTransaction(tx_params) + >>> tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) >>> tx_receipt = w3.eth.get_transaction_receipt(tx_hash) >>> rich_logs = contract.events.myEvent().processReceipt(tx_receipt) >>> rich_logs[0]['args'] @@ -999,7 +1071,14 @@ For example: .. code-block:: python - >>> tx_hash = contract.functions.myFunction(12345).transact({'to':contract_address}) + >>> my_account = w3.eth.account.from_key(PRIVATE_KEY) + >>> nonce = w3.eth.get_transaction_count(my_account.address) + >>> tx_params = contract.functions.myFunction(12345).buildTransaction({ + 'to':contract_address, + 'nonce': nonce, + }) + >>> signed_transaction = my_account.signTransaction(tx_params) + >>> tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) >>> tx_receipt = w3.eth.get_transaction_receipt(tx_hash) >>> processed_logs = contract.events.myEvent().processReceipt(tx_receipt) >>> processed_logs @@ -1048,7 +1127,14 @@ For example: .. code-block:: python - >>> tx_hash = contract.functions.myFunction(12345).transact({'to':contract_address}) + >>> my_account = w3.eth.account.from_key(PRIVATE_KEY) + >>> nonce = w3.eth.get_transaction_count(my_account.address) + >>> tx_params = contract.functions.myFunction(12345).buildTransaction({ + 'to':contract_address, + 'nonce': nonce, + }) + >>> signed_transaction = my_account.signTransaction(tx_params) + >>> tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) >>> tx_receipt = w3.eth.get_transaction_receipt(tx_hash) >>> log_to_process = tx_receipt['logs'][0] >>> processed_log = contract.events.myEvent().processLog(log_to_process) @@ -1089,15 +1175,27 @@ Event Log Object from web3 import Web3 from hexbytes import HexBytes - w3 = Web3(Web3.EthereumTesterProvider()) + provider = Web3.EthereumTesterProvider() + w3 = Web3(provider) bytecode = '6060604052341561000c57fe5b604051602080610acb833981016040528080519060200190919050505b620f42408114151561003b5760006000fd5b670de0b6b3a76400008102600281905550600254600060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b505b610a27806100a46000396000f30060606040523615610097576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde0314610099578063095ea7b31461013257806318160ddd1461018957806323b872dd146101af578063313ce5671461022557806370a082311461025157806395d89b411461029b578063a9059cbb14610334578063dd62ed3e1461038b575bfe5b34156100a157fe5b6100a96103f4565b60405180806020018281038252838181518152602001915080519060200190808383600083146100f8575b8051825260208311156100f8576020820191506020810190506020830392506100d4565b505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561013a57fe5b61016f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061042e565b604051808215151515815260200191505060405180910390f35b341561019157fe5b610199610521565b6040518082815260200191505060405180910390f35b34156101b757fe5b61020b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610527565b604051808215151515815260200191505060405180910390f35b341561022d57fe5b610235610791565b604051808260ff1660ff16815260200191505060405180910390f35b341561025957fe5b610285600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610796565b6040518082815260200191505060405180910390f35b34156102a357fe5b6102ab6107e0565b60405180806020018281038252838181518152602001915080519060200190808383600083146102fa575b8051825260208311156102fa576020820191506020810190506020830392506102d6565b505050905090810190601f1680156103265780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561033c57fe5b610371600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061081a565b604051808215151515815260200191505060405180910390f35b341561039357fe5b6103de600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610973565b6040518082815260200191505060405180910390f35b604060405190810160405280600981526020017f54657374546f6b656e000000000000000000000000000000000000000000000081525081565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a3600190505b92915050565b60025481565b600081600060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410806105f1575081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054105b156105fc5760006000fd5b81600060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555081600060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190505b9392505050565b601281565b6000600060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b919050565b604060405190810160405280600481526020017f544553540000000000000000000000000000000000000000000000000000000081525081565b600081600060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156108695760006000fd5b81600060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190505b92915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b929150505600a165627a7a723058205071371ee2a4a1be3c96e77d939cdc26161a256fdd638efc08bd33dfc65d3b850029' ABI = '[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function","stateMutability":"view"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function","stateMutability":"nonpayable"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function","stateMutability":"view"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function","stateMutability":"nonpayable"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function","stateMutability":"view"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function","stateMutability":"view"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function","stateMutability":"view"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function","stateMutability":"nonpayable"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function","stateMutability":"view"},{"inputs":[{"name":"_totalSupply","type":"uint256"}],"payable":false,"type":"constructor","stateMutability":"nonpayable"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]' my_token_contract = w3.eth.contract(abi=ABI, bytecode=bytecode) alice, bob = w3.eth.accounts[0], w3.eth.accounts[1] assert alice == '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', alice assert bob == '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF', bob - tx_hash = my_token_contract.constructor(1000000).transact({'from': alice, 'gas': 899000, 'gasPrice': Web3.toWei(1, 'gwei')}) - assert tx_hash == HexBytes('0x49e3da72a95e4074a9eaea7b438c73ca154627d317e58abeae914e3769a15044'), tx_hash + + private_keys = provider.ethereum_tester.backend.account_keys + alice_account = w3.eth.account.from_key(private_keys[0]) + bob_account = w3.eth.account.from_key(private_keys[1]) + alice_nonce = w3.eth.get_transaction_count(alice_account.address) + tx_params = my_token_contract.constructor(1000000).buildTransaction({ + 'from': alice, + 'gas': 899000, + 'gasPrice': Web3.toWei(1, 'gwei'), + 'nonce': alice_nonce, + }) + signed_transaction = alice_account.signTransaction(tx_params) + tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) txn_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) assert txn_receipt['contractAddress'] == '0xF2E246BB76DF876Cef8b38ae84130F4F55De395b', txn_receipt['contractAddress'] contract_address = txn_receipt['contractAddress'] @@ -1105,7 +1203,14 @@ Event Log Object total_supply = contract.functions.totalSupply().call() decimals = 10 ** 18 assert total_supply == 1000000 * decimals, total_supply - tx_hash = contract.functions.transfer(alice, 10).transact({'gas': 899000, 'gasPrice': Web3.toWei(1, 'gwei')}) + alice_nonce = w3.eth.get_transaction_count(alice_account.address) + tx_params = contract.functions.transfer(alice, 10).buildTransaction({ + 'gas': 899000, + 'gasPrice': Web3.toWei(1, 'gwei'), + 'nonce: alice_nonce, + }) + signed_transaction = alice_account.signTransaction(tx_params) + tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) .. doctest:: createFilter @@ -1124,7 +1229,15 @@ Event Log Object 'blockNumber': 2})] >>> transfer_filter.get_new_entries() [] - >>> tx_hash = contract.functions.transfer(alice, 10).transact({'gas': 899000, 'gasPrice': 674302241}) + >>> private_key = provider.ethereum_tester.backend.account_keys[0] + >>> alice_nonce = w3.eth.get_transaction_count(alice_account.address) + >>> tx_params = contract.functions.transfer(alice, 10).buildTransaction({ + 'gas': 899000, + 'gasPrice': 674302241, + 'nonce: alice_nonce, + }) + >>> signed_transaction = alice_account.signTransaction(tx_params) + >>> tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) >>> tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) >>> transfer_filter.get_new_entries() [AttributeDict({'args': AttributeDict({'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', @@ -1201,7 +1314,14 @@ For example: bytecode = "0x606060405261022e806100126000396000f360606040523615610074576000357c01000000000000000000000000000000000000000000000000000000009004806316216f391461007657806361bc221a146100995780637cf5dab0146100bc578063a5f3c23b146100e8578063d09de08a1461011d578063dcf537b11461014057610074565b005b610083600480505061016c565b6040518082815260200191505060405180910390f35b6100a6600480505061017f565b6040518082815260200191505060405180910390f35b6100d26004808035906020019091905050610188565b6040518082815260200191505060405180910390f35b61010760048080359060200190919080359060200190919050506101ea565b6040518082815260200191505060405180910390f35b61012a6004805050610201565b6040518082815260200191505060405180910390f35b6101566004808035906020019091905050610217565b6040518082815260200191505060405180910390f35b6000600d9050805080905061017c565b90565b60006000505481565b6000816000600082828250540192505081905550600060005054905080507f3496c3ede4ec3ab3686712aa1c238593ea6a42df83f98a5ec7df9834cfa577c5816040518082815260200191505060405180910390a18090506101e5565b919050565b6000818301905080508090506101fb565b92915050565b600061020d6001610188565b9050610214565b90565b60006007820290508050809050610229565b91905056" ABI = json.loads('[{"constant":false,"inputs":[],"name":"return13","outputs":[{"name":"result","type":"int256"}],"type":"function"},{"constant":true,"inputs":[],"name":"counter","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"amt","type":"uint256"}],"name":"increment","outputs":[{"name":"result","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"a","type":"int256"},{"name":"b","type":"int256"}],"name":"add","outputs":[{"name":"result","type":"int256"}],"type":"function"},{"constant":false,"inputs":[],"name":"increment","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"a","type":"int256"}],"name":"multiply7","outputs":[{"name":"result","type":"int256"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"value","type":"uint256"}],"name":"increased","type":"event"}]') contract = w3.eth.contract(abi=ABI, bytecode=bytecode) - deploy_txn = contract.constructor().transact() + + my_account = w3.eth.account.from_key(PRIVATE_KEY) + nonce = w3.eth.get_transaction_count(my_account.address) + tx_params = contract.constructor().buildTransaction({ + 'nonce': nonce + }) + signed_transaction = my_account.signTransaction(tx_params) + deploy_txn = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) deploy_receipt = w3.eth.wait_for_transaction_receipt(deploy_txn) address = deploy_receipt.contractAddress @@ -1291,7 +1411,13 @@ You can interact with Web3.py contract API as follows: >>> deployed_contract.functions.retrieve().call() '0x0000000000000000000000000000000000000000' - >>> deployed_contract.functions.update({'s1': ['0x0000000000000000000000000000000000000001', '0x0000000000000000000000000000000000000002'], 's2': [b'0'*32, b'1'*32], 'users': []}).transact() - + >>> my_account = w3.eth.account.from_key(PRIVATE_KEY) + >>> nonce = w3.eth.get_transaction_count(my_account.address) + >>> tx_params = deployed_contract.functions.update({'s1': ['0x0000000000000000000000000000000000000001', '0x0000000000000000000000000000000000000002'], 's2': [b'0'*32, b'1'*32], 'users': []}).buildTransaction({ + 'nonce': nonce + }) + >>> signed_transaction = my_account.signTransaction(tx_params) + >>> deploy_txn = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) + >>> tx_receipt = w3.eth.wait_for_transaction_receipt(deploy_txn) >>> deployed_contract.functions.retrieve().call() '0x0000000000000000000000000000000000000002' From 0483a249b8d9e882fd494c9238736bbce05fbeed Mon Sep 17 00:00:00 2001 From: lauws Date: Wed, 6 Apr 2022 01:37:17 +0800 Subject: [PATCH 3/4] Fix docs update to pass the CI --- docs/contracts.rst | 120 ++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 55 deletions(-) diff --git a/docs/contracts.rst b/docs/contracts.rst index eae3999284..b8e39e93e8 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -83,7 +83,9 @@ You should now be set up to run the contract deployment example below : >>> my_private_key = provider.ethereum_tester.backend.account_keys[0] >>> my_account = w3.eth.account.from_key(private_key) + Using we can use ``send_raw_transaction`` to create the contract : + .. code-block:: python # Get nonce for the account @@ -94,8 +96,8 @@ Using we can use ``send_raw_transaction`` to create the contract : # Build the transaction parameters that deploys the contract to be signed >>> tx_params = Greeter.constructor().buildTransaction({ - 'nonce': nonce - }) + ... 'nonce': nonce + ... }) # Sign and send the raw signed transaction >>> signed_transaction = my_account.signTransaction(tx_params) @@ -125,6 +127,7 @@ Using we can use ``send_raw_transaction`` to create the contract : or we can set up ``construct_and_sign_middleware`` and let the middleware signs the transaction: .. code-block:: python + # Get nonce for the account >>> w3.middleware_onion.add(construct_sign_and_send_raw_middleware(my_account)) >>> w3.eth.default_account = my_account.address @@ -656,7 +659,9 @@ Taking the following contract code as an example: .. testsetup:: arrayscontract from web3 import Web3 - w3 = Web3(Web3.EthereumTesterProvider()) + provider = Web3.EthereumTesterProvider() + my_private_key = provider.ethereum_tester.backend.account_keys[0] + w3 = Web3(provider) bytecode = "608060405234801561001057600080fd5b506040516106103803806106108339810180604052602081101561003357600080fd5b81019080805164010000000081111561004b57600080fd5b8281019050602081018481111561006157600080fd5b815185602082028301116401000000008211171561007e57600080fd5b5050929190505050806000908051906020019061009c9291906100a3565b505061019c565b82805482825590600052602060002090600f0160109004810192821561015a5791602002820160005b8382111561012a57835183826101000a81548161ffff02191690837e010000000000000000000000000000000000000000000000000000000000009004021790555092602001926002016020816001010492830192600103026100cc565b80156101585782816101000a81549061ffff021916905560020160208160010104928301926001030261012a565b505b509050610167919061016b565b5090565b61019991905b8082111561019557600081816101000a81549061ffff021916905550600101610171565b5090565b90565b610465806101ab6000396000f3fe608060405260043610610051576000357c0100000000000000000000000000000000000000000000000000000000900480633b3230ee14610056578063d7c8a410146100e7578063dfe3136814610153575b600080fd5b34801561006257600080fd5b5061008f6004803603602081101561007957600080fd5b8101908080359060200190929190505050610218565b60405180827dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b3480156100f357600080fd5b506100fc61026c565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561013f578082015181840152602081019050610124565b505050509050019250505060405180910390f35b34801561015f57600080fd5b506102166004803603602081101561017657600080fd5b810190808035906020019064010000000081111561019357600080fd5b8201836020820111156101a557600080fd5b803590602001918460208302840111640100000000831117156101c757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050610326565b005b60008181548110151561022757fe5b9060005260206000209060109182820401919006600202915054906101000a90047e010000000000000000000000000000000000000000000000000000000000000281565b6060600080548060200260200160405190810160405280929190818152602001828054801561031c57602002820191906000526020600020906000905b82829054906101000a90047e01000000000000000000000000000000000000000000000000000000000000027dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190600201906020826001010492830192600103820291508084116102a95790505b5050505050905090565b806000908051906020019061033c929190610340565b5050565b82805482825590600052602060002090600f016010900481019282156103f75791602002820160005b838211156103c757835183826101000a81548161ffff02191690837e01000000000000000000000000000000000000000000000000000000000000900402179055509260200192600201602081600101049283019260010302610369565b80156103f55782816101000a81549061ffff02191690556002016020816001010492830192600103026103c7565b505b5090506104049190610408565b5090565b61043691905b8082111561043257600081816101000a81549061ffff02191690555060010161040e565b5090565b9056fea165627a7a72305820a8f9f1f4815c1eedfb8df31298a5cd13b198895de878871328b5d96296b69b4e0029" abi = ''' [ @@ -747,11 +752,11 @@ Taking the following contract code as an example: .. doctest:: arrayscontract >>> ArraysContract = w3.eth.contract(abi=abi, bytecode=bytecode) - >>> my_account = web3.eth.account.from_key(PRIVATE_KEY) + >>> my_account = w3.eth.account.from_key(my_private_key) >>> nonce = w3.eth.get_transaction_count(my_account.address) >>> tx_params = ArraysContract.constructor([b'b']).buildTransaction({ - 'nonce': nonce - }) + ... 'nonce': nonce + ... }) >>> signed_transaction = my_account.signTransaction(tx_params) >>> tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) >>> tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) @@ -778,9 +783,8 @@ Taking the following contract code as an example: >>> w3.enable_strict_bytes_type_checking() >>> nonce = w3.eth.get_transaction_count(my_account.address) >>> tx_params = array_contract.functions.setBytes2Value([b'a']).buildTransaction({ - 'nonce': nonce - }) - >>> w3.eth.send_raw_transaction(signed_transaction.rawTransaction) + ... 'nonce': nonce + ... }) Traceback (most recent call last): ... ValidationError: @@ -1028,7 +1032,7 @@ For example: tx_params = myContract.functions.myFunction().buildTransaction({ 'nonce': nonce }) - signed_transaction = my_account.signTransaction(tx_params) + signed_transaction = my_account.sign_transaction(tx_params) tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) receipt = web3.eth.get_transaction_receipt(tx_hash) myContract.events.myEvent().processReceipt(receipt) @@ -1053,7 +1057,7 @@ For example: 'to':contract_address, 'nonce': nonce, }) - >>> signed_transaction = my_account.signTransaction(tx_params) + >>> signed_transaction = my_account.sign_transaction(tx_params) >>> tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) >>> tx_receipt = w3.eth.get_transaction_receipt(tx_hash) >>> rich_logs = contract.events.myEvent().processReceipt(tx_receipt) @@ -1207,7 +1211,7 @@ Event Log Object tx_params = contract.functions.transfer(alice, 10).buildTransaction({ 'gas': 899000, 'gasPrice': Web3.toWei(1, 'gwei'), - 'nonce: alice_nonce, + 'nonce': alice_nonce, }) signed_transaction = alice_account.signTransaction(tx_params) tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) @@ -1218,59 +1222,63 @@ Event Log Object >>> transfer_filter = my_token_contract.events.Transfer.createFilter(fromBlock="0x0", argument_filters={'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf'}) >>> transfer_filter.get_new_entries() [AttributeDict({'args': AttributeDict({'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', - 'to': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', - 'value': 10}), - 'event': 'Transfer', - 'logIndex': 0, - 'transactionIndex': 0, - 'transactionHash': HexBytes('0x9da859237e7259832b913d51cb128c8d73d1866056f7a41b52003c953e749678'), - 'address': '0xF2E246BB76DF876Cef8b38ae84130F4F55De395b', - 'blockHash': HexBytes('...'), - 'blockNumber': 2})] + 'to': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', + 'value': 10}), + 'event': 'Transfer', + 'logIndex': 0, + 'transactionIndex': 0, + 'transactionHash': + HexBytes('0xb262ed26953df1b0246dc322657cc7ab9bacd67804b4d6f773c5dba1867e643c'), + 'address': '0xF2E246BB76DF876Cef8b38ae84130F4F55De395b', + 'blockHash': HexBytes('...'), + 'blockNumber': 2})] >>> transfer_filter.get_new_entries() [] >>> private_key = provider.ethereum_tester.backend.account_keys[0] >>> alice_nonce = w3.eth.get_transaction_count(alice_account.address) >>> tx_params = contract.functions.transfer(alice, 10).buildTransaction({ - 'gas': 899000, - 'gasPrice': 674302241, - 'nonce: alice_nonce, - }) + ... 'gas': 899000, + ... 'gasPrice': 674302241, + ... 'nonce': alice_nonce, + ... }) >>> signed_transaction = alice_account.signTransaction(tx_params) >>> tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction) >>> tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) >>> transfer_filter.get_new_entries() [AttributeDict({'args': AttributeDict({'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', - 'to': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', - 'value': 10}), - 'event': 'Transfer', - 'logIndex': 0, - 'transactionIndex': 0, - 'transactionHash': HexBytes('0xa23e7ef4d2692c5cf34ee99123c9c73099e9c3b68c7850f91c1cbcb91ac327e0'), - 'address': '0xF2E246BB76DF876Cef8b38ae84130F4F55De395b', - 'blockHash': HexBytes('...'), - 'blockNumber': 3})] + 'to': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', + 'value': 10}), + 'event': 'Transfer', + 'logIndex': 0, + 'transactionIndex': 0, + 'transactionHash': + HexBytes('0x27ce29e52f61f611b68d238eabab579a6f1750283ce5df9ac5734a1c9e078d21'), + 'address': '0xF2E246BB76DF876Cef8b38ae84130F4F55De395b', + 'blockHash': HexBytes('...'), + 'blockNumber': 3})] >>> transfer_filter.get_all_entries() [AttributeDict({'args': AttributeDict({'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', - 'to': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', - 'value': 10}), - 'event': 'Transfer', - 'logIndex': 0, - 'transactionIndex': 0, - 'transactionHash': HexBytes('0x9da859237e7259832b913d51cb128c8d73d1866056f7a41b52003c953e749678'), - 'address': '0xF2E246BB76DF876Cef8b38ae84130F4F55De395b', - 'blockHash': HexBytes('...'), - 'blockNumber': 2}), - AttributeDict({'args': AttributeDict({'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', - 'to': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', - 'value': 10}), - 'event': 'Transfer', - 'logIndex': 0, - 'transactionIndex': 0, - 'transactionHash': HexBytes('0xa23e7ef4d2692c5cf34ee99123c9c73099e9c3b68c7850f91c1cbcb91ac327e0'), - 'address': '0xF2E246BB76DF876Cef8b38ae84130F4F55De395b', - 'blockHash': HexBytes('...'), - 'blockNumber': 3})] + 'to': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', + 'value': 10}), + 'event': 'Transfer', + 'logIndex': 0, + 'transactionIndex': 0, + 'transactionHash': + HexBytes('0xb262ed26953df1b0246dc322657cc7ab9bacd67804b4d6f773c5dba1867e643c'), + 'address': '0xF2E246BB76DF876Cef8b38ae84130F4F55De395b', + 'blockHash': HexBytes('...'), + 'blockNumber': 2}), + AttributeDict({'args': AttributeDict({'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', + 'to': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', + 'value': 10}), + 'event': 'Transfer', + 'logIndex': 0, + 'transactionIndex': 0, + 'transactionHash': + HexBytes('0x27ce29e52f61f611b68d238eabab579a6f1750283ce5df9ac5734a1c9e078d21'), + 'address': '0xF2E246BB76DF876Cef8b38ae84130F4F55De395b', + 'blockHash': HexBytes('...'), + 'blockNumber': 3})] Utils ----- @@ -1310,12 +1318,14 @@ For example: import json from web3 import Web3 - w3 = Web3(Web3.EthereumTesterProvider()) + provider = Web3.EthereumTesterProvider() + w3 = Web3(provider) + my_private_key = provider.ethereum_tester.backend.account_keys[0] bytecode = "0x606060405261022e806100126000396000f360606040523615610074576000357c01000000000000000000000000000000000000000000000000000000009004806316216f391461007657806361bc221a146100995780637cf5dab0146100bc578063a5f3c23b146100e8578063d09de08a1461011d578063dcf537b11461014057610074565b005b610083600480505061016c565b6040518082815260200191505060405180910390f35b6100a6600480505061017f565b6040518082815260200191505060405180910390f35b6100d26004808035906020019091905050610188565b6040518082815260200191505060405180910390f35b61010760048080359060200190919080359060200190919050506101ea565b6040518082815260200191505060405180910390f35b61012a6004805050610201565b6040518082815260200191505060405180910390f35b6101566004808035906020019091905050610217565b6040518082815260200191505060405180910390f35b6000600d9050805080905061017c565b90565b60006000505481565b6000816000600082828250540192505081905550600060005054905080507f3496c3ede4ec3ab3686712aa1c238593ea6a42df83f98a5ec7df9834cfa577c5816040518082815260200191505060405180910390a18090506101e5565b919050565b6000818301905080508090506101fb565b92915050565b600061020d6001610188565b9050610214565b90565b60006007820290508050809050610229565b91905056" ABI = json.loads('[{"constant":false,"inputs":[],"name":"return13","outputs":[{"name":"result","type":"int256"}],"type":"function"},{"constant":true,"inputs":[],"name":"counter","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"amt","type":"uint256"}],"name":"increment","outputs":[{"name":"result","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"a","type":"int256"},{"name":"b","type":"int256"}],"name":"add","outputs":[{"name":"result","type":"int256"}],"type":"function"},{"constant":false,"inputs":[],"name":"increment","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"a","type":"int256"}],"name":"multiply7","outputs":[{"name":"result","type":"int256"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"value","type":"uint256"}],"name":"increased","type":"event"}]') contract = w3.eth.contract(abi=ABI, bytecode=bytecode) - my_account = w3.eth.account.from_key(PRIVATE_KEY) + my_account = w3.eth.account.from_key(my_private_key) nonce = w3.eth.get_transaction_count(my_account.address) tx_params = contract.constructor().buildTransaction({ 'nonce': nonce From e92380e2cbb508f09127a45a67b2a1686345e5b6 Mon Sep 17 00:00:00 2001 From: lauws Date: Wed, 6 Apr 2022 01:43:07 +0800 Subject: [PATCH 4/4] Add 2386 news fragment --- newsfragments/2386.doc.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 newsfragments/2386.doc.rst diff --git a/newsfragments/2386.doc.rst b/newsfragments/2386.doc.rst new file mode 100644 index 0000000000..6ec8cafb32 --- /dev/null +++ b/newsfragments/2386.doc.rst @@ -0,0 +1 @@ +Change the ``transact`` method in Contract documentation to use ``send_raw_transaction`` or ``construct_and_sign_middleware``