forked from TrueCloudLab/neoneo-go
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
0079dfb695
commit
94d6b5466f
2 changed files with 104 additions and 73 deletions
|
@ -110,7 +110,9 @@ mode, after it ends the node can be started normally.
|
|||
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.
|
||||
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
|
||||
|
|
173
docs/compiler.md
173
docs/compiler.md
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue