Home  >  Article  >  Backend Development  >  Access Ethereum with Python via web3.py

Access Ethereum with Python via web3.py

王林
王林forward
2023-04-12 13:46:061704browse

Access Ethereum with Python via web3.py

If you want to access Ethereum through Python, you can see from Ethereum's official Github that there are two modules that can be achieved: web3.py and pyethereum. As far as my current understanding is concerned, the difference between the two is that web3.py is mainly used as a client for external access to Ethereum, which means that the web3.py function library itself will not become a blockchain node, nor will it perform blocks. Chain synchronization is to connect a node on the blockchain and use the blockchain as an external database; while pyethereum is more like geth, which is used to make itself a blockchain node. Block synchronization will be performed normally, and you can also start mining as a miner.

In this article, because we want a lightweight client to interact with the blockchain and do not want to prepare a huge storage space to store blockchain data, we will use web3. py is the main one.

  • Configure the web3.py execution environment
  • Connect to the Ethereum node through web3.py
  • Access the ERC20 contract on the blockchain
  • Sign And send the transaction

Configure web3.py execution environment

web3.py can be installed directly through pip.

pip install web3

It should be noted that when you want to install on Windows, you will need to install Visual C Builder in advance, otherwise it will fail because it cannot be compiled in the final stage of the installation.

Connecting Ethereum nodes through web3.py

web3.py Because it will not exist as a blockchain node, it needs a node to access the blockchain. material. Generally speaking, the safest way is to use geth or parity to build your own nodes. However, if you don't want to build your own nodes, you can consider looking at the HTTP node service provided by infura.

Taking infura's current API as an example, if you want to connect to the Ropsten test chain, the link URL is https://ropsten.infura.io/v3/api_key, where api_key needs to be registered to obtain an account. The following program imitates the practice of web3.py's built-in auto.infura, which reads the INFURA_API_KEY parameter from the environment variable to form the HTTP address of infura.io, which is used to establish a connection with the Ropsten test chain.

Deposit and Withdraw ERC20 Contracts on the Blockchain

import os
from web3 import (
HTTPProvider,
Web3,
)
INFURA_ROPSTEN_BASE_URL = 'https://ropsten.infura.io/v3'
def load_infura_url():
key = os.environ.get('INFURA_API_KEY', '')
return "%s/%s" % (INFURA_ROPSTEN_BASE_URL, key)
w3 = Web3(HTTPProvider(load_infura_url()))

Before you start depositing and withdrawing contracts, you need to talk about what ABI is. In Ethereum, because contracts all exist in the form of compiled binary code, the function library has no way to directly know what the content transmitted by the contract is, because the return values ​​​​of the contract are all binary. Therefore, before operating the contract, an ABI file needs to be provided to tell the function library how to use the contract.

# Assume the contract we're going to invoke is a standard ERC20 contract.
with open("erc20.abi.json") as f:
erc20_abi = json.load(f)
# Web3 accept only checksum address. So we should ensure the given address is a
# checksum address before accessing the corresponding contract.
contract_addr = w3.toChecksumAddress('0x4e470dc7321e84ca96fcaedd0c8abcebbaeb68c6');
erc20_contract = w3.eth.contract(address=contract_addr, abi=erc20_abi)
for func in erc20_contract.all_functions():
logger.debug('contract functions: %s', func)
logger.debug("Name of the token: %s", erc20_contract.functions.name().call())

Suppose here that we want to access the smart contract with the address 0x4e470dc7321e84ca96fcaedd0c8abcebbaeb68c6 on the Ropsten test chain. This contract is an ERC20 contract randomly found through etherscan, so you can use the standard ERC20 ABI to access it. When we create the instance of this contract, we first run a loop to print out all the functions in the contract (this step is actually listing the information on the ABI), and then try to call name() in the contract to obtain the contract declaration. Token name. The final output content is as follows:

2018-09-07 15:02:53,815 | __main__ | DEBUG | contract functions: <Function name()>
2018-09-07 15:02:53,816 | __main__ | DEBUG | contract functions: <Function approve(address,uint256)>
2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions: <Function totalSupply()>
2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions: <Function transferFrom(address,address,uint256)>
2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions: <Function decimals()>
2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions: <Function balanceOf(address)>
2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions: <Function symbol()>
2018-09-07 15:02:53,825 | __main__ | DEBUG | contract functions: <Function transfer(address,uint256)>
2018-09-07 15:02:53,825 | __main__ | DEBUG | contract functions: <Function allowance(address,address)>
2018-09-07 15:02:54,359 | __main__ | DEBUG | Name of the token: KyberNetwork

Sign and send the transaction

In the above example, when calling the smart contract, you directly call the function in the contract, but this is generally It can only be used to read data on the blockchain. If you want to write data to the blockchain by calling a smart contract, you must call the contract in another way, that is, you must first sign the transaction and then pay gas to execute the transaction.

Suppose we also want to call an ERC20 contract and execute the transferFrom() function on the contract. transferFrom() requires three parameters _from, _to, and _value, which means that the transfer amount is to be transferred from the _from account to the _to account, and the transfer amount is _value.

# Set the account which makes the transaction.
account = w3.toChecksumAddress(os.environ.get('ETHEREUM_ACCOUNT', ''))
w3.eth.defaultAccount = account
# Web3 accept only checksum address. So we should ensure the given address is a
# checksum address before accessing the corresponding contract.
contract_address = w3.toChecksumAddress('0x4e470dc7321e84ca96fcaedd0c8abcebbaeb68c6')
contract = w3.eth.contract(address=contract_address, abi=contract_abi)
# Prepare the necessary parameters for making a transaction on the blockchain.
estimate_gas = contract.functions.transferFrom(account, account, w3.toWei('1', 'eth')).estimateGas()
nonce = w3.eth.getTransactionCount(account)
# Build the transaction.
txn = contract.functions.transferFrom(account, account, w3.toWei('1', 'eth')).buildTransaction({
'chainId': 3,
'gas': estimate_gas,
'gasPrice': w3.toWei('1', 'gwei'),
'nonce': nonce
})
logger.debug('Transaction: %s', txn)
# Sign the transaction.
private_key = bytes.fromhex(os.environ.get('ETHEREUM_ACCOUNT_PKEY', ''))
signed_txn = w3.eth.account.signTransaction(txn, private_key=private_key)
tx_hash = w3.eth.sendRawTransaction(signed_txn.rawTransaction)
logger.debug('Txhash: 0x%s', bytes.hex(tx_hash))

In the above program, lines 2 ~ 3 first read the account we want to use from the environment variable. This account will be used to send transactions. Of course, gas will also be paid from this account. buckle. Lines 10 ~ 20 create a raw transaction. In this transaction, because we need to specify parameters including gas, nonce, etc., we need to confirm how many parameters to set in the previous lines 11 ~ 12. Then the most important lines 25 ~ 26 read the private key and use the private key to sign the transaction. It is assumed here that the private key will be composed of Hex-encoded text, so bytes.fromhex is used to convert the Hex encoding back to byte format. After signing, send the transaction. When sending the transaction, the API will return the transaction hash in byte format. You can encode it and print it out. Then you can search for the transaction on etherscan.

The above is the detailed content of Access Ethereum with Python via web3.py. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:51cto.com. If there is any infringement, please contact admin@php.cn delete