在脚本中使用流程控制

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

让我们看一个简单的例子,我们有两个签名者,Alice 和 Bob,任何一个都能赎回。使用多重签名,这可以表示为一个 1-of-2 多重签名脚本。为了演示起见,我们将使用一个 OP_IF 子句完成相同的操作:

OP_IF
 <Alice's Pubkey>
OP_ELSE
 <Bob's Pubkey>
OP_ENDIF
OP_CHECKSIG

看着这个赎回脚本,你可能会问:“条件在哪里?在IF子句之前没有任何东西!”

条件不是脚本的一部分。相反,条件将在花费时提供,允许Alice和Bob“选择”他们想要的执行路径:

<Alice's Sig> OP_TRUE

OP_TRUE作为条件(TRUE),将使OP_IF子句执行第一个赎回路径。这个条件将Alice拥有签名的公钥放入堆栈中。OP_TRUE操作码,也称为OP_1,会将数字1推送到堆栈中。

要使Bob赎回此项,他必须选择OP_IF中的第二个执行路径,给出一个FALSE值。OP_FALSE操作码,也称为OP_0,将一个空字节数组推送到堆栈中:

<Bob's Sig> OP_FALSE

Bob的输入脚本导致OP_IF子句执行第二个(OP_ELSE)脚本,该脚本需要Bob的签名。

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

OP_IF
 subscript A
OP_ELSE
 OP_IF
 subscript B
 OP_ELSE
 subscript C
 OP_ENDIF
OP_ENDIF

在这种情况下,有三条执行路径(子脚本A、子脚本B和子脚本C)。输入脚本以一系列TRUE或FALSE值的形式提供路径。例如,要选择子脚本B,输入脚本必须以OP_1 OP_0(TRUE,FALSE)结尾。这些值将被推送到堆栈上,使得第二个值(FALSE)位于堆栈的顶部。外部OP_IF子句弹出FALSE值并执行第一个OP_ELSE子句。然后,TRUE值移到堆栈的顶部,并由内部(嵌套的)OP_IF评估,选择B执行路径。

使用这种结构,我们可以构建具有数十或数百个执行路径的赎回脚本,每条路径提供一种不同的赎回UTXO的方式。要花费,我们构建一个输入脚本,通过在每个流程控制点上将适当的TRUE和FALSE值放入堆栈来导航执行路径。

Last updated