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:
Roman Khimov 2020-05-19 00:17:05 +03:00
parent 77b92de074
commit f8093e415e
2 changed files with 160 additions and 100 deletions

View file

@ -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.

View file

@ -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