ethers.js/docs/v5/cli/asm/README.md
2020-06-09 23:56:58 -04:00

206 lines
6.7 KiB
Markdown

-----
Documentation: [html](https://docs-beta.ethers.io/)
-----
Assembler
=========
Help
----
```
Usage:
ethers-asm [ FILENAME ] [ OPTIONS ]
OPTIONS
--define KEY=VALUE provide assembler defines
--disassemble Disassemble input bytecode
--ignore-warnings Ignore warnings
--pic generate position independent code
--target LABEL output LABEL bytecode (default: _)
OTHER OPTIONS
--debug Show stack traces for errors
--help Show this usage and exit
--version Show this version and exit
```
Example Input Files
-------------------
```
; SimpleStore (uint)
; Set the inital value of 42
sstore(0, 42)
; Init code to deploy myContract
codecopy(0, $myContract, #myContract)
return(0, #myContract)
@myContract {
; Non-payable
jumpi($error, callvalue)
; Get the Sighash
shr({{= 256 - 32 }}, calldataload(0))
; getValue()
dup1
{{= sighash("getValue()") }}
jumpi($getValue, eq)
; setValue(uint)
dup1
{{= sighash("setValue(uint)") }}
jumpi($setValue, eq)
; No matching signature
@error:
revert(0, 0)
@getValue:
mstore(0, sload(0))
return (0, 32)
@setValue:
; Make sure we have exactly a uint
jumpi($error, iszero(eq(calldatasize, 36)))
; Store the value
sstore(0, calldataload(4))
return (0, 0)
; There is no *need* for the PUSH32, it just makes
; decompiled code look nicer
@checksum[
{{= (defines.checksum ? concat([
Opcode.from("PUSH32"),
id(myContract.source)
]): "0x")
}}
]
}
```
```
0x602a6000556044601160003960446000f334601e5760003560e01c8063209652
0x5514602457806355241077146030575b60006000fd5b60005460005260206000
0xf35b6024361415601e5760043560005560006000f3
```
#### Note: Bytecode File Syntax
A bin file may be made up of multiple blocks of bytecode, each may optionally begin with a `0x` prefix, all of which **must** be of even length (since bytes are required, with 2 nibbles per byte)
All whitespace is ignored.
Assembler Examples
------------------
```
/home/ethers> ethers-asm SimpleStore.asm
0x602a6000556044601160003960446000f334601e5760003560e01c80632096525514602457806355241077146030575b60006000fd5b60005460005260206000f35b6024361415601e5760043560005560006000f3
# Piping in ASM source code
/home/ethers> cat SimpleStore.asm | ethers-asm
# Same as above
# Setting a define which the ASM file checks and adds a checksum
/home/ethers> ethers-asm --define checksum SimpleStore.asm
0x602a6000556065601160003960656000f334601e5760003560e01c80632096525514602457806355241077146030575b60006000fd5b60005460005260206000f35b6024361415601e5760043560005560006000f37f10358310d664c9aeb4bf4ce7a10a6a03176bd23194c8ccbd3160a6dac90774d6
```
### Options
#### **--define KEY=VALUE** *or* **--define FLAG**
This allows key/value pairs (where the value is a string) and flags (which the value is `true`) to be passed along to the assembler, which can be accessed in [Scripting Blocks](/v5/api/other/assembly/dialect/#asm-dialect-scripting), such as `{{= defined.someKey }}`.
#### **--ignore-warnings**
By default any warning will be treated like an error. This enabled by-passing warnings.
#### **--pic**
When a program is assembled, the labels are usually given as an absolute byte position, which can be jumped to for loops and control flow. This means that a program must be installed at a specific location.
Byt specifying the **Position Independent Code** flag, code will be generated in a way such that all offsets are relative, allowing the program to be moved without any impact to its logic.
This does incur an additional gsas cost of 8 gas per offset access though.
#### **--target LABEL**
All programs have a root scope named `_` which is by default assembled. This option allows another labelled target (either a [Scopes](/v5/api/other/assembly/dialect/#asm-dialect-scope) or a [Data Segment](/v5/api/other/assembly/dialect/#asm-dialect-datasegment) to be assembled instead. The entire program is still assembled per usual, so this only impacts which part of the program is output.
Disassembler Examples
---------------------
```
/home/ethers> ethers-asm --disassemble SimpleStore.bin
0000 : 0x2a ; #1
0002 : 0x00 ; #1
0004 : SSTORE
0005 : 0x44 ; #1
0007 : 0x11 ; #1
0009 : 0x00 ; #1
000b : CODECOPY
000c : 0x44 ; #1
000e : 0x00 ; #1
0010 : RETURN
0011 : CALLVALUE
0012 : 0x1e ; #1
0014 : JUMPI
0015 : 0x00 ; #1
0017 : CALLDATALOAD
0018 : 0xe0 ; #1
001a : SHR
001b : DUP1
001c : 0x20965255 ; #4
0021 : EQ
0022 : 0x24 ; #1
0024 : JUMPI
0025 : DUP1
0026 : 0x55241077 ; #4
002b : EQ
002c : 0x30 ; #1
002e : JUMPI
002f*: JUMPDEST
0030 : 0x00 ; #1
0032 : 0x00 ; #1
0034 : REVERT
0035*: JUMPDEST
0036 : 0x00 ; #1
0038 : SLOAD
0039 : 0x00 ; #1
003b : MSTORE
003c : 0x20 ; #1
003e : 0x00 ; #1
0040 : RETURN
0041*: JUMPDEST
0042 : 0x24 ; #1
0044 : CALLDATASIZE
0045 : EQ
0046 : ISZERO
0047 : 0x1e ; #1
0049 : JUMPI
004a : 0x04 ; #1
004c : CALLDATALOAD
004d : 0x00 ; #1
004f : SSTORE
0050 : 0x00 ; #1
0052 : 0x00 ; #1
0054 : RETURN
/home/ethers> cat SimpleStore.bin | ethers-asm --disassemble
# Same as above
```