Skip to main content

Web3-Python with Ganache (local)

info

This is a local deploy powered by Ganache. It works just like the Javascript VM on Remix. We will configure the Ganache network, then build->sign->send the contract. Also, we will see how to update the contract, through again build->sign->send procedure.

Web3-python with Ganache-UI#

Python script#

folder structure

$ tree -a  .โ”œโ”€โ”€ .envโ”œโ”€โ”€ .gitignoreโ”œโ”€โ”€ SimpleStorage.solโ”œโ”€โ”€ compiled_code.jsonโ””โ”€โ”€ deploy.py
deploy.py
## import solcx## solcx.install_solc('0.6.0')import jsonfrom numpy import signfrom solcx import compile_standardfrom web3 import Web3import osfrom dotenv import load_dotenvload_dotenv()
with open("./SimpleStorage.sol", 'r') as file:    simple_storage_file = file.read()    ## print(simple_storage_file)
## compile like remixcompiled_sol = compile_standard(    {        "language": "Solidity",        "sources": {"SimpleStorage.sol": {"content": simple_storage_file}},        "settings": {            "outputSelection": {                "*": {                    "*": ["abi", "metadata", "evm.bytecode", "evm.sourceMap"]                }            }        }    },    solc_version="0.6.0",)
with open("compiled_code.json", "w") as file:    json.dump(compiled_sol, file)

bytecode = compiled_sol["contracts"]["SimpleStorage.sol"]["SimpleStorage"]["evm"]["bytecode"]["object"]abi = compiled_sol["contracts"]["SimpleStorage.sol"]["SimpleStorage"]["abi"]

deploy through python to Ganache

note

After the compiling, we now continue to deploy in python code. Copy and paste the private key into .env, and copy paste the account address, as well as server address from the Ganache UI above.

caution

Note that the chain_id should stick to 1337, otherwise errors reported. So you better go to Ganache UI, check or change the NETWORK ID to 1337 if not.
The private key should be headed by 0x in python, add if none.

deploy.py
#...
## Ganache play as the javascript vm on remixw3 = Web3(Web3.HTTPProvider("http://127.0.0.1:7545"))chain_id = 1337  ## NETWORK IDmy_address = "0x2cdacb1F3ccFb0e806485C3ccC7526bBaa9F5935"  ## MetaMask walletprivate_key = os.getenv("PRIVATE_KEY")
## create contract in pythonSimpleStorage = w3.eth.contract(abi=abi, bytecode=bytecode)## build a transaction->sign it->send itnonce = w3.eth.getTransactionCount(my_address)transaction = SimpleStorage.constructor().buildTransaction({    "gasPrice": w3.eth.gas_price,    "chainId": chain_id, "from": my_address, "nonce": nonce,})signed_txn = w3.eth.account.signTransaction(transaction, private_key)  ## sign
print("Deploying contract...")tx_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction)  ## send
tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)  ## wait for the receiptprint("Deployed!")

work with deployed contract

note

We can now deployed the contract to the blockchain, but we want to update it after deployment (send another transaction to the blockchain, which insert a new number 15).

deploy.py
#...
## work with contract: contract address and abisimple_storage = w3.eth.contract(address=tx_receipt.contractAddress, abi=abi)
## again: build->sign->sendprint(simple_storage.functions.retrieve().call())print("Updating Contract...")store_transaction = simple_storage.functions.store(15).buildTransaction({    ## different nonce for different transaction    "chainId": chain_id, "gasPrice": w3.eth.gas_price, "from": my_address, "nonce": nonce + 1,})signed_store_txn = w3.eth.account.signTransaction(    store_transaction, private_key)send_store_tx = w3.eth.send_raw_transaction(signed_store_txn.rawTransaction)tx_receipt = w3.eth.wait_for_transaction_receipt(send_store_tx)print("Updated!")print(simple_storage.functions.retrieve().call())  ## 0->15

deploy on ganache#

caution

check the balance in Ganache UI, if it is zero, you should go to setting and make gas price zero.

$ python deploy.py      Deploying contract...Deployed!0Updating Contract...Updated!15

Replace Ganache-UI by CLI tool#

set-up#

node --versionyarn --versionyarn global add ganache-cliganache-cli --version

start ganache#

$ ganache-cli --deterministicGanache CLI v6.12.2 (ganache-core: 2.13.2)
Available Accounts==================(0) 0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1 (100 ETH)(1) 0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0 (100 ETH)(2) 0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b (100 ETH)(3) 0xE11BA2b4D45Eaed5996Cd0823791E0C93114882d (100 ETH)(4) 0xd03ea8624C8C5987235048901fB614fDcA89b117 (100 ETH)(5) 0x95cED938F7991cd0dFcb48F0a06a40FA1aF46EBC (100 ETH)(6) 0x3E5e9111Ae8eB78Fe1CC3bb8915d5D461F3Ef9A9 (100 ETH)(7) 0x28a8746e75304c0780E011BEd21C72cD78cd535E (100 ETH)(8) 0xACa94ef8bD5ffEE41947b4585a84BdA5a3d3DA6E (100 ETH)(9) 0x1dF62f291b2E969fB0849d99D9Ce41e2F137006e (100 ETH)
Private Keys==================(0) 0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d(1) 0x6cbed15c793ce57650b9877cf6fa156fbef513c4e6134f022a85b1ffdd59b2a1(2) 0x6370fd033278c143179d81c5526140625662b8daa446c22ee2d73db3707e620c(3) 0x646f1ce2fdad0e6deeeb5c7e8e5543bdde65e86029e2fd9fc169899c440a7913(4) 0xadd53f9a7e588d003326d1cbf9e4a43c061aadd9bc938c843a79e7b4fd2ad743(5) 0x395df67f0c2d2d9fe1ad08d1bc8b6627011959b79c53d7dd6a3536a33ab8a4fd(6) 0xe485d098507f54e7733a205420dfddbe58db035fa577fc294ebd14db90767a52(7) 0xa453611d9419d0e56f499079478fd72c37b251a94bfde4d19872c44cf65386e3(8) 0x829e924fdf021ba3dbbc4225edfece9aca04b929d6e75613329ca6f1d31c0bb4(9) 0xb0057716d5917badaf911b193b12b910811c1497b5bada8d7711f758981c3773
HD Wallet==================Mnemonic:      myth like bonus scare over problem client lizard pioneer submit female collectBase HD Path:  m/44'/60'/0'/0/{account_index}
Gas Price==================20000000000
Gas Limit==================6721975
Call Gas Limit==================9007199254740991
Listening on 127.0.0.1:8545
info

Luckily, the balance here is 100 faucet ETH. And the default NETWORK ID is also 1337.

deploy on ganache#

replace address, private key, then in another terminal tab:

$ python deploy.py      Deploying contract...Deployed!0Updating Contract...Updated!15

Back to the Ganache-cli tab:

  Transaction: 0x6aa2ff811bc7fd37fd7c3ab9c04805950a6a2e5c04f9aaeb092c44259274a1b0  Contract created: 0xe78a0f7e598cc8b0bb87894b0f60dd2a88d6a8ab  Gas usage: 366119  Block Number: 1  Block Time: Sun Apr 17 2022 19:57:48 GMT-0400 (Eastern Daylight Time)
eth_getTransactionReceipteth_chainIdeth_calleth_gasPriceeth_chainIdeth_estimateGaseth_sendRawTransaction
  Transaction: 0x290a6a3bce3711aec76159e38e490e8c2ddc6f3850d130812a12d082a6a027b5  Gas usage: 41446  Block Number: 2  Block Time: Sun Apr 17 2022 19:57:48 GMT-0400 (Eastern Daylight Time)
eth_getTransactionReceipteth_chainIdeth_call