Photo by Emran Yousof / Unsplash

Background

俗話說的好 畢圈一日 人間一年..... 這篇主要是記錄如何藉由web3.py來執行 smart contract 的function.

Install

到指定的目錄夾下切換成虛擬環境. 接著再安裝 web3.py 的套件.

$ source .venv/bin/activate
$ pip3 install web3

Config

config.ini 中有兩個資訊要填入. 一個是etheruem的node. 我們需要透過這個 node 來跟整個區塊鏈做連接. 這部分測試時可用 Ganache 來取代. 另外一個則是合約地址. 當你用 Trffule (前面系列有介紹到) depoly 到鏈上時候給你一個 contract address. 把他複製下來並貼到config.ini

config.ini

[DEFAULT]
NODE_HSOT = http://127.0.0.1:8545
CONTRACT_ADDRESS = 0xadd34bf823766846773b738dc8b6c591441a0061

Code

run.py

from web3 import Web3
from datetime import datetime
from pprint import pprint
import sys
import os
import configparser
import json

config = configparser.ConfigParser()
config.read('config.ini')

CONTRACT_ADDRESS = config['DEFAULT']['CONTRACT_ADDRESS']

def main():
    # 先建立 RPC 的連線
    web3 = Web3(Web3.HTTPProvider(config['DEFAULT']['NODE_HSOT']))
    # .sol 檔 compile 完都會產生一個 .json檔. 讀取 json檔的內容
    with open('/path/to/contract.json') as f:
        insatnce = json.load(f)
    # 建立 contract 的 object
    _contract = web3.eth.contract(address=Web3.toChecksumAddress(CONTRACT_ADDRESS), abi=inTimeInsatnce['abi'], bytecode=inTimeInsatnce['bytecode'])
    row = _contract.functions.getUser().call({'from': web3.eth.accounts[0]})
    print(row)
    row = _contract.functions.addUser().transact({'from': web3.eth.accounts[1]})
    print(row)

if __name__ == "__main__":

    
    start = datetime.now()
    argv = sys.argv[1:]

    main()

    end = datetime.now()
    print([str(start), str(end), str(end - start)])

講解一下用法 getUser & addUser 分別是 .sol 檔中的 function name. 括弧內就是帶入對應的參數(如果有需要的話). 那每個function中主要有兩種用法分別是 call & transact. (其實還有其他種, 有興趣的可以上官網看一下. 我個人是用這兩種就夠了).

在 smart contract的概念中正常是呼叫每個 smart contarct都應該要付gas的費用. 但是這樣也太不人性化. 所以就設計成如果 call 的 function 沒有改變到 contract 中的任何變數值則不用收取gas費用. 如果有改變到的話則依照function的複雜程度收費.

  • call: 這個的使用目的性是為了取得資料. 就表示他搭配到的 solidity function 都是那種不會改變變數值的 function. 這個對應到solidity的參數是 returns.
  • transact: 這個則是會傳送一筆交易到區塊鏈上來跟合約互動. (可以想成call一個api request, 那當然這種的就要付gas費用). 這個對應到 solidity的參數是 payable

Reference