事务是修改总账状态的命令。例如,事务中可包含发送付款、在分布式交易所中生成订单、更改账户设置、授权另一个账户持有您发行的货币等改变总账的操作。如果您将总账视为一个数据库,那么事务就是 SQL 命令。
事务具有以下属性:
源账号(Source account)
发起事务的账号被称之为源账号。该事务必须被源账号签署,手续费也由它支付。事务的序列号和源账号的序列号相对应。
费用(Fee)
每笔事务都设置了一个由源账号支付的费用,如果支付的费用少于网络要求的最低费用的话,这笔事务将会失败。事务中包含的操作越多,需要的手续费越多。
序列号(Sequence number)
每个事务都有一个序列号。系统遵循严格的排序规则来处理每个账户的事务。要使事务有效,在应用事务时,它的序列号必须比存储在源帐户字段中的序列号大 1。应用事务时,源账户的序列号将会加 1。如果源账户上序列号为 4,则传入事务的序列号应为 5,应用事务后,源账户上的序列号将变为 5。
请注意,如果具有相同源账户的几个事务被放入同一个事务集中,则系统会根据序列号对它们进行排序和应用。例如,如果某账户提交了 3 个事务,且该账户的序列号为 5,则事务的序列号必须为 6、7 和 8。
操作集
事务中包含了一个操作集,一般来说,其中只有一个操作,但是它最多可以包含 100 个操作。操作会按顺序执行,它们具有原子性,也就是说一个事务中的所有操作要么都执行成功,要么都执行失败。如果一个操作的源账户是其它账户而不是事务的源账户,那么事务需要额外的签名。
签名集
一个事务最多可包含 20 个签名。如果事务包含授权事务不需要的签名,则该事务会视为无效——即不允许添加多余的签名。阅读多重签名了解更多。
需要签名来授权执行操作和更改源账户(收取费用和改变账户序列号)。
备注(Memo)
可选 备注中包含了其它可选的信息,客户端负责处理这个备注。备注可以是以下几种类型:
MEMO_TEXT
: 使用 ASCII 或 UTF-8 编码的字符串,最长为 28 字节MEMO_ID
: 64 位无符号整数MEMO_HASH
: 32 字节的 hashMEMO_RETURN
: 32 字节的 hash,用于记录退款事务的 hash时间界限(Time bounds)
可选 事务被允许进入总账的时间,这个时间用 UNIX 时间戳(秒) 表示,包含一个上限(最晚时间)和一个下限(最早时间)。一个事务提交的时间早于或晚于时间界限,都会因无法加入事务集而执行失败。
maxTime
为0
表示时间界限的上限不被限制。
在总账关闭前,所有的节点都会收集事务。当下一个总账要关闭时,节点将这些事务收集到一个事务集中。网络运行通过 SCP 让各个节点就应该应用哪个事务集达成共识。
创建:用户创建一个事务。尝试使用 js-stellar-sdk 创建一个事务。
签名:事务创建完成后,必须收集所有需要的签名并将其添加到事务信封中。一般情况下,只需要源账户的签名就可以完成授权,但是如果这个事务包含了更复杂的操作的话可能需要更多账户的签名。请参阅多重签名。
提交:签署后,交易应该是有效的,现在可以提交到 Stellar 网络了。事务通常通过 horizon 提交,但您也可以直接将事务提交给 stellar-core 实例。
广播: 当 stellar-core 接收到用户或其他 stellar-core 提供的事务后,它将进行初步检查,以判断该事务是否有效。在后续的检查中(此类检查不包含在这一步中),系统会确保交易格式的正确性、源账户拥有足够的资金来支付交易费用。但在这个阶段 Stellar-core 只会检查源账户的状态,而不会检查诸如交易的接收账户是否存在、账户有足够的资产可以出售、这是否是一个有效的支付路径等其它东西。只要初步检查通过,那么 stellar-core 就会把事务广播给它连接的所有其他服务器。通过这种方式,一个有效的事务会被扩散到整个 Stellar 网络中。
将事务打包到事务集中:当总账关闭时,stellar-core 会将自从上一次总账关闭到现在收集到的所有事务打包到一个事务集中。如果此时还有其它事务被提交,这些事务会在下个总账关闭时被处理。SCP 解决各个节点提议的事务集之间的差异,并决定哪个事务集会被最终应用到网络中。
应用:当 SCP 决定采用哪个事务集之后,这个事务集便会被应用到总账中。此时,系统会向该集合中的每个事务的源账户收取费用。操作按照它们在事务中发生的顺序执行,如果有任何操作失败,则整个事务都将失败,也就是说这个事务中所有的操作都不会生效。应用该集合中的所有事务之后,系统将会创建一个新的总账,并重新启动这个流程。
事务可能会执行失败,以下是错误代码对照表。操作执行失败的原因请查阅操作列表的文档。
错误 | 代码 | 描述 |
---|---|---|
FAILED | -1 | 事务中的某个操作执行失败 (请查阅操作列表) |
TOO_EARLY | -2 | 总账的 closeTime 早于事务中的 minTime |
TOO_LATE | -3 | 总账的 closeTime 晚于事务中的 maxTime |
MISSING_OPERATION | -4 | 事务中没有包含操作 |
BAD_SEQ | -5 | 事务序列号错误 |
BAD_AUTH | -6 | 没有足够多的有效签名/错误的网络 |
INSUFFICIENT_BALANCE | -7 | 执行该事务将导致账户的基本储备金不足 |
NO_ACCOUNT | -8 | 源账户不存在 |
INSUFFICIENT_FEE | -9 | 手续费不足 |
BAD_AUTH_EXTRA | -10 | 包含了没有使用到的签名 |
INTERNAL_ERROR | -11 | 未知错误 |