如果一个 action
需要的参数越来越多,可能选择定义一个 struct 参数是一个更明智的选择。比如下面这个 action
hello.cpp
#include<eosiolib/eosio.hpp> #include<eosiolib/asset.hpp> using namespace eosio; class [[eosio::contract]] hello: eosio::contract { public: using eosio::contract::contract; [[eosio::action]] void hi( name from_contract, asset from_currency, name to_contract, asset to_currency, uint64_t ratio, bool enabled, name owner ){} }; EOSIO_DISPATCH(hello,(hi))
7 个参数,够吓人的了,我在某个合约的时候最多看到 14 个参数。
本着简单化的原则,我们可以把这些参数都放到一个结构体 struct 中,例如
#include<eosiolib/eosio.hpp> #include<eosiolib/asset.hpp> using namespace eosio; struct setting { name from_contract; asset from_currency; name to_contract; asset to_currency; uint64_t ratio; bool enabled; name owner; }; class [[eosio::contract]] hello: eosio::contract { public: using eosio::contract::contract; [[eosio::action]] void hi(const setting& s){} }; EOSIO_DISPATCH(hello,(hi))
使用下面的命令编译
eosio-cpp -o hello.wasm hello.cpp --abigen
然后使用下面的命令来部署下这个合约
cleos set contract hello ../hello -p hello@active
编译完成后,我们打开 hello.abi
可以看到内容如下
{ "____comment": "This file was generated with eosio-abigen. DO NOT EDIT Sat Nov 10 07:37:54 2018", "version": "eosio::abi/1.0", "structs": [ { "name": "hi", "base": "", "fields": [ { "name": "s", "type": "setting" } ] }, { "name": "setting", "base": "", "fields": [ { "name": "from_contract", "type": "name" }, { "name": "from_currency", "type": "asset" }, { "name": "to_contract", "type": "name" }, { "name": "to_currency", "type": "asset" }, { "name": "ratio", "type": "uint64" }, { "name": "enabled", "type": "bool" }, { "name": "owner", "type": "name" } ] } ], "types": [], "actions": [ { "name": "hi", "type": "hi", "ricardian_contract": "" } ], "tables": [], "ricardian_clauses": [], "abi_extensions": [] }
那么,面对这个结构体,我们要如何传递参数呢 ?
首先,想到的肯定是常规的传递方式
cleos push action hello hi '[{"from_contract":"hello","from_currency":"0.0000 EOS","to_contract":"hi","to_currency":"0.0000 SYS","ratio":"50","enabled":true,"owner":"eosio"}]' -p hello@active
上面这个是没啥问题的对吧,但是,如果有两个参数,其中有一个参数是普通参数,又会发生什么事情呢?
我们把结构体精简下,哈哈,不然看起来太复杂了
#include<eosiolib/eosio.hpp> #include<eosiolib/asset.hpp> using namespace eosio; struct setting { name from_contract; asset from_currency; }; class [[eosio::contract]] hello: eosio::contract { public: using eosio::contract::contract; [[eosio::action]] void hi(const name &from , const setting& s){} }; EOSIO_DISPATCH(hello,(hi))
可以看到 hello.abi
内容如下
{ "____comment": "This file was generated with eosio-abigen. DO NOT EDIT Sat Nov 10 07:50:30 2018", "version": "eosio::abi/1.0", "structs": [ { "name": "hi", "base": "", "fields": [ { "name": "from", "type": "name" }, { "name": "s", "type": "setting" } ] }, { "name": "setting", "base": "", "fields": [ { "name": "from_contract", "type": "name" }, { "name": "from_currency", "type": "asset" } ] } ], "types": [], "actions": [ { "name": "hi", "type": "hi", "ricardian_contract": "" } ], "tables": [], "ricardian_clauses": [], "abi_extensions": [] }
部署完成后,还可以采用传参方式
cleos push action hello hi '["from",{"from_contract":"hello","from_currency":"0.0000 EOS"}]' -p hello@active
P.S 这个在早期的版本是有 bug 的,不过最新的版本已经修正了。 如果你发现不能这样做,那么,将 eosio.cdt 升级到最新的版本吧
目前尚无回复