在前面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