Dependencies
Python
web3.py :
Web3.py is a Python library for interacting with Ethereum.
Itβs commonly found in decentralized apps (dapp) to help with sending transactions, interacting with smart contracts, reading block data, and a variety of other use cases.
Installation:
pip install web3
Py-solc-x | Py-solc :
Py-solc is a Python wrapper and version management tool for the solc Solidity compiler
Installation:
pip install py-solc-x
Ganache UI | Cli
Installation:
- Ganache Desktop Download Link
OR - Ganache-cli :
pip install ganache-cli
Lets Get Started
1. Open the directory where you have put your smart contract in the code editor like VSCode.
2. Create solidity file SmartContractDemo.sol
.
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract SmartContractDemo {
struct Person {
string name;
string dateOfBirth;
}
Person[] public idCard;
function numberOfEntries() public view returns (uint256) {
return idCard.length;
}
function store(string memory _name, string memory _birthday) public {
idCard.push(Person(_name, _birthday));
}
function changeData(
uint256 index,
string memory _name,
string memory _birthday
) public {
require(index <= numberOfEntries(), "Given index not present");
idCard[index] = Person(_name, _birthday);
}
function retrieve(uint256 index)
public
view
returns (string memory, string memory)
{
require(index <= numberOfEntries(), "Given index not present");
return (idCard[index].name, idCard[index].dateOfBirth);
}
}
3. Next create a python file deploy.py
. Here, we write the code required to push our contract to the blockchain.
4. First add the below code to import the web3 and py-solc-x in python files:
from web3 import Web3
from solcx import compile_standard, install_solc
import json
5. Read and store the content of SmartContractDemo.sol in a separate variable:
# extract the content of SmartContractDemo.sol
with open("./SmartContractDemo.sol", "r") as file:
smart_contract_demo = file.read()
6. Run the below code to install solc and compile the solidity code:
install_solc("0.6.0")
# Solidity source code
compiled_sol = compile_standard(
{
"language": "Solidity",
"sources": {"SmartContractDemo.sol" : { "content" : smart_contract_demo_file }},
"settings": {
"outputSelection": {
"*": {
"*": ["abi","metadata","evm.bytecode","evm.sourceMap"]
}
}
}
},
solc_version="0.6.0",
)
7. The below code will put in the compiled_code as a new JSON file.
with open("compiled_code.json","w") as file:
json.dump(compiled_sol,file)
8. Now before we deploy this contract, we need abi and bytecode first which we can get from compiled_code. This can be achieved by using this code:
# get abi
abi = compiled_sol["contracts"]["SmartContractDemo.sol"]["SmartContractDemo"]["abi"]
# bytecode
bytecode = compiled_sol["contracts"]["SmartContractDemo.sol"]["SmartContractDemo"]["evm"]["bytecode"]["object]
9. Connecting to Ganache:
To connect with ganache, we need an HTTP Provider URL, chain-id, the public key & private key which will be going to be used for deploying our smart contract.
How to get HTTP provider, chain-id, the public and private key of Transaction account:
If you are using Ganache UI
Step 1: Open Ganache App.
Step 2: Click on the Quickstart button.
This is what Ganache-UI looks like were
-
White-outlined box give us the RPC server i.e.,
http://127.0.0.1:7545
-
Yellow-outlined box give us chain_id i.e,
5777
-
Red-outlined box marks the public key of the account e.g.,
0xE1584b4d8f1b0CeEF97190B296DaF446674A3d63
- Blue-outlined box point to the button will show the private key associated with the given account
or
If you are using Ganache-CLI
Step 1: Open a terminal and then run the given command: ganache-cli
.
This will launch the ganache-cli terminal.
Step 2: Copy and note the public key and private key associated with any account, clain-id, and RPC server url which is http://127.0.0.1:8545
in my case.
Important Note:
- Accounts provided in the Ganache are only meant for development and testing purposes. Please, don't try to do actual transactions.
- Private keys are highly confidential. So, keep your private keys safe. It allows the user to access the wallet.
10. Managing private key
Adding private key:
Even if we are just using the private key associated with ganache, for best practice we should always avoid hard coding private key in our coding.
So, to store the private key, we will add it as an environment variable and extract it in our python program deploy.py
using OS module.
To do so :
- Inside same directory, add a file
.env
- Open
.env
file and write:export $PRIVATE_KEY=<put your private key here>
e.g., ![[Pasted image 20220523145104.png]] - Head back to
deploy.py
and import these module at the top: ![[Pasted image 20220523145413.png]]
11. Go back to our deploy.py
and connect it with ganache.
# Connecting to ganache
w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:8545"))
chain_id = 5777
my_address= "0xE1584b4d8f1b0CeEF97190B296DaF446674A3d63"
private_key = os.getenv("PRIVATE_KEY")
12. Now let's create the contract in python and get the latest transaction.
# Creating contract in python
SmartContractDemo = w3.eth.contract(abi=abi, bytecode=bytecode)
# Get the latest transaction
transaction = SmartContractDemo.constructor().buildTransaction({
"chainId": chain_id,
"gasPrice": w3.eth.gas_price,
"from": my_address,
"nonce": nonce,
})
13. Finally, let's sign our transaction and deploy it.
# Sign the transaction
signed_txn = w3.eth.account.sign_transaction(transaction, private_key=private_key)
print("Deploying Contract!")
# Sent it
tx_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction)
# Wait for the transaction to be mined, and get the transaction receipt
print("Waiting for Transaction to finish...")
tx_receipt=w3.eth.wait_for_transaction_receipt(tx_hash)
print(f"Done! Contract Deployed to {tx_receipt.contractAddress}")
Well done! We have successfully learned to deploy Smart Contract to the local blockchain.
Interacting with our smart contract
There are two types of Interaction one can make with a Smart Contract:
- Call -> Simulate making the call and getting a return value
- Transact -> Actually make a state change
Let's perform both the interaction with our smart contract :
1. To call a public function numberOfEnteries()
from SmartContractDemo, go back to deploy.py
.
# Working with the contracts
smart_contract_demo = w3.eth.contract(address=tx_receipt.contractAddress, abi=abi)
print(f"Number of Enteries in idCard array is {smart_contract_demo.functions.numberOfEnteries()}")
2. Now a state change by adding a data to the idCard
array using the function store()
:
store_transaction = smart_contract_demo.functions.store("Naruto", "10-10-1999").buildTransaction({
"chainId": chain_id,
"gasPrice": w3.eth.gas_price,
"from":my_address,
"nonce":nonce+1,
})
signed_store_txn = w3.eth.account.sign_transaction(
store_transaction, private_key=private_key
)
signed_store_hash = w3.eth.send_raw_transaction(signed_store_txn.rawTransaction)
tx_receipt = w3.eth.wait_for_transaction_receipt(signed_store_hash)
Whenever we make a state change, the transaction has to be signed first with our private key.
Note:
Calling a view or pure public function doesn't cost anything.
Whereas deploying a smart contract and making a function call that changes the state of the blockchain cost some amount of GAS Fees.
3. Finally, finish it by again calling numberOfEnteries()
function and retrieve() function.
print(f"Number of Enteries in idCard array is {smart_contract_demo.functions.numberOfEnteries()}")
print(f"Person at 0th index in idCard array is {smart_contract_demo.functions.idCard(0)}")
4. Now run the deploy.py
file (run via terminal: python ./deploy.py
).
OUTPUT:
Now, if we check the ganache-cli, we can find two transaction records there,
- The First transaction is about contract creation.
- The Second transaction is made we call the store function to add Personal detail to idCard array.
Resource Link
Project Link:
Documentation:
- web3.py : https://web3py.readthedocs.io/en/stable/
- py-solc-x : https://solcx.readthedocs.io/en/latest/
CONNECT WITH ME
I hope you have found this article helpful. Thank you for reading!
Top comments (0)