综述
不需要改变任何现存的共识规则,来增大比特币的交易吞吐量。
动机
比特币网络的吞吐量与它重新定向和拒绝服务限制的共识规则相关。
比特币的重新定向规则确保出块时间大致在10分钟,该规则不可改变。关于其它大大提高交易吞吐量的方法一直存在争议,因为这些方法没有证明它们自己是特别安全的共识层解决方案。
历史
辅助块,第一次被Johnson Lau
在2013年提议。概述了使用特殊操作码使资金进入和退出附加块的方法。
拓展块是最近的提案,也是Johnson Lau
在2017年提出的,
它修订了大量原始提案的想法。
规则
拓展块在原始比特币的区块上设计了一个二层结构,在该拓展块中,矿工将保证额外交易区块的merkle根。
拓展块在opt-in
,序列化,验证和网络服务方面利用了BIP141, BIP143和BIP144的一些功能。拓展块的规则可以认为是这些BIP的拓展和修订。拓展块在当前交易格式下不兼容BIP141,它需要一些小的附加规则。
拓展块维护自己的UTXO集合,以免影响未升级节点中已存在的UTXO集合。这是一个棘手的问题,它要求在当前每个标准区块的结尾都有一个决议交易。
本规则规定了一种欺骗未升级节点的方法,使它们相信已存在的UTXO集合仍然以以前的规则在运行。不幸的是,这需要在升级后的节点上额外的记录一些内容。
承诺结构
愿意包含拓展块的升级节点的矿工将包含一个额外的输出值为0的coinbase数据,输出脚本如下:OP_RETURN 0x24 0xaa21a9ef[32-byte-merkle-root]
承诺结构的序列化和发现规则遵循在BIP141中的规则定义。
merkle root是由merkle tree计算出来的,该树由所有拓展块和标准块的普通交易和SW交易作为叶子。
任何包含拓展块的区块必须包含一个拓展的承诺输出。
拓展块的 opt-in
交易输出可以通过使用SW程序脚本的信号进入拓展块(在BIP141规定),如果包含的脚本是最小编码的P2PKH或P2SH脚本,则可以作为交易输出用来退出拓展块的信号。
拓展块的输出脚本的代码中只包含SW程序,P2PKH和P2SH在拓展块中被认为是无效的。
决议解决
决议交易是一种记录机制,用来维护拓展块的UTXO集合的总价值。这些决议交易作为一个连续的OP_TRUE输出赎回脚本,它们处理拓展块的入口和出口的UTXO集合。
每个区块包含的进入或退出拓展块的输出,必须包含一个最终的决议交易。该决议交易花费所有的试图进入拓展块的输出。这个决议交易必须作为标准块的最后一个交易出现(以便正确扫描所有新创建的输出)。这些资金将被发送到一个任何人都可以花费的输出(OP_TRUE)。除了另一个决议交易,任何花费这种输出的交易都会被共识规则禁止。
这个决议交易的输出必须包含额外的用于试图退出拓展块的输出。
coinbase输出不能包含隔离见证数据,由于先前存在的共识规则,他们不能被决议交易所处理。
一个决议交易的第一个输入必须引用以前的决议交易的首个输出。
费用是从拓展块传播进决议交易,换句话说,决议交易的金额一定要等于拓展块的总的金额。
引导
为了引导拓展块的激活,一个创世的决议交易必须在首个激活的块中被挖掘,用来包含一个拓展块的承诺结构以及输入输出,这个决议交易是唯一一个存在的不需要引用以前的决议交易。
这个创世决议交易的首个输入可以包含一个1-100个字节的脚本,包含一个单一的push操作码,这使得挖掘创世决议交易的矿工可以添加一个特殊的信息。这个输入脚本必须执行成功(没有格式错误的push数据,没有OP_RESERVED 操作码).
决议交易的规则:
决议交易的首个输出必须含有个一个值等于:(previous-resolution-value entering-value - exiting-value) - ext-block-fees
.
接下来的输出脚本和值必须精确的复制拓展块的退出输出(以在拓展块中出现的相同的顺序)。
决议交易的版本必须被设置为uint32的最大值(2^32 -1).规则激活后,这个版本号被共识规则禁止与任何在标准链或拓展链上的交易一起使用,这是对于决议交易简单的非上下文识别所必须的。
进入拓展区块:
任何隔离见证程序的输出都被视为一个opt-in,用来将资金发送至拓展块的UTXO集合的公钥哈希或者脚本哈希上。 示例:
代码语言:javascript复制Transaction #1 (coinbase):
Output #0:
- Script: P2PKH
- Value: 12.5
Output #1:
- Script: OP_RETURN 0xaa21a9ef[merkle-root]
- Value: 0
-------------------------------
Transaction #2 (extension block funding transaction):
Output #0:
- Script: P2WPKH (will enter the extension utxo set)
- Value: 5.0
Output #1:
- Script: P2PKH (stays in the canonical utxo set)
- Value: 2.5
-------------------------------
- 该决议交易可以赎回任何隔离验证的输出;
Transaction #3 (resolution transaction):
Input #0:
- Outpoint:
- Hash: previous-resolution-txid
- Index: 0
Input #1:
- Outpoint:
- Hash: Transaction #2 TXID
- Index: 0
Output #0:
- Script: OP_TRUE
- Value: 5.0
- 在这个例子中,一个花费者要赎回tx2的0号输出,对应的拓展块的存在形式可能如下:
Transaction #4 (redeemer of transaction #2):
Input #0:
- Outpoint:
- Hash: Transaction #2 TXID
- Index: 0
Output #0:
- Script: P2WPKH (this output remains in the ext. block)
- Value: 5.0
退出拓展块
为了确保在拓展链和拓展区块上的一对一交换,必须拓展区块上存在的输出提供出口。
在随后的交易中,tx2的输出的花费者希望获得一个输出出口来获得他们的金额。
代码语言:javascript复制Transaction #5 (coinbase):
Output #0:
- Script: P2PKH
- Value: 12.5
Output #1:
- Script: OP_RETURN 0xaa21a9ef[merkle-root]
- Value: 0
----------------------------
Transaction #6 (resolution transaction):
Input #0:
- Outpoint:
- Hash: previous-resolution-txid
- Index: 0
Output #0:
- Script: OP_TRUE
- Value: 2.5
Output #1:
- Script: P2PKH (duplicated from the exited output below)
- Value: 2.5
--------------------------------
- 拓展区块
Transaction #7:
Input #0:
- Outpoint:
- Hash: Transaction #4 TXID
- Index: 0
Output #0:
- Script: P2WPKH (this output will remain in the ext. block)
- Value: 2.5
Output #1:
- Script: P2PKH (note that this causes an exit!)
- Value: 2.5
退出赎回交易
如上所述,交易输出通过决议交易从拓展块回到主链上。在拓展块上创建的输出不得在任何链上花费,而退出输出必须从决议交易创建的端点来花费。
退出的成熟度要求
类似于coinbase交易,在链重组的情况下,决议交易也可以被永久的取消。这可能使所欲退出输出所包含的花费无效,同时导致该花费交易不可再被传播,不可再在主链上被挖掘。由于这个原因,需要退出的成熟度。
金额
从拓展块收集的金额传播到对应的决议交易上,决议交易的金额必须与拓展块上收集的金额相等。
在共识层,交易费通过交易成本以及由于进入或退出输出而添加到标准区块的 额外的字节来计算(size/legacy-sigops). 在前面的例子中,tx2的花费者的输出应该添加一点费用。
代码语言:javascript复制Transaction #5 (coinbase):
Output #0:
- Script: P2PKH
- Value: 12.501 (reward fee)
Output #1:
- Script: OP_RETURN 0xaa21a9ef[merkle-root]
- Value: 0
---------------------------
Transaction #6 (resolution transaction):
Input #0:
- Outpoint:
- Hash: previous-resolution-txid
- Index: 0
Output #0:
- Script: OP_TRUE
- Value: 2.499 (fee is subtracted)
Output #1:
- Script: P2PKH (from the exited output below)
- Value: 2.5
- 拓展块
Transaction #7:
Input #0:
- Outpoint:
- Hash: Transaction #4 TXID
- Index: 0
Output #0:
- Script: P2WPKH (this output will remain in the ext. block)
- Value: 2.499 (fee is subtracted, this propagates up)
Output #1:
- Script: P2PKH (note that this causes an exit!)
- Value: 2.5
验证
验证拓展块的交易,应当强制执行所有目前部署的软分叉规则,以及额外的类似BIP141的规则集合。
拓展块中的交易集合可以包含一个使用BIP141规则序列化后的隔离验证交易集合。
应该使用VERIFY_WITNESS规则对拓展交易执行验证。
拓展交易一定不可以访问任何标准区块的UTXO集合。
如果一个拓展区块的共识检查失败,则升级的节点必须认为整个区块是无效的。
BIP141规则变化
- 除了决议交易之外,隔离验证的输出只可以从一个拓展区块赎回。
- 隔离验证的交易只能包含隔离验证的输入。
- BIP141嵌套P2SH的功能不再可用,并且不再是共识规则。
-
block weight
和transaction weight
的概念将被移除。 -
sigops cost
的概念继续存在,用于将来的软分叉和可升级的DoS限制.
DoS Limits
DoS限制应该通过拓展块的字节大小以及新定义的交易输入和输出的规则来执行,拓展块的退出输出会影响标准块的DoS限制,因为拓展块增大了字节大小和标准的操作码。
代码语言:javascript复制MAX_BLOCK_SIZE: 1000000 (unchanged)
MAX_BLOCK_SIGOPS: 20000 (unchanged)
MAX_EXTENSION_SIZE: TBD
MAX_EXTENSION_COST: TBD
拓展块的最大字节应该是提高的。区块的平均情况是真正受到输入输出成本的限制。
未来的字节大小和计算的可扩展性可以通过软分叉来添加新的隔离见证程序来实现。在未升级的节点,未知的隔离见证程序作为一个交易输入和输出来计算。新的隔离见证程序含有较低的实现成本,以便允许未来通过软分叉来改变DoS的限制。
拓展交易的成本
拓展块利用BIP141的可升级脚本行为来实现可升级的DoS限制。
计算交易输入的成本
隔离见证的key哈希的v0等于1,乘以系数8.
隔离见证的script哈希v0等于赎回脚本中准确计算的操作码个数,乘以系数8.
未知的隔离见证程序等于1,乘以系数1.
为了减少赎回脚本中加入垃圾数据的机会,只允许垃圾数据在隔离见证交易中存在,序列化后的每73个字节隔离见证的交易等于增加一个额外的点.
为以后7次软分叉升级留出了余地,以减轻DoS限制。
计算输出成本
当前定义的v0版本的隔离见证程序每个都等于8点。未知的隔离见证程序输出等于1点,任何退出输出也一直等于8点。
为以后7次软分叉升级留出了余地,以减轻DoS限制。
灰尘阈值
现在在拓展块内强制执行灰尘共识阈值。
拓展块中交易输出值小于500聪是无效的。这包括输入和输出,但是不包括退出输出。
额外的闪电网络的安全规则
闪电网络面临者当前某些系统性的攻击(在闪电网络白皮书中有定义)。
如果在拓展块中交易的版本号第30bit被设置为1,在区块中的交易空间额外的700字节被保留。【注意:交易空间和操作数的花费尚未定义】
交易空间可以被预先申请,并且被在相同区块中的两笔交易所使用(每个交易的最大字节为350),它们满足以下定义的特殊约束条件。 第一个分配只能由,直接花费 版本号30bit被设置的交易的首个交易输出的交易来花费。
第二个分配只能由这些交易的首个输出来花费,该交易属于存在于过去2016个区块,并且版本号30bit被设置。
如果分配未被其它交易使用,该交易将消耗额外的空间,并且减少区块的可用空间多达700字节。 这是拓展区块的共识规则,并且不适用于标准区块。
这个提案的目的是确保在没有矿工的协调下,对于系统的攻击成本将会异常高。因为块的空间是预先分配给矿工的,用来包含惩罚闪电网络交易,并且由于双方必须同意闪电网络中的承诺交易的版本位,所以该规则被强制执行。这是闪电网络中的一个opt-in 功能,交易费用更高,从而提高了罚款的可用性。架设在大部分不正确的广播情况下,惩罚将通过第二次分配包含在同一个块中,并为第一次分配中的其它交易留出空间。
迁移和采用的点
大多数的比特币系统,当前都可以很好的处理BIP141升级后的规则。
对于目前支持BIP141的钱包,迁移应当是不重要的。
对于全节点的服务,API可能会变,以便将拓展块的交易透明的提供给客户端,就好像它们出现在标准块中一样。当然,这不包含任何矿工API。
钱包的关注点和迁移
当前支持BIP141的钱包必须修改一点关键的地方,以便实现兼容拓展区块。
- 当创建交易时,钱包必须选择一条链去花费(无论是标准链还是拓展链,但不能同时选择两条链)。换句话说,交易必须含有所有的隔离见证输入,或者非隔离见证输入。对于支持两条链的钱包,如果用户没有明确指定,币值选择器可以自动的选择使用哪条链。
- 支持拓展区块的钱包必须忽略决议交易的输入。可以通过简单的检查交易的版本号,类似于钱包已经忽略的coinbase交易输入。这是阻止钱包错误的看到双花的必要条件。
- 支持标准区块和拓展区块资金的钱包必须忽略拓展区块中的退出输出。这是阻止钱包错误的多次索引相同输出的必要条件。
后两条仅适用于直接监控区块链的钱包(即类似于官方bitcoind自带的钱包),监测钱包通常观察区块链并为它们的交易和输出建立索引。
交易池的关注点
交易池的变化是最小的。尽管实现的细节可能有所不同,但一个合格的交易池必须禁止两条链的交叉(两条链的混合输入),以及跟踪退出输出的交易。这些输出不可以被花费在交易池中(它们必须从下个决议交易赎回。)
矿工的关注点
额外的字节和操作数计算
注意:当内部创建块模板,并为标准区块分配大小时,节点必须考虑进入拓展块的交易和退出拓展块的输出交易。一个携带进入输出或退出输出拓展块的交易为标准区块添加了字节数。
在决议交易中,进入拓展块的输出以交易输入的形式添加字节。(此处翻译有些问题)
在决议交易中,退出拓展块的输出以复制输出的形式添加字节和原始操作码。
交易排序和选择算法必须考虑这些内容。
拓展 getblocktemplate(BIP22)
除了传统交易的数组之外,合格的实现必须包含一个拓展交易的数组。该拓展数组包含BIP22中定义的交易,以及BIP145对getblocktemplate
的拓展。
合格的实现,必须将决议交易做为普通交易数组的一部分。该决议交易必须含有一个额外的属性叫resolution
,它是一个bool值,被设置为true。直接在传统交易数组中包含决议交易是为了与现有的挖矿客户端进行向后兼容。
default_witness_commitment
已被重命名为default_extension_commitment
,并被包含在拓展区块的承诺脚本中。
一个额外的mutable
字段在resolution
中被定义。如果传统交易在可变数组中,resolution
允许拓展块可变,前提是客户端能正确的更新决议交易。
除了resolution
的可变字段,还定义了resolution capabilities
字段,以便客户端声明它可以更新决议交易。
对于处理过期挖矿客户端的节点,将拓展块本地存储在commitment-hash->ext
map结构中,此处区块数据可能是必须的(除了调用submitblock期间的一个重新序列化)
数据迁移的关注点
为了标识该UTXO属于哪条链,该功能的实现可能需要在每个存储的UTXO上添加一个额外的位。依据实现的UTXO序列化和压缩格式,这可能需要数据迁移。
激活
- 版本位:2
- 部署名字:
extblk
(在GBT作为非extblk出现) - 开始时间:TBD
- 超时时间:TBD
作用
矿工可以通过第28bit(BIP9 软分叉位)来对拓展块的功能作用进行投票。功能部署的开始时间在拓展块开始3年以后,且矿工激活阈值达95%。最小的锁定时间必须至少为每年26次。
到此为止,未来的拓展块规则集貌似已开发完毕,这在功能集合和拓展性方面是优越的。这使以最小技术包袱进行长期可扩展解决方案,来支持功能链成为可能。
功能激活后,社区期望仍然可以从拓展区块退出,并且根据尚未设计的软分叉条款来确保安全,但是在拓展区块内的资金的进入和转移将不再被允许。 提出了两种可能的功能激活方案,将在本文件的最终版本中选择一种。
方案1
在第28bit被激活时,这个决议交易的输出在当天将作为一个任何人都可以花费的输出被返回。BIP9的第28 bit(或另一个BIP9位)可以被重载用来启用软分叉,以防止该交易在未来实际上成为任何人都可以花费的交易,该功能允许不需要使用硬分叉代码来启用未来的拓展块功能。
按照社会契约的理解,拓展块中的资金在下面的去激活设计中仍然是可用和可赎回的。如果在条款中没有正确的激活和安全的取款操作,用户和交易所可以使用bit位设置软分叉来拒绝该区块。
可以通过使用在BIP9第28bit激活的相同的输出结合另一bit位的新规则来直接升级拓展区块(例如:第27bit在第28bit被激活的情况下有条件的激活新的链,来创建一个直接迁移到新的拓展块而不需要在主链上进行新的交易)。
可以被理解为,这个软分叉可以重载取款或赎回资金的强制限制,以便在取款时可以解析脚本的条款。
方案2
在第28bit被激活时,拓展区块内不允许进一步的交易处理,只允许通过merkle协议退出主链。
这就要求merkle协议的退出代码和规范必须在当天被规范和激活。
通过merkle树协议的取消激活
从旧的拓展块到主链和新的拓展块的赎回,可以通过未来设计的merkle协议来进行移植。通过对UTXO merkle根进行硬编码作为一个共识规则来使资金导入至新的拓展块,并通过merkle路径来验证导入的资金。
要启用导入,节点只需要当前拓展块的32字节的merkle root的拷贝。
这移除了全节点存储所有UTXO集合拷贝在硬盘上的必要性,并且可以在未来赎回时进行较大的链上交易。另一种是使所有的客户端保持UTXO集合的记录,并且在内存中保持所有的位域。
由于UTXO设置是静态的(仅仅是未花费或花费的改变),因为它是从新的输出中来激活的,这比当前提出的用于改变UTXO的设计更简单。
动机
虽然作用看起来有些缺点,但本规范的主要优点是不带有BIP141规则集的拓展块。相反,该体系将为处理拓展块奠定基础。使未来的比特币协议可以包含使用不同规则集的多种不同的拓展块。
引用实现
https://github.com/bcoin-org/bcoin-extension-blocks
引用
原文地址:https://github.com/tothemoon-org/extension-blocks/blob/master/spec.md
本文由 Copernicus团队 姚永芯
翻译,转载无需授权。