# VEP-7: 合并合约的响应交易和响应交易产生的请求交易

# 背景

白皮书 2.3 章节的 Definition 2.6 定义了 Vite 的账本结构,并明确定义了:

交易分为请求交易和响应交易两种,每个交易对应一个单独的区块,每个账户对应一条链,一个交易对中,响应交易引用其对应的请求交易的哈希。

一个合约调用交易,可能会通过消息调用,使多个合约的账户状态发生变化,这时,这个合约的响应交易就会生成一些新的请求交易并在响应交易之后写入账本。

例如:用户账户 A 发起一笔请求交易 A1,调用合约账户 B 的方法,合约账户 B 生成一笔响应交易 B1 执行合约方法,并生成两笔请求交易 B2 和 B3,B2 给用户账户 C 转账,B3 调用合约账户 D 的方法。这个账本结构中,共涉及到 3 个请求区块:A1、B2、B3,和 3 个响应区块:B1、C1、D1。

figure

图 1

# 拆分合约的响应交易和响应交易产生的请求交易的优缺点

以图 1 为例,响应交易 B1 和由 B1 产生的两个请求交易 B2 和 B3 在业务逻辑上是一个事务,在实现过程中被拆分成了 3 个块。这样做的优缺点如下:

优点:

  • 请求交易和响应交易一一对应,账本结构比较清晰,查询在途交易和查询请求交易状态(已被响应 / 未被响应)时比较方便。

缺点:

  • 拆分成多个块之后,很难当成一个事务处理。从校验逻辑上看,在校验响应交易的正确性时,应该同时校验由响应交易生成的请求交易是否正确;请求交易的正确性依赖响应交易的上下文,无法单独校验。在网络传输时,响应交易和请求交易分开传输,如果生成响应交易和请求交易的机器在广播完响应交易后宕机,那么这条合约链将会不完整。

  • 响应交易和请求交易的信息重复存储,增加了链上的数据量,例如:块的生产者信息、依赖信息(块高度、上一个块的哈希等)等。

当前在测试网络中,去掉了合约产生的请求交易上的签名,每个节点在校验响应交易时直接生成请求交易(由虚拟机保证在每个节点上生成相同的请求交易),并丢弃掉从网络上收到的请求交易。这样勉强保证了响应交易和请求交易的事务性。

# 合并合约的响应交易和响应交易产生的请求交易的优缺点

将图 1 中的 B1、B2、B3 合并成一个区块 B1,B1 包含一笔响应交易和这笔响应交易产生的请求交易 B11 和 B12。这种账本结构中,共涉及 1 个请求区块 A1 和 3 个响应区块 B1、C1、D1。

figure

图 2

  • 由于响应交易和它的请求交易被写入到了同一个块中,因此在校验和网络传输时都可以直接当做事务来处理。

  • 减少了区块存储,合约的响应交易以及响应交易产生的请求交易中相同的字段不再存储,例如生产者信息、请求交易的依赖信息等。

  • 为了方便在途交易和请求交易状态的查询,请求交易中保留了独立的交易哈希,因此请求交易和响应交易仍旧是一一对应的关系。

# 结论

以上,建议将合约的响应交易和响应交易产生的请求交易合并成一个块,并保留请求交易中的交易哈希。

合并后一个合约的响应区块可能同时包含一个响应交易和多个请求交易,虽然破坏了请求区块和响应区块一一对应的关系,但是保留了请求交易和响应交易的一一对应关系,并且能带来以下收益:

  • 更符合合约响应交易和响应交易产生的请求交易的事务特性,校验更方便,网络传输更稳定;

  • 节省了账本的存储空间。