コラム

NFT Giveaway Botの作り方(前編:Read contract)【python×web3】

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キーを取得してください。

https://infura.io/

コントラクトと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について解説していきたいと思います。

-コラム