区块链论文研读12:谨慎日志合约 Discreet Log Contracts,详细 清晰 通俗易懂

今天讲的论文来自MIT的Digital Currency Initiative, 名字叫《Discreet Log Contracts》https://adiabat.github.io/dlc.pdf,作者是比特币闪电网络的作者Dryja。它跟闪电网络有一些联系。

本文不是论文的直接翻译。本人希望以通俗易懂的表述方式跟读者分享区块链技术。欢迎关注本人知乎:https://www.zhihu.com/people/liangyihuai/或者知乎专栏

1 论文背景和要解决的问题

现在有一个应用场景,alice和bob想要投注明天的天气,如果明天下雨,bob给alice一个比特币,如果明天晴天,alice给bob一个比特币。第三方可信者olibia在明天的时候揭晓天气情况。但是,olibia可能会被bob或者alice任何一方贿赂。而且,比特币的区块链并不能感知“天气”这个链外的数据。因此,我们将olibia换成一个oracle。具体oracle是什么这里不讲,可以搜索一下关键字‘预言机’或者oracle machine。目的是在明天由oracle来公平地向比特币网络中输入和决定天气情况。

本文向比特币网络中输入链外的“天气”信息的方式是多方签名,i.e., 一个交易的输入需要多个签名。

2 背景知识

如果读者知道椭圆曲线加密算法的话,这段的内容就很好理解了。这里只涉及到它的几个性质,不需要很深入很具体的了解。

如果A和B表示椭圆曲线上的一个点,a和b表示一个标量(即数字),那么能进行如下运算

A+B 或者A-B 或者A*b或者A/b

但是不能:

A*B 或者A/B。

如果G是椭圆曲线上的任意一个点,满足

(aG) + (bG) = (a + b) G (1)

这时候我们可以把a或者b当作私钥,aG或者bG当作公钥了。上面式子便是私钥的和能够得到公钥的和。这是一个很重要的性质,下文会用到。

2.2 Schnorr 签名

区块链论文研读12:谨慎日志合约 Discreet Log Contracts,详细 清晰 通俗易懂
上图表示schnorr签名,a是私钥,A是公钥,k是一个随机数,它只能使用一次。签名包含R和s。因为A和R和s和G大家都知道,所以大家都可以通过式子来认证:sG = R - h(m, R) A,其中m是消息。

之所以k只能使用一次,因为可以根据两次使用同一个k值的签名来计算出私钥a。具体计算如下图。
区块链论文研读12:谨慎日志合约 Discreet Log Contracts,详细 清晰 通俗易懂

3 Discreet Log Contracts 合约构造

下面是论文的合约的构造过程,注意下面的符号表示跟上面的是不一致的,而且,为了更好理解,本人对论文中的书写顺序适当调整了。

区块链论文研读12:谨慎日志合约 Discreet Log Contracts,详细 清晰 通俗易懂
下面事件按照时间先后顺序发送:

  1. oracle根据自己的私钥v生成公钥V = vG,其中G是一个点(比如椭圆曲线上的点)。并且根据一个随机数k生成R = kG。oracle把V和R公布出去。
  2. alice和bob需要下赌注。这里alice下注明天是雨天,bob下注是晴天。他们需要往一个交易里面各自存入1比特币的押金,然后将这个交易发布到区块链中。其中这个交易的输出是两个人的地址。也就是需要两个人的签名才能够花费这个交易里面的钱。
  3. 在区块链链下,链下的含义是,该交易暂时只保存在用户的本地,还没发布到区块链中。alice和bob各自生成一个交易,其中Alice的交易的输出如下:
    PubAi(PubBTimeDelay)2Pub_{A_i} ∨ (Pub_B ∧ TimeDelay ) (2)PubAi​​∨(PubB​∧TimeDelay)(2)
    其中
    PubAi=PubAlice+siG3Pub_{A_i} = Pub_{Alice} + s_i G (3)PubAi​​=PubAlice​+si​G(3)
    siG=Rh(i,R)V4s_iG = R - h(i, R)V (4)si​G=R−h(i,R)V(4)

需要注意的是,比特币的一个交易的输出是一个脚本,它指明了“需要什么样的方式才能拿到这个交易中的钱”。因此上面的(2)式表示一个人能够通过公钥PubAiPub_{A_i}PubAi​​所对应的私钥 PrivAiPriv_{A_i}PrivAi​​来立即拿到里面的钱,或者等待TimeDelay时间之后,通过bob的私钥来拿这个交易中的钱。PubAiPub_{A_i}PubAi​​ 不是Alice的公钥,而是(3)式表示的形式, 其中PubAiPub_{A_i}PubAi​​ 是公钥,对应的私钥为PrivAi=PrivAlice+sPriv_{A_i} = Priv_{Alice} + sPrivAi​​=PrivAlice​+s 。根据现有的信息,Alice能够计算siGs_iGsi​G,但是无法计算PrivAiPriv_{A_i}PrivAi​​,她需要等待语言机公布s。

为什么要有这一项(PubBTimeDelay)(Pub_B ∧ TimeDelay )(PubB​∧TimeDelay)呢?它防止alice将这个交易发布出去。因为只要她发布这个交易到区块链中,bob就能够在timedelay时间之后获取到这个钱了。

Bob的交易的输出如下,跟alice的相反。
PubBi(PubATimeDelay)Pub_{B_i} ∨ (Pub_A ∧ TimeDelay )PubBi​​∨(PubA​∧TimeDelay)

Alice所生成的交易的输入需要Bob的签名,同样,Bob所生成的交易的输入也需要Alice的签名。

  1. 已经过了一天,是雨天。该是oracle发布结果的时候了。它计算
    s=kh("",R)vs = k - h("雨天", R)vs=k−h("雨天",R)v
    然后将这个s公布出去。(比如采用广播的方式)。
  2. 成功投注的alice就能够使用 PrivAi=PrivAlice+sPriv_{A_i} = Priv_{Alice} + sPrivAi​​=PrivAlice​+s 获取到赢回来的钱了。

如果读者读到这里还没有明白整个过程的话,那么可以根据下面两个式子梳理一下思路,本人在弄明白之前也遇到同样的问题:

Alice的交易的输出的共钥是:
PubAi=PubAlice+siGPub_{A_i} = Pub_{Alice} + s_i GPubAi​​=PubAlice​+si​G
对应的私钥是:
PrivAi=PrivAlice+sPriv_{A_i} = Priv_{Alice} + sPrivAi​​=PrivAlice​+s
在语言机公布s之前,alice是能够计算PubAiPub_{A_i}PubAi​​并用于构造这个交易的输出地址。但是需要这个地址所对应的私钥PrivAiPriv_{A_i}PrivAi​​的签名才能够拿到钱,但是这个时候alice无法构造签名,因为预言机还没公布s。Bob是无法拿到钱的,因为

PubBi=PubBob+siG=PrivBobG+siG=(PrivBob+si)G=(PrivBob+(kh("",R)v))G=PrivBiGPub_{B_i} \\ = Pub_{Bob} + s_i G \\ = Priv_{Bob} G + s_i G\\ = (Priv_{Bob} + s_i ) G\\ = (Priv_{Bob} + (k - h("晴天", R)v))G\\ = Priv_{B_i}GPubBi​​=PubBob​+si​G=PrivBob​G+si​G=(PrivBob​+si​)G=(PrivBob​+(k−h("晴天",R)v))G=PrivBi​​G
上面式子中的sss跟oracle公布的s不一致,因此bob无法构造出私钥PrivBiPriv_{B_i}PrivBi​​.

4 Further work

  • 如果交易已经进行到上面第三步了,alice或者bob想中断这个交易或者想让其他人来替代,如果双方中的一方不同意,一定要等到预言机公布结果的那一刻,怎么办呢?
  • alice和bob在交易之前,需要联系上对方。如何以一种分布式的安全的无监管的方式寻找和匹配到他们呢?

5 reference

  • 作者演讲的ppt:https://ocw.mit.edu/courses/media-arts-and-sciences/mas-s62-cryptocurrency-engineering-and-design-spring-2018/lecture-notes/MAS-S62S18-lec15.pdf
  • 作者的演讲视频:https://www.youtube.com/watch?v=P6AX8KdXAts&list=PLUl4u3cNGP61KHzhg3JIJdK08JLSlcLId&index=14
  • 论文地址:https://adiabat.github.io/dlc.pdf

下面是关于schnorr签名的资料

上一篇:java – 构造函数何时以及如何对实例变量强制实施限制?


下一篇:6.4 操作契约 Operation Contracts