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個所有しているようだ、というのがわかる。
※本記事内容の無断転載を禁じます。
ご連絡は以下アドレスまでお願いします★
Wav2Lipのオープンソース版を改造して外部から呼べるAPI化する
Wav2Lipのオープンソース版で静止画の口元のみを動かして喋らせる
【iOS】アプリアイコン・ロゴ画像の作成・設定方法
オープンソースリップシンクエンジンSadTalkerをAPI化してアプリから呼ぶ【2】
オープンソースリップシンクエンジンSadTalkerをAPI化してアプリから呼ぶ【1】
【Xcode】iPhone is not available because it is unpairedの対処法
【Let's Encrypt】Failed authorization procedure 503の対処法
【Debian】古いバージョンでapt updateしたら404 not foundでエラーになる場合
ファイアウォール内部のWindows11 PCにmacOS Sequoiaからリモートデスクトップする
進研ゼミチャレンジタッチをAndroid端末化する
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
VirtualBoxの仮想マシンをWindows起動時に自動起動し終了時に自動サスペンドする
【C/C++】小数点以下の切り捨て・切り上げ・四捨五入
GitLabにHTTPS経由でリポジトリをクローン&読み書きを行う
タスクスケジューラで変更を適用できません。ユーザーアカウントが不明であるか、パスワードが正しくないか、またはユーザーアカウントにタスクを変更する許可がありません。と出た
Intel MacBookAir2020にWindows10→Windows11をインストールする
Linuxでtar.xz形式のファイルを解凍する
Windows11のコマンドプロンプトでテキストをコピーする