docs: update compiler.md, bring it up to date
And add one more reference to it into the main README.
This commit is contained in:
parent
77b92de074
commit
f8093e415e
2 changed files with 160 additions and 100 deletions
11
README.md
11
README.md
|
@ -92,7 +92,16 @@ Available network flags:
|
||||||
- `--privnet, -p`
|
- `--privnet, -p`
|
||||||
- `--testnet, -t`
|
- `--testnet, -t`
|
||||||
|
|
||||||
#Developer notes
|
## Smart contract development
|
||||||
|
|
||||||
|
Please refer to [neo-go smart contract development
|
||||||
|
workshop](https://github.com/nspcc-dev/neo-go-sc-wrkshp) that shows some
|
||||||
|
simple contracts that can be compiled/deployed/run using neo-go compiler, SDK
|
||||||
|
and private network. For details on how Go code is translated to Neo VM
|
||||||
|
bytecode and what you can and can not do in smart contract please refer to the
|
||||||
|
[compiler documentation](docs/compiler.md).
|
||||||
|
|
||||||
|
# Developer notes
|
||||||
Nodes have such features as [Prometheus](https://prometheus.io/docs/guides/go-application) and
|
Nodes have such features as [Prometheus](https://prometheus.io/docs/guides/go-application) and
|
||||||
[Pprof](https://golang.org/pkg/net/http/pprof/) in order to have additional information about them for debugging.
|
[Pprof](https://golang.org/pkg/net/http/pprof/) in order to have additional information about them for debugging.
|
||||||
|
|
||||||
|
|
249
docs/compiler.md
249
docs/compiler.md
|
@ -2,66 +2,36 @@
|
||||||
|
|
||||||
The neo-go compiler compiles Go programs to bytecode that the NEO virtual machine can understand.
|
The neo-go compiler compiles Go programs to bytecode that the NEO virtual machine can understand.
|
||||||
|
|
||||||
## Currently supported
|
## Language compatibility
|
||||||
|
|
||||||
### Go internals
|
The compiler is mostly compatible with regular Go language specification, but
|
||||||
- type checking
|
there are some important deviations that you need to be aware of that make it
|
||||||
- multiple assignments
|
a dialect of Go rather than a complete port of the language:
|
||||||
- global variables
|
* `make()` ane `new()` are not supported, most of the time you can substitute
|
||||||
- types int, string, byte and booleans
|
them with composite literals
|
||||||
- struct types + method receives
|
* there is no real distinction between different integer types, all of them
|
||||||
- functions
|
work as big.Int in Go with a limit of 256 bit in width, so you can use
|
||||||
- composite literals `[]int, []string, []byte`
|
`int` for just about anything. This is the way integers work in Neo VM and
|
||||||
- basic if statements
|
adding proper Go types emulation is considered to be too costly.
|
||||||
- binary expressions
|
* goroutines, channels and garbage collection are not supported and will
|
||||||
- return statements
|
never be because emulating that aspects of Go runtime on top of Neo VM is
|
||||||
- for loops
|
close to impossible
|
||||||
- imports
|
* even though `panic()` is supported, `recover()` is not, `panic` shuts the
|
||||||
|
VM down
|
||||||
|
* lambdas are not supported (#939)
|
||||||
|
* it's not possible to rename imported interop packages, they won't work this
|
||||||
|
way (#397, #913)
|
||||||
|
|
||||||
### Go builtins
|
## VM API (interop layer)
|
||||||
- len
|
|
||||||
- append
|
|
||||||
|
|
||||||
### VM API (interop layer)
|
|
||||||
Compiler translates interop function calls into NEO VM syscalls or (for custom
|
Compiler translates interop function calls into NEO VM syscalls or (for custom
|
||||||
functions) into NEO VM instructions. [Refer to GoDoc](https://godoc.org/github.com/nspcc-dev/neo-go/pkg/interop) for full API documentation.
|
functions) into NEO VM instructions. [Refer to
|
||||||
|
pkg.go.dev](https://pkg.go.dev/github.com/nspcc-dev/neo-go/pkg/interop)
|
||||||
#### Standard NEO Smart Contract API
|
for full API documentation. In general it provides the same level of
|
||||||
- account
|
functionality as Neo .net Framework library.
|
||||||
- asset
|
|
||||||
- attribute
|
|
||||||
- block
|
|
||||||
- blockchain
|
|
||||||
- contract
|
|
||||||
- engine
|
|
||||||
- header
|
|
||||||
- input
|
|
||||||
- iterator
|
|
||||||
- output
|
|
||||||
- runtime
|
|
||||||
- storage
|
|
||||||
- transaction
|
|
||||||
|
|
||||||
#### Custom VM utility helper functions
|
|
||||||
- crypto:
|
|
||||||
- `SHA1`
|
|
||||||
- `SHA256`
|
|
||||||
- `Hash256`
|
|
||||||
- `Hash160`
|
|
||||||
- enumerator
|
|
||||||
- util:
|
|
||||||
- `Equals` (to emit `EQUALS` opcode, not needed usually)
|
|
||||||
- `FromAddress(address string) []byte`
|
|
||||||
|
|
||||||
## Not supported
|
|
||||||
Due to the limitations of the NEO virtual machine, features listed below will not be supported.
|
|
||||||
- channels
|
|
||||||
- goroutines
|
|
||||||
- returning multiple values from functions
|
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
|
|
||||||
### Compile a smart contract
|
### Compiling
|
||||||
|
|
||||||
```
|
```
|
||||||
./bin/neo-go contract compile -i mycontract.go
|
./bin/neo-go contract compile -i mycontract.go
|
||||||
|
@ -73,7 +43,7 @@ By default the filename will be the name of your .go file with the .avm extensio
|
||||||
./bin/neo-go contract compile -i mycontract.go --out /Users/foo/bar/contract.avm
|
./bin/neo-go contract compile -i mycontract.go --out /Users/foo/bar/contract.avm
|
||||||
```
|
```
|
||||||
|
|
||||||
### Debugging your smart contract
|
### Debugging
|
||||||
You can dump the opcodes generated by the compiler with the following command:
|
You can dump the opcodes generated by the compiler with the following command:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -83,62 +53,143 @@ You can dump the opcodes generated by the compiler with the following command:
|
||||||
This will result in something like this:
|
This will result in something like this:
|
||||||
|
|
||||||
```
|
```
|
||||||
INDEX OPCODE DESC
|
INDEX OPCODE PARAMETER
|
||||||
0 0x54 PUSH4
|
0 INITSLOT 0500 ("\x05\x00") <<
|
||||||
1 0xc5 NEWARRAY
|
3 PUSH0
|
||||||
2 0x6b TOALTSTACK
|
4 REVERSEN
|
||||||
3 0x1 PUSHBYTES1
|
5 SYSCALL "\x9a\x1f\x19J"
|
||||||
3 0x2a *
|
10 NOP
|
||||||
5 0x6a DUPFROMALTSTACK
|
11 STLOC0
|
||||||
6 0x0 PUSH0
|
12 LDLOC0
|
||||||
7 0x52 PUSH2
|
13 PUSH1
|
||||||
8 0x7a ROLL
|
14 REVERSEN
|
||||||
9 0xc4 SETITEM
|
15 PUSH1
|
||||||
10 0x6a DUPFROMALTSTACK
|
16 PACK
|
||||||
11 0x0 PUSH0
|
17 SYSCALL "\x05\a\x92\x16"
|
||||||
12 0xc3 PICKITEM
|
22 NOP
|
||||||
13 0x5a PUSH10
|
23 PUSH0
|
||||||
14 0xa2 GTE
|
24 REVERSEN
|
||||||
15 0x64 JMPIFNOT
|
25 SYSCALL "E\x99Z\\"
|
||||||
16 0x7 7
|
30 NOP
|
||||||
16 0x0 0
|
31 STLOC1
|
||||||
18 0x51 PUSH1
|
32 LDLOC1
|
||||||
19 0x6c FROMALTSTACK
|
33 PUSH1
|
||||||
20 0x75 DROP
|
34 REVERSEN
|
||||||
21 0x66 RET
|
35 PUSH1
|
||||||
22 0x0 PUSH0
|
36 PACK
|
||||||
23 0x6c FROMALTSTACK
|
37 SYSCALL "\x05\a\x92\x16"
|
||||||
24 0x75 DROP
|
42 NOP
|
||||||
25 0x66 RET
|
43 PUSH0
|
||||||
|
44 REVERSEN
|
||||||
|
45 SYSCALL "\x87\xc3\xd2d"
|
||||||
|
50 NOP
|
||||||
|
51 STLOC2
|
||||||
|
52 LDLOC2
|
||||||
|
53 PUSH1
|
||||||
|
54 REVERSEN
|
||||||
|
55 PUSH1
|
||||||
|
56 PACK
|
||||||
|
57 SYSCALL "\x05\a\x92\x16"
|
||||||
|
62 NOP
|
||||||
|
63 PUSH0
|
||||||
|
64 REVERSEN
|
||||||
|
65 SYSCALL "\x1dY\xe1\x19"
|
||||||
|
70 NOP
|
||||||
|
71 STLOC3
|
||||||
|
72 LDLOC3
|
||||||
|
73 PUSH1
|
||||||
|
74 REVERSEN
|
||||||
|
75 PUSH1
|
||||||
|
76 PACK
|
||||||
|
77 SYSCALL "\x05\a\x92\x16"
|
||||||
|
82 NOP
|
||||||
|
83 PUSH1
|
||||||
|
84 RET
|
||||||
```
|
```
|
||||||
|
|
||||||
### Test invoke a compiled contract
|
#### Neo Smart Contract Debugger support
|
||||||
You can simulate a test invocation of your compiled contract by the VM, to know the total gas cost for example, with the following command:
|
|
||||||
|
It's possible to debug contracts written in Go using standard [Neo Smart
|
||||||
|
Contract Debugger](https://github.com/neo-project/neo-debugger/) which is a
|
||||||
|
part of [Neo Blockchain
|
||||||
|
Toolkit](https://github.com/neo-project/neo-blockchain-toolkit/). To do that
|
||||||
|
you need to generate debug information using `--debug` option, like this:
|
||||||
|
|
||||||
```
|
```
|
||||||
./bin/neo-go contract testinvoke -i mycompiledcontract.avm
|
$ ./bin/neo-go contract compile -i contract.go -o contract.avm --debug contract.debug.json
|
||||||
```
|
```
|
||||||
|
|
||||||
Will output something like:
|
This file can then be used by debugger and set up to work just like for any
|
||||||
```
|
other supported language.
|
||||||
{
|
|
||||||
"state": "HALT, BREAK",
|
### Deploying
|
||||||
"gas_consumed": "0.006",
|
|
||||||
"Stack": [
|
Deploying a contract to blockchain with neo-go requires a configuration file
|
||||||
{
|
with contract's metadata in YAML format, like the following:
|
||||||
"type": "Integer",
|
|
||||||
"value": "9"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
project:
|
||||||
|
author: Jack Smith
|
||||||
|
email: jack@example.com
|
||||||
|
version: 1.0
|
||||||
|
name: 'Smart contract'
|
||||||
|
description: 'Even smarter than Jack himself'
|
||||||
|
hasstorage: true
|
||||||
|
hasdynamicinvocation: false
|
||||||
|
ispayable: false
|
||||||
|
returntype: ByteArray
|
||||||
|
parameters: ['String', 'Array']
|
||||||
|
```
|
||||||
|
|
||||||
At the moment this is implemented via RPC call to the remote server.
|
It's passed to the `deploy` command via `-c` option:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./bin/neo-go contract deploy -i contract.avm -c contract.yml -e http://localhost:20331 -w wallet.json -g 0.001
|
||||||
|
```
|
||||||
|
|
||||||
|
Deployment works via an RPC server, an address of which is passed via `-e`
|
||||||
|
option and should be signed using a wallet from `-w` option. More details can
|
||||||
|
be found in `deploy` command help.
|
||||||
|
|
||||||
|
#### Neo Express support
|
||||||
|
|
||||||
|
It's possible to deploy contracts written in Go using [Neo
|
||||||
|
Express](https://github.com/neo-project/neo-express) which is a part of [Neo
|
||||||
|
Blockchain
|
||||||
|
Toolkit](https://github.com/neo-project/neo-blockchain-toolkit/). To do that
|
||||||
|
you need to generate a different metadata file using YAML written for
|
||||||
|
deployment with neo-go. It's done in the same step with compilation via
|
||||||
|
`--config` input parameter and `--abi` output parameter, combined with debug
|
||||||
|
support the command line will look like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./bin/neo-go contract compile -i contract.go --config contract.yml -o contract.avm --debug contract.debug.json --abi contract.abi.json
|
||||||
|
```
|
||||||
|
|
||||||
|
This file can then be used by toolkit to deploy contract the same way
|
||||||
|
contracts in other languagues are deployed.
|
||||||
|
|
||||||
|
|
||||||
|
### Invoking
|
||||||
|
You can import your contract into the standalone VM and run it there (see [VM
|
||||||
|
documentation](vm.md) for more info), but that only works for simple contracts
|
||||||
|
that don't use blockchain a lot. For more real contracts you need to deploy
|
||||||
|
them first and then do test invocations and regular invocations with `contract
|
||||||
|
testinvokefunction` and `contract invokefunction` commands (or their variants,
|
||||||
|
see `contract` command help for more details. They all work via RPC, so it's a
|
||||||
|
mandatory parameter.
|
||||||
|
|
||||||
|
Example call (contract `f84d6a337fbc3d3a201d41da99e86b479e7a2554` with method
|
||||||
|
`balanceOf` and method's parameter `AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y` using
|
||||||
|
given RPC server and wallet and paying 0.00001 GAS for this transaction):
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./bin/neo-go contract invokefunction -e http://localhost:20331 -w my_wallet.json -g 0.00001 f84d6a337fbc3d3a201d41da99e86b479e7a2554 balanceOf AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y
|
||||||
|
```
|
||||||
|
|
||||||
## Smart contract examples
|
## Smart contract examples
|
||||||
|
|
||||||
Some examples are provided in the [examples directory](examples).
|
Some examples are provided in the [examples directory](../examples).
|
||||||
|
|
||||||
### Check if the invoker of the contract is the owning address
|
### Check if the invoker of the contract is the owning address
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue