-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
66 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
=============== | ||
Inline Assembly | ||
=============== | ||
Script is a low-level language and acts as assembly for the `Bitcoin Virtual Machine <https://medium.com/@xiaohuiliu/introduction-to-bitcoin-smart-contracts-9c0ea37dc757>`_. | ||
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 <https://powping.com/posts/95e53a7305ad9d333d072575946d0cfd0d6321f40af40f9c66c70955ada94e58>`_) 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. | ||
|
||
.. code-block:: solidity | ||
// 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. | ||
|
||
.. code-block:: solidity | ||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters