From 94d6b5466f40e3a14195d39d056d78de9b1551d2 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Tue, 19 May 2020 00:17:05 +0300 Subject: [PATCH] docs: update compiler.md, bring it up to date And add one more reference to it into the main README. --- README.md | 4 +- docs/compiler.md | 173 +++++++++++++++++++++++++++-------------------- 2 files changed, 104 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index aa1aa2629..29e761596 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/docs/compiler.md b/docs/compiler.md index a7e59652c..593e5cfa2 100644 --- a/docs/compiler.md +++ b/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