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 0079dfb695
commit 94d6b5466f
2 changed files with 104 additions and 73 deletions

View file

@ -2,66 +2,39 @@
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
* global variables can't be changed in functions (#638)
* it's not possible to rename imported interop packages, they won't work this
way (#397, #913)
* nested selectors are not yet supported (#957)
* using value variable in range-based loops is not yet supported (#958)
### 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 +46,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:
```
@ -112,33 +85,89 @@ INDEX OPCODE DESC
25 0x66 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