【EOS】2.3 深入理解ABI檔案
在前面2.2節部署eos.token
合約時,使用的是提供好的ABI
檔案。
智慧合約是附著在賬號上的,所以智慧合約一定對應著一個賬號。
什麼是ABI檔案?
全稱是Application Binary Interface,翻譯為中文就是應用程式二進位制介面,這個和API有相同的內涵啊,都是介面,介面就意味著可以對外提供服務,但是怎麼用需要按照介面指定。
ABI檔案是基於JSON格式的描述,描述的內容是:如何將使用者的操作在JSON格式和二進位制格式之間進行轉化。
此外,ABI檔案還描述如何在資料庫狀態和JSON格式檔案之間進行轉換。
簡而言之,一旦我們用ABI檔案對智慧合約進行描述之後,開發者和使用者們就能輕而易舉的用JSON檔案與智慧合約互動了。
值得注意的是,ABI檔案只是一個互動說明,而不是強制執行,所以,可以向智慧合約傳遞非嚴格按照ABI檔案說明的資料。
構建ABI檔案
{
"version": "eosio::abi/1.0",
"types": [],
"structs": [],
"actions": [],
"tables": [],
"ricardian_clauses": [],
"abi_extensions": [],
"___comment" : ""
}
Types
自定義資料型別需要在ABI檔案中進行描述,但是對於EOS.IO的內建型別,無需在ABI檔案中說明,之前的hello
eos.token
合約的ABI檔案中,types
都是[]
,因為沒有自定義型別。
這裡,其實是給型別建立別名:
"types": [{
"new_type_name": "account_name",
"type": "name"
}
]
這個示例就是給account_name
建立一個筆名,在ABI檔案裡用name
可以代替account_name
。
Actions
用於宣告智慧合約有哪些可以呼叫的action
。
{
"name": "transfer", // 在智慧合約中定義的操作
"type": "transfer", // 在structs中宣告的資料結構名
"ricardian_contract" : "" // 可選引數,開發中
}
name
欄位表示操作的名字,也是定義的函式名字,type
欄位用於在structs
中查詢資料結構,ricardian_contract
,待定。name
和type
一般相同,但不要求相同,即:一般情況下,函式名和結構體名相同,但並不要求相同。
示例:
"actions": [{
"name": "transfer",
"type": "transfer",
"ricardian_contract": ""
},{
"name": "issue",
"type": "issue",
"ricardian_contract": ""
}, {
"name": "create",
"type": "create",
"ricardian_contract": ""
}
]
這裡是聲明瞭三個操作。
Structs
宣告各個action
需要傳入的引數,系統根據actions
部分中宣告的type
,在structs
部分尋找對應的資料結構,也就是說,函式宣告部分並沒包含具體內容,具體資料需要到structs
中尋找。
總體內容如下:
{
"name": "issue", // 資料結構名
"base": "", // 繼承的父結構名
"fields": [] // 引數陣列,包含引數名和型別
}
其中,fields
欄位中陣列元素型別如下:
{
"name":"",
"type":""
}
注意,這些structs
欄位裡的資料,並非全部是顯式宣告的,有些對應的是操作的引數。
示例:
"structs": [{
"name": "transfer",
"base": "",
"fields": [
{"name":"from", "type":"account_name"},
{"name":"to", "type":"account_name"},
{"name":"quantity", "type":"asset"},
{"name":"memo", "type":"string"}
]
},{
"name": "create",
"base": "",
"fields": [
{"name":"issuer", "type":"account_name"},
{"name":"maximum_supply", "type":"asset"},
{"name":"can_freeze", "type":"uint8"},
{"name":"can_recall", "type":"uint8"},
{"name":"can_whitelist", "type":"uint8"}
]
},{
"name": "issue",
"base": "",
"fields": [
{"name":"to", "type":"account_name"},
{"name":"quantity", "type":"asset"},
{"name":"memo", "type":"string"}
]
}
]
Tables
在tables
部分會列出智慧合約需要建立的資料表的名稱以及資料表中儲存的結構體名稱。
"tables" :[{
"name": "accounts"
"type": "account",
"index_type": "i64",
"key_names": ["currency"],
"key_types": ["uint64"]
}, {
"name": "stat",
"type": "currency_stats",
"index_type": "i64",
"key_names": ["currency"],
"key_types": ["uint64"]
}
]
type
就是資料表中儲存的結構體名稱。
"structs": [{
"name": "account",
"base": "",
"fields": [
{"name":"balance", "type":"asset"},
{"name":"frozen", "type":"uint8"},
{"name":"whitelist", "type":"uint8"}
]
},{
"name": "currency_stats",
"base": "",
"fields": [
{"name":"supply", "type":"asset"},
{"name":"max_supply", "type":"asset"},
{"name":"issuer", "type":"account_name"},
{"name":"can_freeze", "type":"uint8"},
{"name":"can_recall", "type":"uint8"},
{"name":"can_whitelist", "type":"uint8"},
{"name":"is_frozen", "type":"uint8"},
{"name":"enforce_whitelist", "type":"uint8"}
]
}
]
最後將所有內容合在一起就是:
{
"version": "eosio::abi/1.0",
"types": [
{
"new_type_name": "name",
"type": "name"
}
],
"structs": [
{
"name": "create",
"base": "",
"fields": [
{
"name":"issuer",
"type":"name"
},
{
"name":"maximum_supply",
"type":"asset"
}
]
},
{
"name": "issue",
"base": "",
"fields": [
{
"name":"to",
"type":"name"
},
{
"name":"quantity",
"type":"asset"
},
{
"name":"memo",
"type":"string"
}
]
},
{
"name": "retire",
"base": "",
"fields": [
{
"name":"quantity",
"type":"asset"
},
{
"name":"memo",
"type":"string"
}
]
},
{
"name": "close",
"base": "",
"fields": [
{
"name":"owner",
"type":"name"
},
{
"name":"symbol",
"type":"symbol"
}
]
},
{
"name": "transfer",
"base": "",
"fields": [
{
"name":"from",
"type":"name"
},
{
"name":"to",
"type":"name"
},
{
"name":"quantity",
"type":"asset"
},
{
"name":"memo",
"type":"string"
}
]
},
{
"name": "account",
"base": "",
"fields": [
{
"name":"balance",
"type":"asset"
}
]
},
{
"name": "currency_stats",
"base": "",
"fields": [
{
"name":"supply",
"type":"asset"
},
{
"name":"max_supply",
"type":"asset"
},
{
"name":"issuer",
"type":"name"
}
]
}
],
"actions": [
{
"name": "transfer",
"type": "transfer",
"ricardian_contract": ""
},
{
"name": "issue",
"type": "issue",
"ricardian_contract": ""
},
{
"name": "retire",
"type": "retire",
"ricardian_contract": ""
},
{
"name": "create",
"type": "create",
"ricardian_contract": ""
},
{
"name": "close",
"type": "close",
"ricardian_contract": ""
}
],
"tables": [
{
"name": "accounts",
"type": "account",
"index_type": "i64",
"key_names" : ["currency"],
"key_types" : ["uint64"]
},
{
"name": "stat",
"type": "currency_stats",
"index_type": "i64",
"key_names" : ["currency"],
"key_types" : ["uint64"]
}
],
"ricardian_clauses": [],
"abi_extensions": []
}
END.
參考:
[0] https://www.cnblogs.com/yuanfangyuan/p/9072668.html
[1] https://developers.eos.io/eosio-home/docs/the-abi