打造公链

脚本中的流控制

2018-06-27  本文已影响0人  建怀

在脚本中使用流控制

比特币脚本中流量控制的一个非常常见的用途是构建一个提供多个执行路径的赎回脚本,每个脚本都有一种不同的赎回UTXO的方式。

我们来看一个简单的例子,我们有两个签名人,Alice和Bob,两人中任何一个都可以兑换。 使用多重签名,这将被表示为1-of-2 多重签名脚本。 为了示范,我们将使用IF子句做同样的事情:

IF
 <Alice's Pubkey> CHECKSIG
ELSE
 <Bob's Pubkey> CHECKSIG
ENDIF

看这个赎回脚本,你可能会想:“条件在哪里?”IF子句之前没有什么!“ 条件不是赎回脚本的一部分。

相反,该解锁脚本将提供该条件,允许Alice和Bob“选择”他们想要的执行路径。

Alice用解锁脚本兑换了这个:

<Alice's Sig> 1

最后的1作为条件(TRUE),将使IF子句执行Alice具有签名的第一个兑换路径。

为了兑换这个Bob,他必须通过给IF子句赋一个FALSE值来选择第二个执行路径:

<Bob's Sig> 0

Bob的解锁脚本在堆栈中放置一个0,导致IF子句执行第二个(ELSE)脚本,这需要Bob的签名。

由于可以嵌套IF子句,所以我们可以创建一个“迷宫”的执行路径。 解锁脚本可以提供一个选择执行路径实际执行的“地图”:

IF
    script A
ELSE
   IF
script B
  ELSE
script C
  ENDIF
ENDIF

在这种情况下,有三个执行路径(脚本A,脚本B和脚本C)。 解锁脚本以TRUE或FALSE值的形式提供路径。

要选择路径脚本B,例如,解锁脚本必须以1 0(TRUE,FALSE)结束。

使用这个结构,我们可以用数十或数百个执行路径构建赎回脚本,每个脚本提供了一种不同的方式来兑换UTXO。 要花费,我们构建一个解锁脚本,通过在每个流量控制点的堆栈上放置相应的TRUE和FALSE值来导航执行路径。

复杂的脚本示例

我们的例子使用了迪拜公司所有者Mohammed的故事,他们正在经营进出口业务。

在这个例子中,Mohammed希望用灵活的规则建立公司资本账户。他创建的方案需要不同级别的授权,具体取决于时间锁定。

多重签名的计划的参与者是Mohammed,他的两个合作伙伴Saeed和Zaira,以及他们的公司律师Abdul。三个合作伙伴根据多数规则作出决定,因此三者中的两个必须同意。然而,如果他们的钥匙有问题,他们希望他们的律师能够用三个合作伙伴签名之一收回资金。最后,如果所有的合作伙伴一段时间都不可用或无行为能力,他们希望律师能够直接管理该帐户。

这是Mohammed设计的脚本: 具有时间锁定(Timelock)变量的多重签名

IF                                                                              (1)
  IF                                                                            (2)
    2                                                                           (3)
  ELSE                                                                          (4)
    <30 days> CHECKSEQUENCEVERIFY DROP                                          (5)
    <Abdul the Lawyer's Pubkey> CHECKSIGVERIFY                                  (6)
    1                                                                           (7)
  ENDIF                                                                         (8)
  <Mohammed's Pubkey> <Saeed's Pubkey> <Zaira's Pubkey> 3 CHECKMULTISIG         (9)
ELSE                                                                            (10)
  <90 days> CHECKSEQUENCEVERIFY DROP                                            (11)
  <Abdul the Lawyer's Pubkey> CHECKSIG                                          (12)
ENDIF                                                                           (13)

Mohammed的脚本使用嵌套的IF ... ELSE流控制子句来实现三个执行路径。

在第一个执行路径中,该脚本作为三个合作伙伴的简单的2-of-3 multisig操作。

第二个执行路径只能在UTXO创建30天后才能使用。

第三个执行路径允许律师单独花费资金,但只能在90天之后。

该执行路径由第3行和第9行组成。第3行将multisig的定额设置为2(2 - 3)。该执行路径可以通过在解锁脚本的末尾设置TRUE TRUE来选择: 解锁第一个执行路径的脚本(2-of-3 multisig)

0 <Mohammed's Sig> <Zaira's Sig> TRUE TRUE

第二个执行路径只能在UTXO创建30天后才能使用。 那时候,它需要签署Abdul(律师)和三个合作伙伴之一(三分之一)。
这是通过第7行实现的,该行将多选的法定人数设置为1。要选择此执行路径,解锁脚本将以FALSE TRUE结束: 解锁第二个执行路径的脚本(Lawyer + 1-of-3)

0 <Saeed's Sig> <Abdul's Sig> FALSE TRUE

FALSE和TRUE这两个值被推到堆栈,所以先push FALSE,然后push TRUE。 因此,第一个IF操作码首先弹出的是TRUE。(后进先出)

第三个执行路径允许律师单独花费资金,但只能在90天之后。 要选择此执行路径,解锁脚本必须以FALSE结束: 解锁第三个执行路径的脚本(仅适用于律师)

<Abdul's Sig> FALSE

前提条件是90天后,解锁脚本中的FALSE就是要调过第一个执行路径,然后第二个执行路径,<30 days> CHECKSEQUENCEVERIFY DROP就直接返回FALSE,进入第三个执行路径。

如果三个合伙人钥匙丢了,然后律师的钥匙也丢了,资金是不是取不出来了?我的答案是没法解锁,取不出来。

合伙人有2个解锁,然后重新签名加锁,这样就相当于重置了。

就看后面还有没有接执行路径。

上一篇下一篇

猜你喜欢

热点阅读