7.7复杂的脚本示例

在本节中,我们将本章中的许多概念合并成一个例子。 我们的例子使用了迪拜公司所有者Mohammed的故事,他们正在经营进出口业务。

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

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

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

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

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

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

该执行路径由第3行和第9行组成。第3行将multisig的定额设置为2(2 - 3)。

该执行路径可以通过在解锁脚本的末尾设置TRUE TRUE来选择: 解锁第一个执行路径的脚本(2-of-3 multisig)

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

提示 此解锁脚本开头的0是因为CHECKMULTISIG中的错误从堆栈中弹出一个额外的值。 额外的值被CHECKMULTISIG忽略,否则脚本签名将失败。 推送0(通常)是解决bug的方法,如CHECKMULTISIG执行中的错误章节所述。

第二个执行路径只能在UTXO创建30天后才能使用。 那时候,它需要签署Abdul(律师)和三个合作伙伴之一(三分之一)。

这是通过第7行实现的,该行将多选的法定人数设置为1。要选择此执行路径,解锁脚本将以FALSE TRUE结束: 解锁第二个执行路径的脚本(Lawyer + 1-of-3)

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

提示 为什么先FALSE后TRUE? 反了吗?这是因为这两个值被推到堆栈,所以先push FALSE,然后push TRUE。 因此,第一个IF操作码首先弹出的是TRUE。

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

  1. <Abdul's Sig> FALSE

在纸上运行脚本来查看它在堆栈(stack)上的行为。

阅读这个例子还需要考虑几件事情。 看看你能找到答案吗?

  • 为什么律师可以随时通过在解锁脚本中选择FALSE来兑换第三个执行路径?
  • 在UTXO开采后分别有多少个执行路径可以使用5,35与105天?
  • 如果律师失去钥匙,资金是否流失? 如果91天过去了,你的答案是否会改变?
  • 合作伙伴如何每隔29天或89天“重置”一次,以防止律师获得资金?
  • 为什么这个脚本中的一些CHECKSIG操作码有VERIFY后缀,而其他的没有?