合约通信编程
一、通信模型和执行流程
EOSIO智能合约可以相互通信,例如让另一个合约执行某些与当前action相关的操作,或触发当前action范围之外的未来交易。
EOSIO支持Inline和Deferred两种基本通信模式。Inline通信可以理解为在当前action中执行操作,可视为同步通信,Deferred通信可以理解为触发未来事务操作,可视为异步通信。
1. Inline通信
Inline通信的形式是请求作为调用操作的一部分而执行。Inline通信使用原始交易相同的scope和权限作为执行上下文,并保证与当前action一起执行。可以被认为是transaction中的嵌套transaction。如果transaction的任何部分失败,Inline动作将和其他transaction一起回滚。无论成功或失败,Inline都不会在transaction范围外生成任何通知。
2. Deferred通信
Deferred通信在概念上等同于发送一个transaction给一个账户。这个transaction的执行是eos产快节点自主判断进行的,Deferrd通信无法保证消息一定成功或者失败。
如前所述,Deferred通信将在稍后由产快节点自行决定,从原始transaction(即创建deferred通信的transaction)的角度来看,它只能确定创建请求是成功提交还是失败(如果失败,transaction将立即失败),Deferred通信承担发送transaction的权力,也可以取消Deferred的transaction。
3. Inline通信流程
下图说明了多级嵌套的多action事务,雇主运行工资单,将支付转入员工账户,员工账户由银行管理,银行向其客户(员工)提供通知,以便客户可以利用银行提供的服务,例如支票和储蓄账户之间的自动转账。
在本例中,原始transaction对employer合约执行两项操作:employer::runpayroll和employer::dootherstuff。这两项action中更有趣的是runpayroll。以下是它的功能,缩进与嵌套的Inline操作一致。
runpayroll进行从雇主账户到银行账户的eosio::token::transfer这个Inline通信,此示例选择在银行所需的信息的“memo”字段中加入了以确保合适的员工获得付款的信息。
eosio::token::transfer action执行转账操作,
然后通知雇主,
然后通知银行。
银行有一份合约,收到eosio::token::transfer通知。收到后,原始transaction中的“memo”中的参数
将用于某些特定的业务,以将资金转入员工的帐户。
银行的行为通知员工账户存款。
员工有一个监听eosio::token::transfer通知的合约。收到后,参数用于确定转移
是否为自己,Employee的合约发送Inline操作bank::doacctpolicy。
bank::doacctpolicy 根据客户配置的政策为客户执行一些操作,例如,
在员工的银行支票和储蓄账户之间转移资金。
dootherstuff 做了一些其他的行动,说明一个交易可以有多个行动。
下图描绘了上例中transction跟踪:
4. Deferred通信流程
上述情况也可以使用Deferred通信完成,下图显示了Deferred通信场景。
Deferred通信和Inline通信有一些差异:
1. 员工提交Deferred操作而不是Inline操作。
2. Deferred通信将导致transaction进行排队等待可能的进一步处理,而不是直接处理给出处理结果。这是Deferred交易一个非常重要的特征!
3. 当被调用时,动作执行的上下文与发出Deferred请求的原始transaction上下文无关。
二、Inline/Deferred通信编程