Pythonを利用して、スマートコントラクトを操作する方法を解説していきます。
今回は、コントラクトの情報を取得する方法になります。
Web3.pyのインストール
まずは、今回利用するライブラリ『Web3.py』をインストールしましょう!
pip install web3
公式ドキュメントは、こちらからどうぞ
https://web3py.readthedocs.io/en/stable/
さっそく『Web3.py』を使って、NFTのコントラクトの情報を取得していきましょう!
事前準備(contract address/abiの取得)
読み取りたいコントラクトの『contract address』と『abi』を取得していきます。
今回、例として使用するNFTは、こちらになります。
まずは、下記URLを開いてください
https://opensea.io/assets/matic/0xb405f48f67a06916a366c77bcf42992903ef0619/595
開いてもらうとこちらの画面になるかと思います。
少しスクロールして、『Details』をクリックし、『Contract Address』をクリックしてください。
すると、『polygonscan』が開きます。ここで『Contract Address』を取得します。
次に『Contract』を押してください。
すると、この画面になるかと思います。このNFTは、ChocoMintさんのchocomintV2で発行しています。
一番下の方までスクロールしてください。
すると、『Contract ABI』が表示されるので、コピーしましょう!
『abi.json』というファイル名で、保存します。
Web3.pyを使って、Read Contractしてみよう!
今回使用するプログラムの全体は、こちらになります。
#解説1
from web3 import Web3
#1 ネットワーク接続の設定
network_url = "https://polygon-rpc.com/"
web3 = Web3(Web3.HTTPProvider(network_url))
#2 接続確認(True or False)
print(web3.isConnected())
#3 チェーンIDの確認
print(web3.eth.chain_id)
#解説2
contract_address = "0xb405f48F67a06916A366c77bCF42992903ef0619"
#1 abiの読み込み
import json
json_open = open("abi.json", "r")
abi = json.load(json_open)
#解説3
#1 スマートコントラクトに接続
contract = web3.eth.contract(address = contract_address, abi = abi)
#2 Read Contractにあるnameの実行
print(contract.functions.name().call())
#3 Read Contractにあるsymbolの実行
print(contract.functions.symbol().call())
#解説4
#1 ownerのaddressを入力する
wallet_address = "0x82fEDBC04ddB1BDf63754DFBf97a804C644b5525"
#2 balanceOfを実行する
print(contract.functions.balanceOf(wallet_address).call())
まずは、ブロックチェーンに接続してみましょう!
今回の例では、ポリゴンネットワークに接続します。
from web3 import Web3
#1 ネットワーク接続の設定
network_url = "https://polygon-rpc.com/"
web3 = Web3(Web3.HTTPProvider(network_url))
#2 接続確認(True or False)
print(web3.isConnected())
#3 チェーンIDの確認
print(web3.eth.chain_id)
- 『network_url』に接続したいチェーンのRPC URLを代入します。
- きちんと接続されれば、『True』が返ってきます。
- チェーンIDの確認。ポリゴンネットワークのIDである『137』が返ってきます。
次に、先ほど取得したコントラクト情報を読み込んでいきます。
contract_address = "0xb405f48F67a06916A366c77bCF42992903ef0619"
#1 abiの読み込み
import json
json_open = open("abi.json", "r")
abi = json.load(json_open)
- 先ほど取得したabiの情報を読み込んでいます。
まずは、簡単なRead Contractからやってみましょう!
#1 スマートコントラクトに接続
contract = web3.eth.contract(address = contract_address, abi = abi)
#2 Read Contractにあるnameの実行
print(contract.functions.name().call())
#3 Read Contractにあるsymbolの実行
print(contract.functions.symbol().call())
- スマートコントラクトに接続します。
- Read contractにある『name』を実行します。
今回の場合、『FashionableEggDragons』が返ってきます。 - Read contractにある『symbol』を実行しています。
今回の場合、『FED』が返ってきます。
Read contractでも確認してみましょう!『Polygonscan』に戻ります。
https://polygonscan.com/address/0xb405f48f67a06916a366c77bcf42992903ef0619#readContract
『Contract』を押し、『Read Contract』を押してください。その後、『6.name』までスクロールしてください。
先ほど取得した結果と同じ『FashionableEggDragons』になっていることが確認できたかと思います。
『13.symbol』までスクロールしてみてください。先ほど取得した値と一致していますよね?
何をしているかというと、コントラクトのfunction nameを実行しています。
コントラクトのコードを読み解いていくと、『ERC721Upgradeable.sol』の中に『function name』があります。
このfunctionが実行されたため、結果として『name』が返されました。
コントラクト情報を読み込む(Read Contract)だけであれば、怖いことは何もないので、このあたりの理解は不要です。
一方で、Write Contractを実行したりする場合は、このあたりの理解が深いと安心して操作することが出来ます。
次に、変数を代入して、コントラクト情報を取得してみましょう!
Read Contractの1番上にある『balanceOf』を実行してみましょう。
#1 ownerのaddressを入力する
wallet_address = "0x82fEDBC04ddB1BDf63754DFBf97a804C644b5525"
#2 balanceOfを実行する
print(contract.functions.balanceOf(wallet_address).call())
- ownerのwallet addressを代入します。ここでは、私のwallet addressを入力しています。
- ownerの変数を代入して、『balanceOf』を実行します。
すると、私が保有しているNFTの数量が返ってきます。
『Polygonscan』で確認してみましょう!
①にownerアドレスを入力し、Queryを押します。すると、先ほど返ってきた保有量が返ってくるかと思います。
※私は、頻繁にNFTを配っているため、画面に表示されている『808』から少なくなっているかもしれません。
小ネタ1:checksum addressへの変換
wallet addressが全部小文字だと、エラーが出力されます。
どこからかwalletアドレスを取得してきて、再利用する際にひっかかりました。
次のプログラムを実行してみてください。
import json
from web3 import Web3
network_url = "https://polygon-rpc.com/"
web3 = Web3(Web3.HTTPProvider(network_url))
contract_address = "0xb405f48F67a06916A366c77bCF42992903ef0619"
json_open = open("abi.json", "r")
abi = json.load(json_open)
contract = web3.eth.contract(address = contract_address, abi = abi)
#1 wallet addressがすべて小文字の場合
wallet_address = "0x82fedbc04ddb1bdf63754dfbf97a804c644b5525"
print(contract.functions.balanceOf(wallet_address).call())
これを実行すると、『non-checksum address』は使えないとエラーが出力されます。
この場合、①checksum addressを使用する②ENSを使用する必要があります。
無理やりchecksum addressへ変換する方法
ここでは、無理やりchecksum addressへ変換してみます。
from web3 import Web3
network_url = "https://polygon-rpc.com/"
web3 = Web3(Web3.HTTPProvider(network_url))
contract_address = "0xb405f48F67a06916A366c77bCF42992903ef0619"
json_open = open("abi.json", "r")
abi = json.load(json_open)
contract = web3.eth.contract(address = contract_address, abi = abi)
#1 wallet addressがすべて小文字の場合
wallet_address = "0x82fedbc04ddb1bdf63754dfbf97a804c644b5525"
#2 checksum addressへ変換
wallet_address = Web3.toChecksumAddress(wallet_address)
print(wallet_address)
print(contract.functions.balanceOf(wallet_address).call())
自動的に、アドレスの中に大文字が割り当てられました。
※推奨された方法ではないので、使う際には注意が必要です!
小ネタ2:ENSアドレスを使ってコントラクト情報を取得
ENSアドレスを使用することも可能です。
※ENSアドレスは、メインネットでしか使えません。
INFULAのAPIキー
メインネット(イーサリアム)の場合、INFULAというAPIサービスを利用してコントラクト情報を引き出します。
下記URLよりAPIキーを取得してください。
コントラクトとabiの取得
先ほどまで使用していたコントラクトは、ポリゴンネットワークのコントラクトになるので、こちらのコントラクトを使用してください。
https://etherscan.io/address/0xa6a67c3f16bc46720cde857ef7d03d1c1c625664#code
abi情報を取得したら、『abi2.json』というファイル名で、保存します。
では、INFULAのAPIキーを反映させて、下のプログラムを実行してみてください!
import json
from web3 import Web3
network_url = "ここにAPIキーを入力してください(https://mainnet.infura.io/v3/****)"
web3 = Web3(Web3.HTTPProvider(network_url))
contract_address = "0xA6A67c3F16bC46720cDe857eF7d03D1c1C625664"
json_open = open("abi2.json", "r")
abi = json.load(json_open)
contract = web3.eth.contract(address = contract_address, abi = abi)
#1 ENSアドレスを使ってコントラクト情報を取得
wallet_address = "eggdragon.eth"
print(contract.functions.balanceOf(wallet_address).call())
保有数『1』が返ってくると思います。
まとめ
今回は、web3.pyを使ったRead contractについてちょっとだけ解説してみました。
これを応用することで、様々な情報を簡単に取得することが出来ます。
次回は、web3.pyを使ったGiveaway botを中心に、Write contractについて解説していきたいと思います。