#
web3py
#
Introduction
web3.py is a Python library for interacting with Ethereum.
It’s commonly found in decentralized apps (dapps) to help with sending transactions, interacting with smart contracts, reading block data, and a variety of other use cases.
The original API was derived from the Web3.js Javascript API, but has since evolved toward the needs and creature comforts of Python developers.
#
Gettings Started
To install:
pip install web3py
#
Connecting to a Provider
This library depends on a connection to an Ethereum node. These connections are called Providers and there are several ways to configure them.
#
Test Provider
For quick prototyping, you can use a test provider, eth-tester. This provider includes some accounts prepopulated with test ether and instantly includes each transaction into a block. web3.py makes this test provider available via EthereumTesterProvider.
from web3 import Web3, EthereumTesterProvider
w3 = Web3(EthereumTesterProvider())
w3.is_connected()
#
Local Providers
The hardware requirements are steep, but the safest way to interact with Ethereum is to run an Ethereum client on your own hardware. For locally run nodes, an IPC connection is the most secure option, but HTTP and websocket configurations are also available. By default, the popular Geth client exposes port 8545 to serve HTTP requests and 8546 for websocket requests. Connecting to this local node can be done as follows:
from web3 import Web3, AsyncWeb3
# IPCProvider:
w3 = Web3(Web3.IPCProvider('./path/to/geth.ipc'))
# HTTPProvider:
w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))
# WebsocketProvider:
w3 = Web3(Web3.WebsocketProvider('wss://127.0.0.1:8546'))
w3.is_connected()
#
Remote Providers
The quickest way to interact with the Ethereum blockchain is to use a remote node provider, like Infura, Alchemy, QuickNode, or Chainstack. You can connect to a remote node by specifying the endpoint, just like the previous local node example:
from web3 import Web3, AsyncWeb3
w3 = Web3(Web3.HTTPProvider('https://<your-provider-url>'))
w3 = AsyncWeb3(AsyncWeb3.AsyncHTTPProvider('https://<your-provider-url>'))
w3 = Web3(Web3.WebsocketProvider('wss://<your-provider-url>'))
#
Connecting to Polygon Mumbai
Using a public rpc endpoint. (You can find links at chainlist.org)
from web3 import Web3
web3 = Web3(Web3.HTTPProvider("https://matic-mumbai.chainstacklabs.com"))
print("MUMBAI Connection: ", web3.is_connected())
Using Alchemy
from web3 import Web3
alchemy_url = "https://polygon-mumbai.g.alchemy.com/v2/<ALCHEMY_KEY>"
web3 = Web3(Web3.HTTPProvider(alchemy_url))
print("MUMBAI Connection: ", web3.is_connected())
INFO
There are breaking changes from version 5.x to 6.x. All methods were changed from camel case to snake case
For example:
# web3py 5.x
print(web.isConnected())
# web3py 6.x
print(web.is_connected())
#
Getting Blockchain Info
It’s time to start using web3.py! Once properly configured, the w3 instance will allow you to interact with the Ethereum blockchain.
Try getting all the information about the latest block:
latest_block = web3.eth.block_number
print("Latest block:", latest_block)
Get the balance of an account:
balance = web3.eth.get_balance('0x742d35Cc6634C0532925a3b844Bc454e4438f44e')
print(balance)
Get the info on a transaction:
tx = web3.eth.get_transaction('0x42306f309f4139c98fb828ca063be38354f1ac9bf57642fc9c2d325b1367819c')
print(tx)
#
Transactions
Sending a transaction
tx = {
"from": account.address,
"to": user2.address,
"value": 12345,
"nonce": web3.eth.get_transaction_count(account.address),
"gas": 100000,
"gasPrice": 10000,
"chainId": web3.eth.chain_id
}
singed_tx = web3.eth.account.sign_transaction(tx, account.privateKey)
web3.eth.send_raw_transaction(singed_tx.rawTransaction)
#
Deploying a Smart Contract
import vyper
source_vyper = """
# @version ^0.3.6
val: public(uint16)
@external
def __init__():
self.val = 1904
"""
compiled_vyper = vyper.compile_code(source_vyper, output_formats=['abi', 'bytecode', 'opcodes'])
abi = compiled_vyper.get('abi')
bytecode = compiled_vyper.get('bytecode')
contract = web3.eth.contract(abi=abi, bytecode=bytecode)
transaction = contract.constructor().build_transaction({
"from": account.address,
'nonce' : web3.eth.get_transaction_count(account.address),
'gas': 9000000,
'gasPrice': web3.to_wei(50, 'gwei'),
'chainId': web3.eth.chain_id
})
signed_tx = web3.eth.account.sign_transaction(transaction, account.privateKey)
tx_hash = web3.eth.send_raw_transaction(signed_tx.rawTransaction)
print(f"Waiting for transaction {web3.toHex(tx_hash)} to be included in a block...")
response = web3.eth.wait_for_transaction_receipt(web3.toHex(tx_hash))
contract_address = response.get('contractAddress')
print("Contract deployed at:", contract_address)
Deployment transaction
{
'value': 0,
'chainId': 131277322940537,
'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf',
'nonce': 0,
'gas': 90000,
'gasPrice': 50000000000,
'data': '0x346100ae5760006000556100946100196000396100946000f36003361161000c5761007c565b60003560e01c3461008257632e64cec1811861003657600436186100825760005460405260206040f35b636057361d811861005b57602436186100825760043560005560005460405260206040f35b633c6bb436811861007a57600436186100825760005460405260206040f35b505b60006000fd5b600080fda165767970657283000306000b005b600080fd',
'to': b''
}
#
Interacting with Smart Contracts
deployed_contract = web3.eth.contract(abi=abi, address=contract_address)
stored_value = deployed_contract.functions.val().call()
print("Stored value in contract:", stored_value)