.hpp文件_EOS智能合约入门3——解析abi文件

d41a881d540ee410ad679e51fa1dfcbf.png

通过eosio.cdt提供的eosin-cpp 工具可以生成ABI文件。为什么要理解ABI,因为在开发的时候,自定义类型等可能会导致生成的ABI文件错误,为了能够修复错误,我们需要先理解ABI。

ABI全称是Application Binary Interface,它是一个基于JSON格式的说明文件,用来描述action在JSON和二进制之间的转换。同时,它还用来描述怎么用JSON表示数据库状态,或根据JSON得到数据库状态。与说明文档类似,有了ABI,开发人员可以通过它理解合约。

注:ABI只是一个说明文件,传递给合约的消息或action不一定得完全符合它。
为了更好理解abi,现在,自己来写一个ABI文件。

在任意一个位置,创建一个空白文件,叫eosio.token.abi,写入下列代码。

{
   "version": "eosio::abi/1.0",
   "types": [],
   "structs": [],
   "actions": [],
   "tables": [],
   "ricardian_clauses": [],
   "abi_extensions": [],
   "___comment" : ""
}

接下来会逐个解释每一行。

1. Type

这里的types是对于自定义类型的说明。在编写代码时,有些类型的名字可能比较长,或者我们想要让类型名称更加具体,我们给这样的类型起一个别名。举一个例子,我们在编写Hello World的时候,用到了eosio中的类型name,我们现在想让它更具体一点,我们给它起个别名叫username。修改完的代码如下。

#include <eosio/eosio.hpp>  

using namespace eosio;      
typedef name username; //给name取个别名叫username

class [[eosio::contract]] helloWorld : public contract { 
  public:
      using contract::contract;  
      [[eosio::action]]   
      void hello( username user ) {  //将之前的name修改为username
      	  require_auth( user );
		  print( "Hello World", user );
		}
};

编译该文件(eosio-cpp helloWorld.cpp -o helloWorld.wasm)。打开abi文件,会发现types变变成了如下。

"types": [
        {
            "new_type_name": "username",
            "type": "name"
        }
    ],

很直观,new_type_name是我们新起类型别名,type是类型原本的名称。
需要注意的是,eosio内建的类型不会在abi文件中显示出来。那什么是内建类型呢,就是eosio已经帮我们定义好了的类型,上面用到到name就是一个内建类型。具体的内建类型可以在此查看

2. Struct

显然,这里的struct是对于合约中结构体的说明。举个例子说明。在之前eosio.token合约的hpp文件中,在代码的一百多行的位置,可以看到以下代码。

struct [[eosio::table]] account {
            asset    balance;

            uint64_t primary_key()const { return balance.symbol.code().raw(); }
         };

这就是其中的一个结构体。同时,打开该合同的abi文件,可以看到对应的说明,如下。name是结构体名,base是该结构体的基类(这里没有,所以为空),fields是结构体内变量的名称及其类型。

"structs": [
        {
            "name": "account",
            "base": "",
            "fields": [
                {
                    "name": "balance",
                    "type": "asset"
                }
            ]
        },
        ...]

但是你会发现,eosio.token.hpp里明明只定义了两个结构体,abi文件里structs却写着很多个。这是因为还有一种叫做隐性结构体(implicit struct)的东西,它们对应着合约action及其参数。
同样用eosio.token合约举例。对比abi文件的structs和eosio.token.hpp文件的action方法名跟参数,可以发现,name就是action方法的名称,fields里边则是action方法的参数及参数对应的类型。

3. Action

Action这一块用于描述该合约中可供外部调用的动作。同样,举例eosio.token合约。
hpp文件中action内容如下。

[[eosio::action]]
         void close( const name& owner, const symbol& symbol );
         
[[eosio::action]]
         void create( const name&   issuer,
                      const asset&  maximum_supply);
[[eosio::action]]
         void issue( const name& to, const asset& quantity, const string& memo );
    ...

abi文件对应内容如下。

"actions": [
        {
            "name": "close",
            "type": "close",
            "ricardian_contract": ""
        },
        {
            "name": "create",
            "type": "create",
            "ricardian_contract": ""
        },
        {
            "name": "issue",
            "type": "issue",
            "ricardian_contract": ""
        },
        ...
    ]

name明显就是action的名称了,type则是该方法对应的隐性结构体的名称(上面有讲到),richardian_contract是李嘉图合约(后续会解释)。

4. Table

同样用eosio.token合约举例。hpp文件中对于表account的定义如下。

struct [[eosio::table]] account {
            asset    balance;
            uint64_t primary_key()const { return balance.symbol.code().raw(); }
         };
        
typedef eosio::multi_index< "accounts"_n, account > accounts;

abi的table内容如下。

{
  "name": "accounts",     //表的名称,在实例化时确定;
  "type": "account",      //表对应的结构体;
  "index_type": "i64",    //表的主键的类型;
  "key_names" : ["primary_key"],  //字段名称,长度需与下面的key_types相同;
  "key_types" : ["uint64"] //字段的类型,需与上面的key_names对应,并且长度相同;
}

(1) name:表的名称为accounts。官方开发文档的说法是“***The eosio.token contract instantiates two tables, accounts and stat. ***”(关于multi_index的具体解释ref="http://qq/">请看这里 )。意思是上面hpp部分的最后一行代码实例化了一个叫accounts的表。(2) type:这个accounts的表是基于account结构体的,所以type为account。(3) index_type: 索引类型为i64。(4) key_names:字段为"[primary_key]"。上面hpp部分的第三行决定了一个类型为uint64主键。(5) key_type:字段类型为[“uint64”]。同上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值