内联汇编

脚本是一种低级语言,可以看作是 比特币虚拟机 的汇编语言。通常,开发人员不用直接使用它,而是用像sCrypt这样的高级语言。但有些情况下用脚本语言更合适。例如,直接写出更优化的脚本,比用sCrypt生成的更高效。或者脚本是用外部工具(如 MiniForth )生成的,想集成到sCrypt中。

用汇编表示法可以直接把脚本嵌入到sCrypt源代码中。可以用脚本编写sCrypt函数,并像正常的sCrypt函数一样被调用。

调用规范

For a function to be written in Script, its entire body must be enclosed by asm mode. Function parameters are on top of the stack, in reverse order as declared. For example, for a function with signature function foo(int p0, bytes p1, bool p2): int, p2 will be top of the stack, p1 second from top, and p0 third from top when entering asm mode. When exiting asm mode, the return value is on top of the stack. All other items in the stack before the call must remain intact.

Three assembly functions are shown below.

// compute length of "b" in bytes
function len(bytes b): int {
    asm {
        op_size
    }
}

// this is also fine since the return is on top and none in the old stack is changed
function len(bytes b): int {
    asm {
        op_size
        op_nip
    }
}

function lenFail(bytes b): int {
    // this is wrong since the original top of stack is dropped
    asm {
        op_drop
        op_size
    }
}

汇编变量

asm 模式下,可以用 $ 前缀来使用变量。其他脚本都是逐字复制到最终脚本输出中的,而汇编变量不是。变量以它的作用域为前缀,这样可以避免重名,由变量所在的合约和函数进行唯一标识。例如,在合约 contractFoo 中的函数 func 中有个变量 $var ,在最终脚本输出中会被转换成 $contractFoo.func.var

下面展示一个例子。

function p2pkh(Sig sig, PubKey pubKey): bool {
    asm {
        op_dup
        op_hash160
        $pkh
        op_equalverify
        op_checksig
    }
}

注意

内联汇编绕过了sCrypt的许多功能,例如类型检查等。所以使用这个高级功能时要格外小心。此外,该功能在与外部工具的兼容性上是不区分大小写的。