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`
|
||||
- `--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
|
||||
[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.
|
||||
|
||||
## Currently supported
|
||||
## Language compatibility
|
||||
|
||||
### Go internals
|
||||
- type checking
|
||||
- multiple assignments
|
||||
- global variables
|
||||
- types int, string, byte and booleans
|
||||
- struct types + method receives
|
||||
- functions
|
||||
- composite literals `[]int, []string, []byte`
|
||||
- basic if statements
|
||||
- binary expressions
|
||||
- return statements
|
||||
- for loops
|
||||
- imports
|
||||
The compiler is mostly compatible with regular Go language specification, but
|
||||
there are some important deviations that you need to be aware of that make it
|
||||
a dialect of Go rather than a complete port of the language:
|
||||
* `make()` ane `new()` are not supported, most of the time you can substitute
|
||||
them with composite literals
|
||||
* there is no real distinction between different integer types, all of them
|
||||
work as big.Int in Go with a limit of 256 bit in width, so you can use
|
||||
`int` for just about anything. This is the way integers work in Neo VM and
|
||||
adding proper Go types emulation is considered to be too costly.
|
||||
* goroutines, channels and garbage collection are not supported and will
|
||||
never be because emulating that aspects of Go runtime on top of Neo VM is
|
||||
close to impossible
|
||||
* 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
|
||||
- len
|
||||
- append
|
||||
|
||||
### VM API (interop layer)
|
||||
## VM API (interop layer)
|
||||
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.
|
||||
|
||||
#### Standard NEO Smart Contract API
|
||||
- account
|
||||
- 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
|
||||
functions) into NEO VM instructions. [Refer to
|
||||
pkg.go.dev](https://pkg.go.dev/github.com/nspcc-dev/neo-go/pkg/interop)
|
||||
for full API documentation. In general it provides the same level of
|
||||
functionality as Neo .net Framework library.
|
||||
|
||||
## Quick start
|
||||
|
||||
### Compile a smart contract
|
||||
### Compiling
|
||||
|
||||
```
|
||||
./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
|
||||
```
|
||||
|
||||
### Debugging your smart contract
|
||||
### Debugging
|
||||
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:
|
||||
|
||||
```
|
||||
INDEX OPCODE DESC
|
||||
0 0x54 PUSH4
|
||||
1 0xc5 NEWARRAY
|
||||
2 0x6b TOALTSTACK
|
||||
3 0x1 PUSHBYTES1
|
||||
3 0x2a *
|
||||
5 0x6a DUPFROMALTSTACK
|
||||
6 0x0 PUSH0
|
||||
7 0x52 PUSH2
|
||||
8 0x7a ROLL
|
||||
9 0xc4 SETITEM
|
||||
10 0x6a DUPFROMALTSTACK
|
||||
11 0x0 PUSH0
|
||||
12 0xc3 PICKITEM
|
||||
13 0x5a PUSH10
|
||||
14 0xa2 GTE
|
||||
15 0x64 JMPIFNOT
|
||||
16 0x7 7
|
||||
16 0x0 0
|
||||
18 0x51 PUSH1
|
||||
19 0x6c FROMALTSTACK
|
||||
20 0x75 DROP
|
||||
21 0x66 RET
|
||||
22 0x0 PUSH0
|
||||
23 0x6c FROMALTSTACK
|
||||
24 0x75 DROP
|
||||
25 0x66 RET
|
||||
INDEX OPCODE PARAMETER
|
||||
0 INITSLOT 0500 ("\x05\x00") <<
|
||||
3 PUSH0
|
||||
4 REVERSEN
|
||||
5 SYSCALL "\x9a\x1f\x19J"
|
||||
10 NOP
|
||||
11 STLOC0
|
||||
12 LDLOC0
|
||||
13 PUSH1
|
||||
14 REVERSEN
|
||||
15 PUSH1
|
||||
16 PACK
|
||||
17 SYSCALL "\x05\a\x92\x16"
|
||||
22 NOP
|
||||
23 PUSH0
|
||||
24 REVERSEN
|
||||
25 SYSCALL "E\x99Z\\"
|
||||
30 NOP
|
||||
31 STLOC1
|
||||
32 LDLOC1
|
||||
33 PUSH1
|
||||
34 REVERSEN
|
||||
35 PUSH1
|
||||
36 PACK
|
||||
37 SYSCALL "\x05\a\x92\x16"
|
||||
42 NOP
|
||||
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
|
||||
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:
|
||||
#### Neo Smart Contract Debugger support
|
||||
|
||||
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:
|
||||
```
|
||||
{
|
||||
"state": "HALT, BREAK",
|
||||
"gas_consumed": "0.006",
|
||||
"Stack": [
|
||||
{
|
||||
"type": "Integer",
|
||||
"value": "9"
|
||||
}
|
||||
]
|
||||
}
|
||||
This file can then be used by debugger and set up to work just like for any
|
||||
other supported language.
|
||||
|
||||
### Deploying
|
||||
|
||||
Deploying a contract to blockchain with neo-go requires a configuration file
|
||||
with contract's metadata in YAML format, like the following:
|
||||
|
||||
```
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in a new issue