2018-03-30 16:15:06 +00:00
|
|
|
# NEO-GO-VM
|
|
|
|
|
2020-06-25 07:36:21 +00:00
|
|
|
A cross platform virtual machine implementation for `NEF` compatible programs.
|
2018-03-30 16:15:06 +00:00
|
|
|
|
|
|
|
# Installation
|
|
|
|
|
2022-04-20 18:30:09 +00:00
|
|
|
VM is provided as a part of neo-go binary, so usual neo-go build instructions
|
2019-09-18 08:10:53 +00:00
|
|
|
are applicable.
|
2018-03-30 16:15:06 +00:00
|
|
|
|
2019-09-18 08:10:53 +00:00
|
|
|
# Running the VM
|
2018-03-30 16:15:06 +00:00
|
|
|
|
|
|
|
Start the virtual machine:
|
|
|
|
|
|
|
|
```
|
2019-09-18 08:10:53 +00:00
|
|
|
$ ./bin/neo-go vm
|
2018-03-30 16:15:06 +00:00
|
|
|
|
|
|
|
_ ____________ __________ _ ____ ___
|
|
|
|
/ | / / ____/ __ \ / ____/ __ \ | | / / |/ /
|
|
|
|
/ |/ / __/ / / / /_____/ / __/ / / /____| | / / /|_/ /
|
|
|
|
/ /| / /___/ /_/ /_____/ /_/ / /_/ /_____/ |/ / / / /
|
|
|
|
/_/ |_/_____/\____/ \____/\____/ |___/_/ /_/
|
|
|
|
|
|
|
|
|
|
|
|
NEO-GO-VM >
|
|
|
|
```
|
|
|
|
|
|
|
|
# Usage
|
|
|
|
|
|
|
|
```
|
|
|
|
_ ____________ __________ _ ____ ___
|
|
|
|
/ | / / ____/ __ \ / ____/ __ \ | | / / |/ /
|
|
|
|
/ |/ / __/ / / / /_____/ / __/ / / /____| | / / /|_/ /
|
|
|
|
/ /| / /___/ /_/ /_____/ /_/ / /_/ /_____/ |/ / / / /
|
|
|
|
/_/ |_/_____/\____/ \____/\____/ |___/_/ /_/
|
|
|
|
|
|
|
|
|
|
|
|
NEO-GO-VM > help
|
|
|
|
|
2019-09-18 08:10:53 +00:00
|
|
|
Commands:
|
2021-09-08 14:27:11 +00:00
|
|
|
aslot Show arguments slot contents
|
2021-09-06 15:40:41 +00:00
|
|
|
break Place a breakpoint
|
|
|
|
clear clear the screen
|
|
|
|
cont Continue execution of the current loaded script
|
|
|
|
estack Show evaluation stack contents
|
|
|
|
exit Exit the VM prompt
|
|
|
|
help display help
|
|
|
|
ip Show current instruction
|
|
|
|
istack Show invocation stack contents
|
|
|
|
loadbase64 Load a base64-encoded script string into the VM
|
|
|
|
loadgo Compile and load a Go file with the manifest into the VM
|
|
|
|
loadhex Load a hex-encoded script string into the VM
|
|
|
|
loadnef Load a NEF-consistent script into the VM
|
2021-09-08 14:27:11 +00:00
|
|
|
lslot Show local slot contents
|
2021-09-06 15:40:41 +00:00
|
|
|
ops Dump opcodes of the current loaded program
|
|
|
|
parse Parse provided argument and convert it into other possible formats
|
|
|
|
run Execute the current loaded script
|
2021-09-08 14:27:11 +00:00
|
|
|
sslot Show static slot contents
|
2021-09-06 15:40:41 +00:00
|
|
|
step Step (n) instruction in the program
|
|
|
|
stepinto Stepinto instruction to take in the debugger
|
|
|
|
stepout Stepout instruction to take in the debugger
|
|
|
|
stepover Stepover instruction to take in the debugger
|
2019-09-18 08:10:53 +00:00
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
You can get help for each command and its parameters adding `help` as a
|
|
|
|
parameter to the command:
|
|
|
|
|
|
|
|
```
|
|
|
|
NEO-GO-VM > step help
|
|
|
|
|
|
|
|
Usage: step [<n>]
|
|
|
|
<n> is optional parameter to specify number of instructions to run, example:
|
|
|
|
> step 10
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
## Loading in your script
|
2018-03-30 16:15:06 +00:00
|
|
|
|
2020-06-25 07:36:21 +00:00
|
|
|
To load an avm script in NEF format into the VM:
|
2018-03-30 16:15:06 +00:00
|
|
|
|
|
|
|
```
|
2020-06-25 07:36:21 +00:00
|
|
|
NEO-GO-VM > loadnef ../contract.nef
|
2018-04-04 19:41:19 +00:00
|
|
|
READY: loaded 36 instructions
|
2018-03-30 16:15:06 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
Run the script:
|
|
|
|
|
|
|
|
```
|
|
|
|
NEO-GO-VM > run
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"value": 1,
|
|
|
|
"type": "BigInteger"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
```
|
|
|
|
|
2018-04-04 19:41:19 +00:00
|
|
|
You can also directly compile and load `.go` files:
|
|
|
|
|
|
|
|
```
|
|
|
|
NEO-GO-VM > loadgo ../contract.go
|
|
|
|
READY: loaded 36 instructions
|
|
|
|
```
|
|
|
|
|
2021-09-06 15:40:41 +00:00
|
|
|
To make it even more complete, you can directly load hex or base64 strings into the VM:
|
2018-04-04 19:41:19 +00:00
|
|
|
|
|
|
|
```
|
2024-09-26 11:51:23 +00:00
|
|
|
NEO-GO-VM > loadhex 0c0c48656c6c6f20776f726c6421
|
|
|
|
READY: loaded 14 instructions
|
|
|
|
NEO-GO-VM 0 > run
|
2018-04-04 19:41:19 +00:00
|
|
|
[
|
|
|
|
{
|
2024-09-26 11:51:23 +00:00
|
|
|
"type": "ByteString",
|
|
|
|
"value": "SGVsbG8gd29ybGQh"
|
2018-04-04 19:41:19 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
```
|
|
|
|
|
2019-09-18 08:10:53 +00:00
|
|
|
## Running programs with arguments
|
2022-04-20 18:30:09 +00:00
|
|
|
You can invoke smart contracts with arguments. Take the following ***roll the dice*** smart contract as an example.
|
2018-04-10 09:45:31 +00:00
|
|
|
|
|
|
|
```
|
|
|
|
package rollthedice
|
|
|
|
|
2020-03-03 14:21:42 +00:00
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/interop/runtime"
|
2018-04-10 09:45:31 +00:00
|
|
|
|
2021-09-06 15:40:41 +00:00
|
|
|
func RollDice(number int) {
|
2018-04-10 09:45:31 +00:00
|
|
|
if number == 0 {
|
|
|
|
runtime.Log("you rolled 0, better luck next time!")
|
|
|
|
}
|
|
|
|
if number == 1 {
|
|
|
|
runtime.Log("you rolled 1, still better then 0!")
|
|
|
|
}
|
|
|
|
if number == 2 {
|
|
|
|
runtime.Log("you rolled 2, coming closer..")
|
|
|
|
}
|
|
|
|
if number == 3 {
|
|
|
|
runtime.Log("Sweet you rolled 3. This dice has only 3 sides o_O")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
To invoke this contract we need to specify both the method and the arguments.
|
|
|
|
|
2019-09-18 08:10:53 +00:00
|
|
|
The first parameter (called method or operation) is always of type
|
2022-04-20 18:30:09 +00:00
|
|
|
string. Notice that arguments can have different types. They can be inferred
|
|
|
|
automatically (please refer to the `run` command help), but if you need to
|
|
|
|
pass a parameter of a specific type you can specify it in `run`'s arguments:
|
2018-04-10 09:45:31 +00:00
|
|
|
|
|
|
|
```
|
|
|
|
NEO-GO-VM > run rollDice int:1
|
|
|
|
```
|
|
|
|
|
|
|
|
> The method is always of type string, hence we don't need to specify the type.
|
|
|
|
|
2019-09-18 08:10:53 +00:00
|
|
|
To add more than 1 argument:
|
2018-04-10 09:45:31 +00:00
|
|
|
|
|
|
|
```
|
|
|
|
NEO-GO-VM > run someMethod int:1 int:2 string:foo string:bar
|
|
|
|
```
|
|
|
|
|
2019-09-18 08:10:53 +00:00
|
|
|
Currently supported types:
|
|
|
|
- `bool (bool:false and bool:true)`
|
2018-04-10 09:45:31 +00:00
|
|
|
- `int (int:1 int:100)`
|
|
|
|
- `string (string:foo string:this is a string)`
|
|
|
|
|
2019-09-18 08:10:53 +00:00
|
|
|
## Debugging
|
2018-03-30 16:15:06 +00:00
|
|
|
The `neo-go-vm` provides a debugger to inspect your program in-depth.
|
|
|
|
|
2019-09-18 08:10:53 +00:00
|
|
|
|
|
|
|
### Stepping through the program
|
2018-03-30 16:15:06 +00:00
|
|
|
Step 4 instructions.
|
|
|
|
|
|
|
|
```
|
|
|
|
NEO-GO-VM > step 4
|
2019-09-18 08:10:53 +00:00
|
|
|
at breakpoint 3 (DUPFROMALTSTACK)
|
|
|
|
NEO-GO-VM 3 >
|
2018-03-30 16:15:06 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
Using just `step` will execute 1 instruction at a time.
|
|
|
|
|
|
|
|
```
|
2019-09-18 08:10:53 +00:00
|
|
|
NEO-GO-VM 3 > step
|
|
|
|
at breakpoint 4 (PUSH0)
|
|
|
|
NEO-GO-VM 4 >
|
2018-03-30 16:15:06 +00:00
|
|
|
```
|
|
|
|
|
2019-09-18 08:10:53 +00:00
|
|
|
### Breakpoints
|
|
|
|
|
2018-03-30 16:15:06 +00:00
|
|
|
To place breakpoints:
|
|
|
|
|
|
|
|
```
|
|
|
|
NEO-GO-VM > break 10
|
|
|
|
breakpoint added at instruction 10
|
2018-04-04 19:41:19 +00:00
|
|
|
NEO-GO-VM > cont
|
2019-09-18 08:10:53 +00:00
|
|
|
at breakpoint 10 (SETITEM)
|
2018-04-04 19:41:19 +00:00
|
|
|
NEO-GO-VM 10 > cont
|
2018-03-30 16:15:06 +00:00
|
|
|
```
|
|
|
|
|
2019-09-18 08:10:53 +00:00
|
|
|
## Inspecting stack
|
|
|
|
|
2018-04-04 19:41:19 +00:00
|
|
|
Inspecting the evaluation stack:
|
2018-03-30 16:15:06 +00:00
|
|
|
|
|
|
|
```
|
2018-04-04 19:41:19 +00:00
|
|
|
NEO-GO-VM > estack
|
2018-03-30 16:15:06 +00:00
|
|
|
[
|
|
|
|
{
|
|
|
|
"value": [
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
null
|
|
|
|
],
|
|
|
|
"type": "Array"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"value": 4,
|
|
|
|
"type": "BigInteger"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
```
|
|
|
|
|
2021-09-06 15:40:41 +00:00
|
|
|
There is one more stack that you can inspect.
|
2018-04-04 19:41:19 +00:00
|
|
|
- `istack` invocation stack
|
|
|
|
|
2021-09-08 14:27:11 +00:00
|
|
|
There are slots that you can inspect.
|
|
|
|
- `aslot` dumps arguments slot contents.
|
|
|
|
- `lslot` dumps local slot contents.
|
|
|
|
- `sslot` dumps static slot contents.
|
|
|
|
|