EOS 学習メモ:トークンお試し編 の続き。
前回 token
contract をデプロイする際は、eosio.cdt が提供してくれている eosio-cpp が生成してくれた ABI を利用したが、高度な contract を書いたりカスタム型を利用したりすると ABI の生成がうまくいかないことがあるらしい。そんなときのために ABI の仕組みについて理解して、必要に応じてデバッグしたり手直ししたりできないとダメだよとのこと。太字で imperative と書いてあるので、人間がやることではないような気もするが必須なんだろう。。。
ということで、eosio.token
の ABI の内容を確認してみる。
{
"____comment": "This file was generated with eosio-abigen. DO NOT EDIT Wed Jan 30 13:26:49 2019",
"version": "eosio::abi/1.1",
"structs": [
{
"name": "account",
"base": "",
"fields": [
{
"name": "balance",
"type": "asset"
}
]
},
{
"name": "close",
"base": "",
"fields": [
{
"name": "owner",
"type": "name"
},
{
"name": "symbol",
"type": "symbol"
}
]
},
{
"name": "create",
"base": "",
"fields": [
{
"name": "issuer",
"type": "name"
},
{
"name": "maximum_supply",
"type": "asset"
}
]
},
{
"name": "currency_stats",
"base": "",
"fields": [
{
"name": "supply",
"type": "asset"
},
{
"name": "max_supply",
"type": "asset"
},
{
"name": "issuer",
"type": "name"
}
]
},
{
"name": "issue",
"base": "",
"fields": [
{
"name": "to",
"type": "name"
},
{
"name": "quantity",
"type": "asset"
},
{
"name": "memo",
"type": "string"
}
]
},
{
"name": "open",
"base": "",
"fields": [
{
"name": "owner",
"type": "name"
},
{
"name": "symbol",
"type": "symbol"
},
{
"name": "ram_payer",
"type": "name"
}
]
},
{
"name": "retire",
"base": "",
"fields": [
{
"name": "quantity",
"type": "asset"
},
{
"name": "memo",
"type": "string"
}
]
},
{
"name": "transfer",
"base": "",
"fields": [
{
"name": "from",
"type": "name"
},
{
"name": "to",
"type": "name"
},
{
"name": "quantity",
"type": "asset"
},
{
"name": "memo",
"type": "string"
}
]
}
],
"types": [],
"actions": [
{
"name": "close",
"type": "close",
"ricardian_contract": ""
},
{
"name": "create",
"type": "create",
"ricardian_contract": ""
},
{
"name": "issue",
"type": "issue",
"ricardian_contract": ""
},
{
"name": "open",
"type": "open",
"ricardian_contract": ""
},
{
"name": "retire",
"type": "retire",
"ricardian_contract": ""
},
{
"name": "transfer",
"type": "transfer",
"ricardian_contract": ""
}
],
"tables": [
{
"name": "accounts",
"type": "account",
"index_type": "i64",
"key_names": [],
"key_types": []
},
{
"name": "stat",
"type": "currency_stats",
"index_type": "i64",
"key_names": [],
"key_types": []
}
],
"ricardian_clauses": [],
"variants": [],
"abi_extensions": []
}
types
にはカスタム型を定義するらしいが、今回は ビルトイン型 しか使っていないので何も定義されていない。
structs
には、contract が利用するデータ構造を定義する。struct には implicit struct と explicit struct があり、前者は contract 内で明示的に定義されていないデータ構造(各アクションの引数)であり、後者は contract 内で明示的に定義されているデータ構造(account
と currency_stats
)である。
actions
には、外部から実行可能な action を定義する。各 action の type
には、structs
で定義した引数 struct の name
を記述し、action との対応関係を明示する。ということで、今回含めほとんどの場合は、各 action の name
と type
が同じ文字列になるはずだが、これらは必ずしも同じである必要はない。
tables
には、データを保持するための table を定義する。今回は account
を保持するための accounts
table と、currency_stats
を保持するための stat
table が定義されている。もちろん、account
と currency_stats
は structs
で定義されているデータ構造を指す。また、table に対して pk の型を指定する必要があり、今回は両 table ともに uint64 となっている。
ABI に記述できることは他にもあるが、ここではスキップする。詳しくは こちら を参照。
また、contract を更新したときは ABI の更新を忘れないように気をつけようねとのこと。例えば、誤った table 定義がなされた ABI で contract に table を加えてしまったりすると、table からデータが取得できなくなったりするらしい。
今回はここまで。