This is a stduy note of the Youtube videoSolidity, Blockchain, and Smart Contract Course.
1 Python Ethereum Dev Tools
- Web3.py is a Python library for interacting with Ethereum. - Brownie, built on top of
Web3.py
, is a Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine. - Ganache is a personal blockchain for rapid Ethereum and Corda distributed application development. You can use Ganache across the entire development cycle; enabling you to develop, deploy, and test your dApps in a safe and deterministic environment.
- Infura: Infura API provides instant access over HTTPS and WebSockets to the Ethereum network. Ensure transactions go through smoothly and quickly at the best prices with Infura Transactions (ITX).
China ids are list in Chainlist.org.
Use pip3 install web3
to install Web3.py
.
Use pip3 install solcx
to install py-solc-x
. The solcx
is a Python module that let you interact with solc
compiler. You need to install the required solc
compiler before compiling code:
|
|
The flow to create a new contract in chain:
- Create a contructor in Python with
abi
andbytecode
:MyConstructor = w3.eth.contract(abi = abi, bytecode = bytecode)
- Get the
nonce
:nonce = w3.eth.getTransactionCount(my_address)
- Build a new contract, use the Python contract’s
constructor().buildTransaction()
withchainId
,from
, andnonce
. - To sing a new contract transaction:
signed_tx = w3.eth.account.sign_transaction(transaction, private_key)
- To deploy a new contract:
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
- To wait and get transaction receipt:
tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
Working with a contract needs its address from its receipt and its ABI: my_contract = w3.eth.contract(address=tx_receipt.contractAddress, abi=abi)
. Then you can interact with the on-chain contract in two way:
- call, no change to transaction states. Call is a simulation of making the call and getting a return value. For example:
my_contract.functions.retrieve().call
. - transact, needs gas to make a state change. you need to build transaction, sign it, deploy it, and optionally wait for it.
- build:
my_tx = my_contract.functions.my_function(arg).buildTransaction(chainId, from, nonce)
. - sign:
signed_tx = w3.eth.account.sign_transaction(my_tx, private_key)
- deploy:
send_tx = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
- wait:
tx_receipt = w3.eth.wait_for_transaction_receipt(send_tx)
.
- build:
Use yarn global add ganache-cli
to install Ganache CLI. Use ganache-cli --deterministic
to run Ganache CLI in deterministic way – the same accounts and private keys.
To call the mainnet or test ethereum network, use Infura to create and project and find the connection URL for each network.
The source code is below:
|
|
2 The Brownie Framework
Working with different chains and different contracts requires a lot of low level tasks. Brownie is a Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine. Popular products such as Yearn Finance (lending management), Curve.Fi (exchange), Badger.com (bitcoin yield DAO) use the Brownie framework.
Use pipx
to install brownie as the following:
|
|
Then use brownie init
to intialize a project in the current folder. Put contracts into the contracts
folder. Run brownie compile
to compile contracts and put outputs in build/contracts
folder.
Put deploy scripts in the scripts
folder and use brownie run my_script.py
to run the Python script. Brownie will spin up a local Ganache CLI by default as the deploy Chain.
Brownie performs many tasks automatically such as open a contract file, compile it and connect to a chain. We only need to provide an address and a private key. Use brownie accounts new my-account
to create an account named my-account
with a specified private key and password.
Then you can load an account with account = accounts.load("my-account")
.
Alternatively, you can load a private key from an environment variable. First, export your private key in .env
file. Then config brownie-config.yaml
with dotenv: .env
. Use the code account = accounts.add(os.getenv("PRIVATE_KEY"))
to get the private key. You can also define wallets
in Brownie configuration file. Then use brownie’s config
to get an account.
The code to deploy, read and change data using Brownie is as following:
|
|
To run it in a specifed network such as kovan
, run brownie run deploy.py --network kovan
. If the network is not a development network, Brownie creates a record in the deployments/42
where 42
is the chain id of kovan
.