Python web3
Pythonでのコントラクトへのアクセスプロジェクトを少しずつですが作成し始めました。
軽く調べたりしましたがJavaScriptからアクセスする形よりも資料が少ないので非常に苦戦しそうです!
簡単にですが現時点でなんとなく理解したこととかをまとめてみます。
Pythonにもweb3のライブラリがあるのでそれを用いることでアクセスすることが可能です。
インストール
pip3 install web3
実際に使用するための準備
from web3 import Web3,HTTPProvider web3 = Web3(HTTPProvider("http://127.0.0.1:7545")) # Ganacheなどで動かしているアドレスとポート
これだけでローカルで動作させているブロックチェーンには接続できます。
blockNumber = web3.eth.blockNumber
とかやれば情報が取得できるので確認できます。
これだけだとコントラクトのメソッドを呼び出せないので自作したコントラクトのインスタンスを取得する必要があります。
JavaScriptの時は以下の感じでした。
import artifacts from '../build/contracts/UnitFactory.json' const UnitFactory = contract(artifacts)
大変今更なのですが今回Pythonを触ったことでここの処理が何をしているのかようやく把握しました。
- Truffleでmigrateを行うとbuild以下のフォルダにjsonが吐き出される
- 吐き出されたjsonにはアップロードしたコントラクトのアドレス等の必要な情報がjson形式で保存される
- そのjsonをweb3に渡すことでインスタンスが取得できる
というような形になっているようです。
Python版も流れは一緒のようです。
ドキュメントを見ると
# get bytecode >>> bytecode = compiled_sol['contracts']['Greeter.sol']['Greeter']['evm']['bytecode']['object'] # get abi >>> abi = json.loads(compiled_sol['contracts']['Greeter.sol']['Greeter']['metadata'])['output']['abi'] >>> Greeter = w3.eth.contract(abi=abi, bytecode=bytecode)
abiとbytecodeを生成してますがtruffleの吐き出したjsonを覗くとその辺りの情報はありそうなのでjsonをそのまま読み込めば使えそうです。
json読み込み処理
import json f = open("UnitFactory.json", 'r') json_data = json.load(f)
読み込んだjson_dataを投げてインスタンスを生成してみます!
UnitFactory = web3.eth.contract(json_data)
実行してみたらエラーが出ました!
UnitFactory = web3.eth.contract(json_data) File "/usr/local/lib/python3.7/site-packages/web3/eth.py", line 438, in contract return ContractFactory(address) File "/usr/local/lib/python3.7/site-packages/web3/contract.py", line 286, in __init__ self.address = normalize_address(self.web3.ens, address) File "/usr/local/lib/python3.7/site-packages/web3/_utils/normalizers.py", line 212, in normalize_address validate_address(address) File "/usr/local/lib/python3.7/site-packages/web3/_utils/validation.py", line 152, in validate_address raise TypeError('Address {} must be provided as a string'.format(value))
アドレス周りが原因っぽい感じですが…?
もやっとしてますが時間が無くなってしまったので今日はここまで><