2024-07-08
コントラクトの関数で読み込み専用の関数=Solidityにおいてview returnsの関数=は、トランザクション不要で呼んでデータプロパティを取得できる。
web3.jsでパラメータのABIエンコード処理を行い、window.ethereumで関数コールの実行を行う。
自分の作成したERC-721仕様のコントラクトで、呼びたい関数ownerOf,balanceOfを以下abi.jsonで定義しているとする。
JSON | abi.json | GitHub Source |
[ { "inputs": [ { "internalType": "address", "name": "owner", "type": "address" } ], "name": "balanceOf", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "tokenId", "type": "uint256" } ], "name": "ownerOf", "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, ]
まずこれをajaxで取得し展開する。
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script>//<![CDATA[ var abi_json = null; $.ajax({ type: 'GET', url: 'abi.json', data: '', async : true, dataType: 'text', success: function(data) { if(data != null) { abi_json = JSON.parse(data); } } }); //]]></script>
abi_json[0]は関数balanceOfの定義、abi_json[1]は関数ownerOfの定義が入るはずである。
このコントラクトがNFTであるとして、発行済みのトークンID「2」番の持ち主は誰か?を知りたい=ownerOfをコールする。
関数名と引数はencodeFunctionCallを使ってまとめてABIエンコードできる。
https://web3js.readthedocs.io/en/v1.2.11/web3-eth-abi.html
コントラクトのアドレスが0xFccccccFd3a58c65352cdE9286D8BE2b05aaaaaaであるとすると、
<script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.min.js"></script> <script>//<![CDATA[ var web3js = null; if (typeof window.ethereum !== 'undefined' && typeof web3 !== 'undefined') { web3js = new Web3(); var fc_call_param = web3js.eth.abi.encodeFunctionCall(abi_json[1], [2]); var send_params = { to: '0xFccccccFd3a58c65352cdE9286D8BE2b05aaaaaa', data: fc_call_param, }; var owner = await window.ethereum.request({ method: 'eth_call', params: [send_params, "latest"], }); console.log(owner); } //]]></script>
encodeFunctionCallの第一引数にはコントラクトの呼びたい関数が定義されたABI JSONを指定する。ownerOfはabi_json[1]であるので、それを指定する。
第二引数には関数ownerOfに渡す引数を配列で指定する。ここでは引数はトークンID整数1つであるので、取得希望のID「2」を指定しているだけ。
もしも複数の引数を取る関数=たとえば第二引数にアドレスを取る関数=の場合、[2, "0xaaaaacccccxxxxx..."] などと指定する。
関数コールデータfc_call_paramが用意できたので、window.ethereumに渡すパラメタにセットする。最終的にはプロパティ読み出し関数「eth_call」をリクエストする。
実行結果例
0x0000000000000000000000005192891f9f446cd42a770aac22771ef242dad2f0
トークン2番の持ち主がowner変数に文字列として返った。では、これをそのまま関数balanceOfに渡せばこの人が持っているこのNFTの数がそのまま取得できるはずである。
しかしここで注意しなくてはいけないのが、先頭から続く0000000...をつけたまま渡すとInvalid addressエラーになる。
よって、replaceなどでこのゼロを取っ払ってから渡さなくてはいけない。以下のように。
0x5192891f9f446cd42a770aac22771ef242dad2f0
ではこのアドレスの人がこのコントラクトNFTトークンを所有している数を求める=balanceOfをコールする。
<script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.min.js"></script> <script>//<![CDATA[ var web3js = null; if (typeof window.ethereum !== 'undefined' && typeof web3 !== 'undefined') { web3js = new Web3(); var fc_call_param = web3js.eth.abi.encodeFunctionCall(abi_json[0], ['0x5192891f9f446cd42a770aac22771ef242dad2f0']); var send_params = { to: '0xFccccccFd3a58c65352cdE9286D8BE2b05aaaaaa', data: fc_call_param, }; var token_counts = await window.ethereum.request({ method: 'eth_call', params: [send_params, "latest"], }); console.log(token_counts); } //]]></script>
balanceOfはさきのabi_jsonの配列[0]にて定義されているので、abi_json[0]を指定する。balanceOfの引数は取得希望所有者アドレス文字列であるので、それを指定する。
実行結果
0x0000000000000000000000000000000000000000000000000000000000000002
どうやらこの人は、このコントラクトNFTの発行するトークンを2個所有しているようだ、というのがわかる。
※本記事内容の無断転載を禁じます。
ご連絡は以下アドレスまでお願いします★
Intel Macbook2020にBootCampで入れたWindows11 Pro 23H2のBluetoothを復活させる
Windowsのデスクトップ画面をそのまま配信するための下準備
WindowsでGPUの状態を確認するには(ASUS系監視ソフトの自動起動を停止する)
CORESERVER v1プランからさくらインターネットスタンダートプランへ引っ越しメモ
さくらインターネットでPython MecabをCGIから使う
さくらインターネットのPHPでAnalytics-G4 APIを使う
インクルードパスの調べ方
【Git】特定ファイルを除外する.gitignore
【Ubuntu/Debian】NVIDIA関係のドライバを自動アップデートさせない
【Apache】サーバーに同時接続可能なクライアント数を調整する
Windows版Google Driveが使用中と言われアンインストールできない場合
【Windows10】リモートデスクトップ間のコピー&ペーストができなくなった場合の対処法
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
【Linux】iconv/libiconvをソースコードからインストール
Googleスプレッドシートを編集したら自動で更新日時を入れる
【C/C++】小数点以下の切り捨て・切り上げ・四捨五入
【ひかり電話+VoIPアダプタ】LANしか通ってない環境でアナログ電話とFAXを使う
Windows11でMacのキーボードを使うには