區塊鏈EOS|智能合約入門3——解析abi文件

系列文章:

1. Hello World!
2. 部署token合約併發行、交易幣
3. 解析abi文件(本文)


正文

  通過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的具體解釋請看這裏 )。意思是上面hpp部分的最後一行代碼實例化了一個叫accounts的表。
(2) type:這個accounts的表是基於account結構體的,所以type爲account。
(3) index_type: 索引類型爲i64。
(4) key_names:字段爲"[primary_key]"。上面hpp部分的第三行決定了一個類型爲uint64主鍵。
(5) key_type:字段類型爲[“uint64”]。同上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章