[Part 1/2] Deploy a Smart Contract on Ethereum with Python, Truffle and web3py
In this tutorial, we'll write a simple smart contract, deploy it to a personal Ethereum blockchain, and call the contract from a Python script.
What you need to have installed before we proceed:
- Python3 v3.5.3 or later, I had some issues using version 3.8 then switched to 3.5.3;
- NodeJS v8.9.4 or later (for installing
truffle
);
The full project code is available at GitHub
TOC
- Project Setup
- Writing the smart contract
- Deploying smart contract to the blockchain
- Calling the deployed contract
1. Project setup
First, let's create a folder for the project:
$ mkdir hello-eth
$ cd hello-eth
Inside hello-eth
folder, install truffle
:
npm install truffle
...
# You should something like this once the installation process is finished
+ truffle@5.1.25
We will use the truffle
CLI tool to initialize an empty smart contract project:
$ ./node_modules/.bin/truffle init
# if truffle was installed globally (npm install -g truffle): $ truffle init
The above command will create the following project structure:
contracts/
: Directory for Solidity contracts source code (.sol
files).migrations/
: Directory for contracts migration files.test/
: Directory for test files. Won't be covered in this tutorial.truffle.js
: Truffle configuration file.
contracts/
and migrations/
folders will already contain a Migration
contract and its deploy script (1_initial_migration.js
). This contract is used by truffle to keep track of the migrations of our contracts. It won't be covered in this tutorial, so don't worry about it.
2. Writing the smart contract
Yes, I'll use the Hello World
example. Create a file called HelloWorld.sol
inside contracts/
folder and add the following content to it:
pragma solidity >= 0.5.0 < 0.7.0;
contract HelloWorld {
function sayHello() public pure returns (string memory) {
return 'Hello World!';
}
}
From the project root folder, use truffle
to compile the contract:
$ ./node_modules/.bin/truffle compile # or just truffle compile if installed globally...
It will output the compiled contract HelloWorld.sol
as HelloWorld.json
inside build/contracts/
folder.
We now have a compiled contract and are ready to deploy it to our running to the (local) blockchain.
3. Deploying smart contract to the blockchain
To deploy our smart contract to the blockchain we first need:
- a migration script;
- a blockchain to deploy the contract to;
For the migration script, create a file named 2_deploy_contract.js
inside migrations/
folder and add the following content to it:
var HelloWorld = artifacts.require("HelloWorld");
module.exports = function(deployer) {
deployer.deploy(HelloWorld);
};
Truffle suite contains a personal blockchain that we can use for testing purposes. Open your terminal and run:
$ truffle develop
You should see an output similar to the following:
Truffle Develop started at http://127.0.0.1:9545/
Accounts:
(0) 0xdfb772fba7631b5bfde93cc3e2b0e488d1a17b2a
...
(9) 0x974779d6a98264043e8bb1c8b0cf93d9c7141a29
Private Keys:
...
truffle(develop)>
We can now migrate
our contract, which calls each migration in migrations/
(in order), deploying the contracts to the blockchain.
truffle(develop)> migrate
Starting migrations...
...
2_deploy_contracts.js
=====================
Deploying 'HelloWorld'
----------------------
> transaction hash: 0xddc3dd045a7b6f70063303ff534d07e93c1dcb7a0a6c15e42fe281c7d2ab53e8
> Blocks: 0 Seconds: 0
> contract address: 0xb7afC8dB8EEf302cd30553B39cEa0599093FDE3C
contract address
is the address on the Ethereum network that hosts this contract instance.
Sweet! We now have a Smart Contract deployed on our personal Ethereum blockchain. Next step is call it from a Python script.
4. Calling the deployed contract
Under the project root folder (hello-eth/
) create a file named app.py
with the following content (pay attention to the comments explaining the script):
import json
from web3 import Web3, HTTPProvider
# truffle development blockchain address
blockchain_address = 'http://127.0.0.1:9545'
# Client instance to interact with the blockchain
web3 = Web3(HTTPProvider(blockchain_address))
# Set the default account (so we don't need to set the "from" for every transaction call)
web3.eth.defaultAccount = web3.eth.accounts[0]
# Path to the compiled contract JSON file
compiled_contract_path = 'build/contracts/HelloWorld.json'
# Deployed contract address (see `migrate` command output: `contract address`)
deployed_contract_address = '0xb7afC8dB8EEf302cd30553B39cEa0599093FDE3C'
with open(compiled_contract_path) as file:
contract_json = json.load(file) # load contract info as JSON
contract_abi = contract_json['abi'] # fetch contract's abi - necessary to call its functions
# Fetch deployed contract reference
contract = web3.eth.contract(address=deployed_contract_address, abi=contract_abi)
# Call contract function (this is not persisted to the blockchain)
message = contract.functions.sayHello().call()
print(message)
Now, execute the following commands in your terminal:
$ pip3 install web3
$ python3 app.py
> 'Hello World!'
Wrapping up
In this tutorial, you learned how to:
- Write a simple Smart Contract in Solidity;
- Create a personal Ethereum Blockchain for tests and development;
- Deploy a contract to the blockchain using
truffle
; - Call the contract function from a Python application.