灵活交易(Flexible Transactions)

2016-09-26 10:31 来源:巴比特资讯 阅读:5923
最近不断有人问我一个问题,而且越来越频繁。这个问题是关于隔离见证(Segregated Witness)方案,特别是以硬分叉为基础的版本将会怎样。

Transactions

最近不断有人问我一个问题,而且越来越频繁。这个问题是关于隔离见证(Segregated Witness)方案,特别是以硬分叉为基础的版本将会怎样。

隔离见证(或简称为“SegWit”)非常复杂。它试图解决相当多的、完全不同的和不相关的问题,并试图以向后兼容的方式这样做。这不是一件小事!

那么,SegWit究竟视图解决什么问题呢?我们可以在效益文件中找到这些信息:

  1. 延展性修复

  2. 对签名中哈希运算操作的线性扩容(也即一倍的哈希运算导致一倍的CPU消耗,10倍的运算则对应10倍的消耗)(译者注:这一句的原文是Linear scaling of sighash operationssighash)

  3. 输入值签名

  4. 通过“支付给脚本哈希(P2SH)”交易标准,增加多重签名(Multisig)的安全性

  5. 脚本版本

  6. 降低UTXO增长

  7. Compact fraud proofs (紧凑的欺诈证明)

如上所述,SegWit试图以一种向后兼容的方式解决这些问题。这种要求只是因为SegWit作者设置了这一要求。这样设置是因为他们希望用软分叉推动这个协议升级。本文将试图回答这个问题:这是否是解决这些问题的最好办法。

从延展性开始,问题是,一笔交易从资金所有者和挖区块的矿工构建开始,因为延展性问题,延展性改变都会被认为是有效的交易,但交易标识符(TX-id)已经改变了。在我们深入探讨之前,让我们先看看交易数据结构。

如果我们看一下现在的交易数据结构,我们会注意到一些问题。

 

filehelper_1474631294768_38
最初的交易格式是由中本聪设计,它是包含一个4字节的版本号。这种设计方法在行业中是很常见的,采用的方式是当数据结构中的任何字段需要更改时,则定义一个新版本。就比特币而言,我们还没有做到这一点,我们仍然处于版本1。

比特币取而代之的是做出更小的、半向后兼容的变化。比如,CHECKSEQUENCEVERIFY特点是将repurposes序列字段作为一种添 加数据的方式(译者注:CHECKSEQUENCEVERIFY重定义了sequence 字段以便在不破坏兼容性的前提下增加数据),而不破坏旧客户端的数据。顺便说一句,在主要客户端中,这个特定的改变(详见 BIP68)不向后兼容,因为它依赖于一个大于1的交易版本号,他们都检查标准交易,并说只有版本1是标准的。

一个版本号的设计意味着,设计师想使用硬分叉来处理变化。一个新的客户端需要知道如何解析一个新设计的数据结构,这应该是显而易见的。因此,一个主 意是要改变版本号,所以老客户会知道他们无法解析这个新的交易版本。为了保持操作,每个人都必须升级到支持这个新交易版本的客户端。

让我们看看为什么我们会想改变版本,我用红色标记了着一些项目,它们易使人混淆。最特别的是,在交易中,这些数字分别是以3个不同的、不兼容的格式存储。这不见得是大的和确定的程序错误。

交易是由比特币的所有者签名加密,以便其他人可以验证,他实际上可以转移该地址的比特币。签名保存在 TX-in-script中。

密码极客们可能已经注意到一些奇怪的东西,它们违背任何课本知识。即数字签名必须放置在它标志的事物外面。这是因为数字签名可以保护自己,防止被更 改。但一个签名本身会引起这种变化。所以您必须在您签署的事物外储存签名。(译者注:即数字签名必须放置在它签署的数据之外。这是因为数字签名可以保护被 签署的数据不被更改,但签名的本身则会引起数据的变化。因此你必须把签名放在被签署的数据之外)

就如何实际进行签署交易,比特币的创造者做了一些“聪明”的设计,所以签名实际上不必在交易之外。大多数情况下,它确实起作用了。但我们希望它能完美无瑕地的发挥作用,因为目前这些设计太过“聪明”,会导致可怕的延展性问题,人们已经就此而赔钱了。

SegWit(隔离见证)怎么样?

SegWit(隔离见证)实际上只解决这些项目中的一个问题。它将签名从交易中移出来。SegWit(隔离见证)未解决比特币交易中的任何其他问题,在做出交易后,它也没有改变版本,这意味着老客户基本上无法理解其本质意义。

老版本客户端将不再能够检查交易的SegWit(隔离见证)类型,因为当真正的数据移动到“拖车”上时,SegWit(隔离见证)的作者只是使 SegWit(隔离见证)交易打上“一切OK”的标签,而明知道老客户会忽略“拖车”。(译者注:隔离见证的作者把其设计的类似于一辆车上贴上一个“一切 都OK”标签,但却把真实的数据移到车后面的拖车上,知道旧客户端不会去检查拖车)

SegWit(隔离见证)想要保持交易的数据结构不变,并试图修复交易的数据结构。这将导致相互矛盾,因为您不能同时进行,于是就有了非理想的情况,随之而来的黑客攻击也在预料之中。

然后的问题是,SegWit(隔离见证)引进了更多的“技术债务”,它是一个软件术语,指的是开发团队在设计或架构选型时从短期效应的角度选择了一 个易于实现的方案,但从长远来看,这种方案会带来更消极的影响,亦即开发团队所欠的债务。“债务”一词在这里比喻地十分准确,随着时间的推移,使用交易的 每个人都必须了解这种缺陷,从而正确地操作。这与支付利息非常相似。

使用软分叉是指老客户将无法验证交易,甚至无法完全解析它们。但这些老客户自己认为他们正在做充分的验证。

我们能对此进行改进吗?

我想建议一种方法来一次性改变交易的数据结构,使它变得更加面向未来,并随着时间的推移,修复它遇到的问题,包括延展性问题。事实证明,这种新的数据结构,可使SegWit(隔离见证)能修复并解决所有的、相当琐碎的其他问题。

我打算提出一个升级方案我称之为:

Flexible Transactions(灵活交易)

上个周末,我写了一个小应用程序(源代码请点击这里),读取一个交易,然后按照我为比特币设计的一个新格式写出来。它基于我已经在其他项目上使用了一段时间的主意,但这是第一个开源版本。

基本的想法是改变交易,使其更像现代系统,如JSON, HTML and XML。它是一个以“标签”为基础的格式,比封闭式的“binary-blob”(二进制-blob)格式要有更多各种优点。

例如,如果您添加一个新的field(字段),就像HTML中的标签,您的旧浏览器将只是忽略它,使它向后兼容,并且适用于未来的升级。

更多的优点;

  • 解决延展性问题,它将变得微不足道。

  • 以“标签”为基础的系统可以使您跳过未使用或默认值的writing(写入)。

  • 因为我们正在做出改变,在交易中,我们可以只使用var-int(可变整数)编码数据来替代3个不同的类型。

  • 添加新的标签后(例如ScriptVersion(脚本版本)),不需要进一步修改交易数据结构。所有老客户仍然可以解析所有已知的数据。

  • 实际的交易时间比平均值缩短约3%(超过200K的交易计算)

  • SegWit(隔离见证)增加了大量的技术债务,而我的“Flexible Transactions(灵活交易)”方案不会造成大量的技术债务摊销。

 

“Flexible Transactions(灵活交易)”方案一般看起来如下:

filehelper_1474631359863_56
Flexible Transaction (灵活的交易)建议使用一个标签列表,如JSON; ”Name:” “Value”.,使内容变得非常灵活且可扩展。仅仅只取代了文本, Flexible Transaction(灵活的交易)使用一个二进制格式。注意如何跳过未使用的标签。NLockTime 和 Sequence 没有使用,所以它们在 交易中被跳过。

最大的变化是, TX-in-script (又名witness(见证)数据)被移动到交易末端。当一个钱包产生这种新的交易类型时,他们将在最后追加witness(见证)数据,但是,通过哈希算法计算witness(见证)数据之前结束的数据来获得交易标识。

Witness(见证)数据通常包含一个公钥以及签名。在Flexible Transactions(灵活交易)方案中,签名由完全相同的数据集签署完成,采用哈希算法生成TX-input。解决延展性的问题。如果有人改变交易,这将使签名无效。

 

我使用测试应用程序进行测试,我测试了187000个最近的交易,并检查了这个改变会对交易的大小有什么影响。

  • 交易从平均1712字节下降到1660字节,平均值从333个字节下降到318个字节。

  • 在它们已被确认后,交易可以进一步精简(去除签名)。精简后,大小平均下降450个字节,或中位数平均下降101个字节

  • 与SegWit(隔离见证)相反,所有客户端进行此升级后,得到交易体积都更小。

  • 在签名被移除后,交易和区块,可以期望高达75%的体积大小减少。

Broken OP_CHECKSIG脚本指令

实际上为了从源头解决延展性问题,我们需要修复这个指令。但是,我们不能改变原来的脚本,直到我们决定制作一个版本2的脚本语言。

这种变化并不是制作版本2的一个很好的时机,这将是疯狂的,因为在同一时间,我们还推出了交易本身得一个新格式。(同一时间有太多的变化必然会引起问题)。

这意味着,为了使Flexible Transaction(灵活交易)方案实际发挥作用,我们现在需要在脚本中使用一个从未使用过的NOP码,并且让它的作用基本上与 OP_CHECKSIG相同,但是,在决定它如何签署方面,不使用过于复杂的方式,我们只是定义它来签署完全相同的交易区域,我们也用它来创建TX- ID。(参见上面表格最右列)。

这个新的opcode(操作码)应该是比较容易的代码,它将使我们非常容易地解决在未来版本的脚本中引入脚本的问题。

那么,与SegWit(隔离见证)相比如何?

首先,引入一个新版本的交易并不意味着我们停止支持当前版本。因此,所有这一切都是完美的向后兼容,客户可以继续在旧版本上使用旧的交易格式进行交易。当然会存在一些问题,但没有人最终会被卡住。

对于一个交易,使用一个标记的格式,是一次性硬分叉升级协议,这允许更多的变化,并且对未来系统的影响要小得多。也与SegWit(隔离见证)有相 似之处,毕竟争取的是同样的目标。但是,SegWit(隔离见证)试图通过重新利用现有的fields(字段)来调整静态存储格式,而Flexible transactions(灵活交易)方案提出了一个连贯的简单的设计,消除了大量相互冲突的概念。

最重要的是,在Flexible transactions(灵活交易)方案已经引入多年后,,我们可以继续受益于标签系统,从而扩展和修复我们今天还没有想到和发现的问题,使用相同的和一致的概念。

类似于SegWit(隔离见证),我们可以在同一(区块)空间容纳更多的交易,签名(witness部分)可以通过全节点精简,而不造成任何安全问 题,这些两个解决方案来是一样的。SegWit(隔离见证)未实现的是,未使用的功能不占空间。因此,如果一个交易不使用NLockTime(它们当中近 100%使用),在SegWit中,它们依然将占据空间,而本建议的方案不会。预期您的交易尺寸会较小,因此费用会较低!

在体积大小上, SegWit(隔离见证)目标是增加60%的空间。通过移除签名来减少开销。在我的测试中,Flexible transactions(灵活交易)显示了增加了75%的空间。

SegWit(隔离见证)还描述了如何将存储在区块中的数据进行更改。它在Merkle进程树上创建了一个额外的分支。Flexible transactions(灵活交易)在本质是和SegWit(隔离见证)使用相同的办法解决了相同的区块应用问题。这意味着我们也可以采用Merkle 进程树的方案。没有发生变化。

在本文上述提到的优势列表中,包括SegWit(隔离见证)作者所述的优势。事实证明,这些优势彼此本身是完全不相关的,他们每个都有一个非常独立的解决他们问题的方案。棘手的部分来自于老客户的要求,他们被迫把他们都推到一个“修复”的问题上。

让我们来逐一回顾一下:

延展性修复

使用这个新版本的交易数据结构解决了所有已知的延展性问题。

对签名中哈希运算操作的线性扩容(Linearscaling of sighash operations)

这试图解决的问题在bitcointalk里的这个帖子(https://bitcointalk.org/?topic=140078)有描述。

在这个讨论结果显示,SigOps变量被引入,不久就被证明这不是最优解。在BIP109中有一个更好的解决办法叫sig-hash-bytes(运算总节点数)。它是基于这样的事实,哈希是验证过程最昂贵的部分(需要注意的是哈希也是签名验证的一部分)。

在这个解决方案中,给出了一个明确的结论,1M区块最多只允许计算650MB的哈希数量,相应的就只需要5秒钟的验证时间,这样是对验证区块时间的一个保护,不至于特别长。

这是一个很好的平衡,每MB的区块650MB的哈希运算可以保证最极端的交易发生时保证区块验证。

这看起来像是一个不需要去解决的问题。修改协议,可能带来意想不到的后果,这是矫枉过正。

输入值的签名

包括在本建议方案中。

通过pay-to-script-hash (P2SH)交易标准,增加多重签名的安全性

在本文中列出的Flexible transactions(灵活交易)方案的建议中,使SegWit(隔离见证)中许多额外的变化在以后很容易添加。这种变化是其中之一。

底线是,对于SegWit(隔离见证),使用更大的哈希来对SegWit(隔离见证)安全更改,仅仅只对SegWit(隔离见证)有效,因为SegWit(隔离见证)没有解决交易的版本问题,使得单独处理它变得平凡而价值很小。

通过Flexible transactions(灵活交易)方案,这种变化可以在未来任何时间进行,且影响最小。

脚本版本

注意,这只是介绍了版本控制字节。它实际上并没有引入一个新版本的脚本。

这是一个很好的例子,Flexible transactions(灵活交易)方案的标签格式比SegWit(隔离见证)采用的静态存储格式更具优势,因为添加这样的版本标签会更清洁、更便捷、 更低侵入。只添加一个新的标签,默认为版本1,所以能与没有标签的旧版本交易保持一致。

试想一下,在每一个HTML页都必须包含“body background=white”,因为它不允许被丢弃。这就是SegWit现在所做的。尽管实际上目前并没有支持改变它。

降低UTXO增长

我建议您为自己而仔细阅读这点,这是相当有趣的技术,我相信许多人都不会完全掌握、理解这个想法。底线是,他们声称UTXO数据库将避免增长,因为SegWit(隔离见证)不允许为更多的客户提供服务。

我甚至不知道该如何回应这样的解决方案。这是典型的把婴儿和洗澡水一起倒掉。

在过去的20年里,数据库技术已经非常成熟,相比于自由和开源数据库今天所能做的事请,这个数据库根本微不足道。当然,UTXO数据库稍微不适合正常的SQL数据库,但从长远来看,告诉客户到别的地方去的做法,没有哪个长远的项目会做这样的事。

Compact fraud proofs (紧凑的欺诈证明)

再次地,这个并不包括在SegWit(隔离见证)中,而是只提供了一个基础。Flexible transactions(灵活交易)也提供了相同的基础,在这里两个方案是一样的。

我们提供了哪些SegWit(隔离见证)没有提供的?

  1. 交易变得可扩展。未来的改进是方便的。

  2. 交易体积更小。使用较少的功能,需要更少的空间。

  3. 我们只使用一个整数类型而不是3个来编码。

  4. 我们移除了技术债务并实现了简化。SegWit(隔离见证)则相反。

总结

SegWit(隔离见证)具有一些好的想法和一些必要的修正。取其精华去其糟粕是可以的,但是需要硬分叉。这篇文章表明,这些优势是相当重要的,而且是值得的。

我们介绍了一种标签数据结构。从概念上讲,它像JSON和XML一样灵活,但本建议的方案是一个紧凑和快速的二进制格式。采用Flexible transactions(灵活交易)数据格式可以让未来许多的改进和创新保持一致和干净,在随后的阶段,即使更长的时间里,其向后兼容的方式比 SegWit(隔离见证)更优秀。我们可以看到SegWit(隔离见证)试图分开来修复的基础事项是可以被一次性全做完的,对比特币来说,作为一个系统, 这样做风险更低。

在SegWit(隔离见证)已经开始设计了一年后,我们仍然发现各种问题,并且延迟了软件释放时间,我认为,放弃保持向后兼容的要求应摆到台面上来来讨论。

引入Flexible transactions(灵活交易)升级有很大的好处,因为交易设计变得具有可扩展性。进行一次性的硬分叉让我们在未来可以进行软升级。

Flexible transactions(灵活交易)方案降低了整个系统所需的变化量。不仅仅对完整节点来说是这样,而且特别考虑到许多工具和钱包是通过共享库来创建和解析交易。

任何关心协议稳定性的人应考虑本文建议的Flexible transactions(灵活交易)升级方案,因为在升级之后,失败风险低于SegWit(隔离见证)几个数量级。它没有技术债务,这将使我们能够在未来更好地进行创新。

Flexible transactions(灵活交易)的交易体积更小,能比SegWit(隔离见证)提供更显著的空间节约。 

(感谢币圈才子@vatten的校核)


声明:此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。本网站所提供的信息,只供参考之用。

点击阅读全文