Use Script inside sCrypt
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 smaller and more efficient than Script generated by sCrypt. Or script is generated using external tools like Baguette and needs to be integrated into sCrypt.
To achieve this currently, you have to edit the auto-generated .scrypt
files under your project's artifacts
directory.
First you create a project called P2PKH
:
npx scrypt-cli project P2PKH --asm
Notice the --asm
option must be enabled, meaning you are going to use inline assembly format of script.
Your contract is at src/contracts/p2pkh.ts
:
export class P2PKH extends SmartContract {
@prop()
readonly address: Addr
constructor(address: Addr) {
super(...arguments)
this.address = address
}
@method()
public unlock(sig: Sig, pubkey: PubKey) {
assert(
pubKey2Addr(pubkey) == this.address,
'public key does not correspond to address'
)
assert(this.checkSig(sig, pubkey), 'signature check failed')
}
}
Say you want to substitute the unlock
function with manual script, you edit the file .asm/asm.json
.
{
"P2PKH": {
"unlock": "OP_DUP OP_HASH160 $pubKeyHash OP_EQUALVERIFY OP_CHECKSIG"
}
}
Variables can be defined by prefix $
, as in $pubKeyHash
.
We could also define multiple substitutions for multiple methods, if needed.
Now, you can compile the contracts with --asm
option:
npx scrypt-cli compile --asm
Now, after compiling, the function body will be replaced with script, as could be seen in artifacts/P2PKH.scrypt
.
Set Inline Assembly Variables
Assembly variables can be replaced with literal Script in ASM format using setAsmVars()
. Each variable is prefixed by its unique scope, namely, the contract and the function it is under.
p2pkh = new P2PKH(Addr(myAddress.toByteString()))
// Set ASM variable
// Keep in mind that these are NOT constructor parameters and must be set separately.
asmVarValues = {
'P2PKH.unlock.address': myAddress.toByteString()
}
p2pkh.setAsmVars(asmVarValues)
Full code can be found on GitHub. For more information about inline script/assembly, please refer to here.
Inline script bypasses many features of sCrypt such as type checking. Extreme caution has to be taken when using this advanced feature.