EOS智能合约开发系列(14): 关于require_auth函
前面两篇文章我们分析了eosio.msig
合约。中间有些内容因为篇幅没有仔细讲解,今天开始打算把一些知识点攻克一下。有些比较难的知识点,自然会详细介绍;有些呢,则看起来比较简单,然而深入进去之后,却可以加深对EOS系统的理解。今天先介绍第一个知识点:require_auth
函数。
action的结构
要说清楚这个方法的含义和用法,咱们需要从action
的结构说起。详见eoslib.hpp
中的action类,这里把它的结构简化表示成下面这样:
* struct action {
* account_name account; // the contract defining the primary code to execute for code/type
* action_name name; // the action to be taken
* permission_level[] authorization; // the accounts and permission levels provided
* bytes data; // opaque data processed by code
* };
一个action的数据包含:
account
: action的处理器(handler
)所在的合约账号
name
: action的名字
authorization
: 调用者提供的action的权限列表(可以是一组keys,也可以是一组别人的许可权限,回忆一下前几篇关于自定义许可权限的内容,把知识点打通)
data
: action的数据参数,如果是transfer
action,这里的数据就是类似这样的内容:
{
"from": "inita",
"to": "initb",
"amount": "100.0000 EOS",
"memo": "1234"
}
你可能说,“不对,data明明是个byte数组,怎么能存储一个结构呢?”,这其实是数据序列化的结果,关于序列化和反序列化,如果你还不是很了解,可以从网上搜索一下相关知识。
require_auth
现在我们再说require_auth
就比较容易了,先看签名:
/**
* Verifies that @ref name exists in the set of provided auths on a action. Throws if not found.
*
* @brief Verify specified account exists in the set of provided auths
* @param name - name of the account to be verified
*/
void require_auth( account_name name );
英文好的看下注释,再结合action的结构就完全明白了:它校验通过name
形参传进来的账户,看是否在本action已提供的权限列表
中。如果在,则校验通过,否则,抛出异常。
比如如果执行下面的命令发起一个action:
cleos push action hello.code hi '["user"]' -p user@active
这里发起的这个hi
action的结构就是类似这样的:
{
"account": "hello.code",
"name": "hi",
"authorization": [ {"account": "user", "permission":"active"} ],
"data": ["user"]
}
所以如果在hi
action的处理器里面调用require_auth(N(user))
是可以通过检查的,因为user
在authorization
数组中;而require_auth(N(hello.code))
就会检测失败,并抛出异常。
有时候,你可能就想看看某个账户是否在action的已提供权限列表
里,并不想抛出异常,那该怎么办?
这个时候可以用has_auth方法:
/**
* Verifies that @ref name has auth.
*
* @brief Verifies that @ref name has auth.
* @param name - name of the account to be verified
*/
bool has_auth( account_name name );
require_auth2
还有一个类似的require_auth2
方法,它的签名是这样的:
/**
* Verifies that @ref name exists in the set of provided auths on a action. Throws if not found.
*
* @brief Verify specified account exists in the set of provided auths
* @param name - name of the account to be verified
* @param permission - permission level to be verified
*/
void require_auth2( account_name name, permission_name permission );
这个检查更为严格一点,除了指定账户,还要指定许可。这个许可是严格检查的,也就是说,假如你在代码里写的是:
require_auth(N(user), N(active));
那么下面的命令是通不过这个检查的:
cleos push action hello.code hi '["user"]' -p user@owner
尽管这里使用的是更高的权限user@owner
,也无法通过检查。
好了,今天就这样。
简介:不羁,一名程序员;专研EOS技术,玩转EOS智能合约开发。
微信公众号:know_it_well
知识星球地址:https://t.zsxq.com/QvbuzFM