https://developers.eos.io/welcome/latest/protocol/transactions_protocol
经过这几天对共识协议的完整翻译和梳理,一个最大的感受就是收获大,但确实费时费力。不过,总体来说还是值得的。
原文是transaction,更倾向翻译成交易,可能有地方叫事务。
action之前一直翻译成行为,最近翻阅一些资料后,应该翻译成操作更合适。
1 概述
操作(action)是指在一个智能合约中的原子行为。在之前的实战例子中也可以感受到,智能合约就是由多个action构成,用户可以通过cleos push action命令执行某合约中的某个action。从更高层次看,去中心化应用中,交易定义一组被原子性执行的actions。与数据库中事务的概念类似,交易中的一组actions必须按照预先定义好的顺序,一个接一个的执行,要么都成功,要么都失败。在交易失败的情况下,为了维护交易的原子性和完整性,需要将区块链的状态恢复到执行交易前的状态。这保证了在故障点之前执行的任何action都不会产生任何副作用。
1.1 操作(action)
操作能被一个或多个之前在区块链上创建的actor授权。个人理解,这里的actor应该比account更细粒度,一个account可能有多个actor。即具有特定权限的actor可以指定谁执行某操作。在一个智能合约中,操作即可以被显式创建,也可以被隐式创建(内联操作)。
对于任何给定的actor:action对,最多有一个显式关联的最小权限(不理解)。如果没有显式最小权限,则隐式默认为actor@active。
每个actor都可以独立地为给定的操作设置自己的最低权限。此外,EOSIO软件中有一个复杂但灵活的授权结构,允许actor代表其他帐户执行操作(push action)。因此,需要检查是否为某个actor授权执行某操作。
在一个交易中,有两种类型的操作,他们的主要区别就是被执行的方式不同:
显式操作:在已签名的交易中显式出现
隐式操作(内联操作):作为处理交易的一个副作用(side effect),例如通知?
和显式操作一样,隐式操作也被定义在智能合约中。关键的区别在于,内联操作不不会在网络传播并最终包含在块中的实际交易中,他们是隐式的。
1.1.1 显式操作
显式操作包含在组成交易的实际操作列表中。在被放到交易里面之前,显式操作被实现为具体的操作实例。显式操作还包含实际的负载数据(如果有的话),这些数据和操作相关联,且作为交易的一部分。
1.1.2 隐式操作
隐式(内联)操作是在一个交易中被显式操作(即调用者)调用而产生的,该交易需要隐式操作来执行一个操作,以便显式操作(即调用者)继续进行。正因这样,内联操作和调用者是工作在相同的作用域和权限下的。因此,内联操作可以确保和调用者在同一个交易中执行。
1.2 智能合约
在EOSIO系统中,智能合约是由一系列根据功能划分的操作和这些操作所依赖的类型定义组成。即合约由操作和类型组成。因此,操作定义了合约的实际行为。一些行为是由标准的eosio合约实现,例如账号创建,为BP投票,通证转账等。应用开发者能通过在自定义的合约中创建自定义的操作来扩展、代替或者修改这些功能。另一方面,交易就是典型的在应用程序级创建的,智能合约和交易类似。
1.2.1 实现
智能合约是用c++语言实现的,需要从eosio::contract类继承。操作就是合约类中的方法。交易是在eosio应用程序中动态生成的,通过交易实例实现。eosio处理每一个交易实例,跟踪它的状态:创建、签名、验证、执行。
2 交易实例
实例由交易头、操作实例列表和交易扩展。根据交易过期时间(交易被执行的时候会计算出来),交易头评估它需要包含的必要信息。(过期时间不一样,交易头中信息还不一样?)其他字段包括包含该交易的块号(没有找到!!!),块id前缀(用于防止跨链,跨分支攻击,没有找到!!!)、CPU和网络使用的上限、以及延迟事务的秒数(如果适用)。交易实例如下示意图。
操作实例由常规操作或上下文无关的操作组成。签名是在交易级别被创建和验证的。也就是说单一行为不会做签名的。帐户和权限会基于单个操作处理。
每个操作实例都包含一些信息,用于根据操作中指定的actor的权限级别(即actor@permission)和合约中为该操作指定的实际授权来验证它是否可以执行。
2.1 交易ID
每个交易实例对应着一个交易实体,不同交易通过交易ID区分。交易ID是通过包含在交易实例中的基本信息经过加密哈希处理后生成的。因此,交易ID是由交易头,操作列表和交易扩展字段唯一决定的(这不是废话嘛)。交易实例后续可以被具化成签名交易实例或打包交易实例。
2.2 签名交易实例
签名的交易扩展了交易字段的基本内容,包括对交易进行签名的账号生成的签名信息。还包括与交易实例中包含的上下文无关操作(如果有的话)相关的任何数据。只有被账号签名过的交易,才能准备被执行和验证。
签名交易字段如下:https://developers.eos.io/welcome/latest/protocol/transactions_protocol/#signed_transaction-schema
2.3 打包交易实例
被打包的交易里面,是否压缩是可选项。打包交易会将空间最小化,形成EOSIO中最常见的交易类型。因此,当交易被推入一个块时,不管是否压缩,它们都是打包交易。
打包交易字段如下:https://developers.eos.io/welcome/latest/protocol/transactions_protocol/#packed_transaction-schema
扩展
1、eosio是如何确认交易的原子性的?
参考:https://www.zhihu.com/question/30272728
没有找到eos如何做到的,找到普通数据库如何做到的。
为了实现原子性,需要通过日志:将所有对数据的更新操作都写入日志,如果一个事务中的一部分操作已经成功,但以后的操作,由于断电/系统崩溃/其它的软硬件错误而无法继续,则通过回溯日志,将已经执行成功的操作撤销,从而达到“全部操作失败”的目的。最常见的场景是,数据库系统崩溃后重启,此时数据库处于不一致的状态,必须先执行一个crash recovery的过程:读取日志进行REDO(重演将所有已经执行成功但尚未写入到磁盘的操作,保证持久性),再对所有到崩溃时尚未成功提交的事务进行UNDO(撤销所有执行了一部分但尚未提交的操作,保证原子性)。crash recovery结束后,数据库恢复到一致性状态,可以继续被使用。
2、交易参数关系