An sCrypt Developer’s Guide to Optimization

Part I: manual optimization

sCrypt
2 min readMay 18, 2021

sCrypt programming is different from traditional programming done in Javascript or Python, as the compiled code size directly determines their running cost when the transaction encapsulating it is submitted to the Bitcoin network. It is thus imperative that the resulting Script is as small as possible to save transaction fees¹. We list some tips for developers to manually optimize their sCrypt contracts’ Script outputs.

1. Batch same function calls

All function calls are implemented by inlining. The function body is copied to where it is called. If there are multiple callers of the same function, code size can be saved by merging them. In the following example, two Tx.checkPreimage() calls are consolidated into one.

2. Code in raw Script

Inline assembly allows native Bitcoin Script to be directly embedded in sCrypt code, for more fine-grained control. If you know customized Script that is shorter than what sCrypt yields, you can use it instead.

3. Use implicit/default constructors

A constructor often just uses its arguments to initialize each property. Use default constructor if this is the case to save code size.

4. Avoid variable reassignments

Bitcoin Virtual Machine (BVM) operates purely on stack. Unlike many other VMs, it does not have other types of memory like register or RAM, in which writing to a variable location takes O(1). BVM takes O(n) to write to a variable, where n is the depth of the variable down the stack².

A special case is static properties of a contract. They are stored at the bottom of the stack internally, making them especially expensive to update. If they really have to be changed, see if they can be made into non-static properties.

5. Use loop induction variables

An induction variable is cheaper than a regular variable incremented in every loop.

6. Use optimized version of OP_PUSH_TX

See optimal and OP_CODESEPARATOR version of OP_PUSH_TX.

7. Use Merklized Abstract Syntax Tree

See this article.

[1] Currently, transaction fee is simply proportional to script/transaction size, which will evolve to take script complexity into consideration. Thus optimization objective is expected to evolve in the future as well.

[2] Reading a variable is always O(1).

--

--

sCrypt
sCrypt

Written by sCrypt

sCrypt (https://scrypt.io) is a web3 development platform specialized in UTXO-blockchains like Bitcoin

No responses yet