这篇文章最初被发表在Medium上。
我们开发了一种有效的算法来验证比特币智能合约中由某一方签署的任意数据。与之前基于Rabin签名的签名算法相比,它是基于ECDSA的,从而重新使用原生比特币密钥直接生成和验证签名。
[caption id="attachment_472824" align="alignnone" width="730"] bitnovo[/caption]概述
比特币智能合约需要预言机来导入外部数据,如天气和商品价格。一旦导入,智能合约需要通过方法来验证数据是否真的来自经授权的预言机。具体来说,我们需要解决以下问题。
如何验证一段数据是由带有已知公钥的预言机签名的?
P和p分别表示预言机的公钥和私钥,首先对要签名的数据进行哈希处理。结果要加上p,从而生成一个新的私钥p '。
x = sha256 (数据)
p ' =р+ x
对应的公钥P '可以由如下推导:
P ' =p ' * G = (p + x) * G = P + x * G
G是在比特币系统中使用的椭圆曲线的生成器。
预言机使用导出的私钥p '来签名,而不是原来的p。这里的一切除了p都是公开的,因为只有预言机知道p,只有他知道p '并可以使用它来签署P '。若要在一个合约里计算P ',我们需要计算x * G然后把结果加上P。
在脚本里有效地计算x * G
计算x * G的简单方法就是在椭圆曲线上使用点乘法。然而,它在计算上是昂贵的。我们注意到G是在椭圆曲线上的一个特殊点。如果我们将x视为私钥,x * G本质上就是x的公钥X。
X= x * G
因此,只需验证(x, X)是一个有效的私钥与公钥对。
为了验证这一点,我们利用了OP_PUSH_TX技术。在OP_PUSH_TX里,我们使用私钥来签名这个sighash原像,并使用本地签名检查,OP_CHECKSIG,来针对相应的公钥检查结果签名。如果检查通过,我们可以确定签名sighash原像一定是针对当前花费交易的。另外,公钥必须从私钥中派生出来。我们选择(x, X)作为OP_PUSH_TX中的密钥对,从而验证X确实是x的公钥。
高效的公钥添加
使用之前的椭圆曲线库,我们可以有效地添加P和X。
P ' = P + X
一旦我们有了P ',我们就可以使用本地的OP_CHECKSIG来验证包含数据的花费交易是否由预言机使用p '签名。完整的代码如下所示。
第16行使用OP_PUSH_TX来验证X=x * G。第19行检查P '= P + X 。22行检查签名是用p'生成的。
值得注意的是,预言机参与了交易的签名,其中的数据在其输入的解锁脚本中。为了最大限度地灵活地创建交易的剩余部分,他可以在签名时使用sighash标志,例如SIGHASH_NONE | SIGHASH_ANYONECANPAY。相比之下,基于Rabin签名的预言机可以简单地在不参与交易的创建的情况下发布签名数据。
总结
通过重新使用比特币密钥对,基于ECDSA的预言机可以利用比特币生态系统已经提供的现有基础设施和网络效应(其中包括所有比特币钱包和许多服务提供商,如区块链浏览器),从而显著降低开发成本。在实践中,它成为了最先进的基于Rabin签名的预言机的一个有竞争力的替代方案,尽管后者的脚本尺寸更小并且因此交易费用更低。
感谢
本文是nChain专利WO2018189634的扩展,作者是Cambridge Cryptographic的Ying Chen。
另请观看:CoinGeek纽约大会演讲,比特币智能合约与计算
?t=20698