Inline Assembly

Script is a low-level language and acts as assembly for the Bitcoin Virtual Machine. Usually, developers do not have to deal with it directly and can use high-level languages like sCrypt. However, there are cases where using Script is desirable. For example, customized script is optimized and thus more efficient than script generated by sCrypt. Or script is generated using external tools (like MiniForth) and needs to be integrated into sCrypt.

Script can be embedded directly into sCrypt source code using assembly representation. An sCrypt function can be written in Script and called like a regular sCrypt function.

Calling Convention

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, all parameters must be poped and replaced with a single returned result on top of the stack. All other items in the stack must remain intact.

Two assembly functions are shown below.

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

function lenFail(bytes b): int {
    // this is wrong since there are TWO elements on stack upon return
    asm {
        op_size
    }
}

Assembly Variable

Variables can be used inside asm mode by prefix $. Unlike the rest of Script, which is copied verbatim into the final script output, a variable is prefixed by its scope to avoid name collision, uniquely identified by the function and contract it is within. For example, supposed a variable $var is used inside function func inside contract contractFoo, it will show up in the final script output as $contractFoo.func.var.

An example is shown below.

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

Notes

Inline assembly bypasses many features of sCrypt such as type checking. Extreme caution has to be taken using this advanced feature. Also it is case-insensitive for compatibility with external tools.