Skip to content

Commit

Permalink
assembly
Browse files Browse the repository at this point in the history
  • Loading branch information
xhliu committed Sep 24, 2020
1 parent 15778b7 commit 60b4862
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 0 deletions.
60 changes: 60 additions & 0 deletions asm.rst
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 language 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. A 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.
6 changes: 6 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ sCrypt is designed to facilitate writing smart contract running on chain.
rabin
multipartyhashpuzzles

.. toctree::
:maxdepth: 1
:caption: Advanced

asm

Contact
-------
`Slack <https://join.slack.com/t/scryptworkspace/shared_invite/enQtNzQ1OTMyNDk1ODU3LTJmYjE5MGNmNDZhYmYxZWM4ZGY2MTczM2NiNTIxYmFhNTVjNjE5MGYwY2UwNDYxMTQyNGU2NmFkNTY5MmI1MWM>`_
Expand Down

0 comments on commit 60b4862

Please sign in to comment.