2018-02-19 09:24:28 +00:00
# NEO-GO Compiler
The neo-go compiler compiles Go programs to bytecode that the NEO virtual machine can understand.
2018-02-28 19:45:54 +00:00
***NOTE:*** The neo-go compiler is under very active development and will be updated on a weekly basis. The API is likely going to change, ** *hence do not use this in production environments (mainnet)*** yet.
2018-02-19 09:24:28 +00:00
2018-02-27 09:04:24 +00:00
For help, questions and discussion feel free to join the [City Of Zion discord ](https://discordapp.com/invite/R8v48YA ) and hop in the #golang channel. Or reach out to me on twitter [@anthdm ](https://twitter.com/anthdm )
2018-02-24 09:10:45 +00:00
2018-02-19 09:24:28 +00:00
## Currently supported
2018-02-24 09:06:48 +00:00
### Go internals
2018-02-19 09:24:28 +00:00
- type checker
- multiple assigns
2018-02-25 12:26:56 +00:00
- global variables
- types int, string, byte and booleans
2018-02-19 09:24:28 +00:00
- struct types + method receives
- functions
2018-02-27 09:04:24 +00:00
- composite literals `[]int, []string, []byte`
2018-02-19 09:24:28 +00:00
- basic if statements
- binary expressions.
- return statements
2018-02-24 09:06:48 +00:00
- imports
### VM API (interop layer)
- storage
2018-02-25 12:26:56 +00:00
- runtime
2018-02-19 09:24:28 +00:00
## Not yet implemented
- for loops
- ranges
- builtins (append, len, ..)
2018-02-25 12:26:56 +00:00
- some parts of the interop layer (VM API)
2018-02-19 09:24:28 +00:00
## Not supported
Due to the limitations of the NEO virtual machine, features listed below will not be supported.
- channels
- goroutines
- multiple returns
2018-02-27 09:04:24 +00:00
## Smart contract examples
### Check if the invoker of the contract is the owning address
```Golang
package mycontract
import "github.com/CityOfZion/neo-go/pkg/vm/smartcontract/runtime"
var owner = []byte{0xaf, 0x12, 0xa8, 0x68, 0x7b, 0x14, 0x94, 0x8b, 0xc4, 0xa0, 0x08, 0x12, 0x8a, 0x55, 0x0a, 0x63, 0x69, 0x5b, 0xc1, 0xa5}
func Main() bool {
isOwner := runtime.CheckWitness(owner)
if isOwner {
runtime.Log("invoker is the owner")
return true
}
return false
}
```
### Simple token
```Golang
package mytoken
import (
2018-03-02 15:49:10 +00:00
"github.com/CityOfZion/neo-go/pkg/vm/smartcontract/runtime"
"github.com/CityOfZion/neo-go/pkg/vm/smartcontract/storage"
2018-02-27 09:04:24 +00:00
)
var owner = []byte{0xaf, 0x12, 0xa8, 0x68, 0x7b, 0x14, 0x94, 0x8b, 0xc4, 0xa0, 0x08, 0x12, 0x8a, 0x55, 0x0a, 0x63, 0x69, 0x5b, 0xc1, 0xa5}
type Token struct {
Name string
Symbol string
TotalSupply int
Owner []byte
}
func (t Token) AddToCirculation(amount int) bool {
ctx := storage.GetContext()
inCirc := storage.GetInt(ctx, "in_circ")
inCirc += amount
storage.Put(ctx, "in_circ", inCirc)
return true
}
func newToken() Token {
return Token{
Name: "your awesome NEO token",
Symbol: "YANT",
TotalSupply: 1000,
Owner: owner,
}
}
func Main(operation string, args []interface{}) bool {
token := newToken()
trigger := runtime.GetTrigger()
if trigger == runtime.Verification() {
isOwner := runtime.CheckWitness(token.Owner)
if isOwner {
return true
}
return false
}
if trigger == runtime.Application() {
if operation == "mintTokens" {
token.AddToCirculation(100)
}
}
return true
}
```
2018-02-24 09:06:48 +00:00
## How to report compiler bugs
2018-02-19 09:24:28 +00:00
1. Make a proper testcase (example testcases can be found in the tests folder)
2. Create an issue on Github
3. Make a PR with a reference to the created issue, containing the testcase that proves the bug
4. Either you fix the bug yourself or wait for patch that solves the problem
2018-02-24 09:06:48 +00:00
## Quick start
### Compile a smart contract
```
2018-02-24 09:19:15 +00:00
./bin/neo-go contract compile -i mycontract.go
2018-02-24 09:06:48 +00:00
```
By default the filename will be the name of your .go file with the .avm extension, the file will be located in the same directory where you called the command from. If you want another location for your compiled contract:
```
2018-02-24 09:19:15 +00:00
./bin/neo-go contract compile -i mycontract.go --out /Users/foo/bar/contract.avm
2018-02-24 09:06:48 +00:00
```
### Debugging your smart contract
You can dump the opcodes generated by the compiler with the following command:
```
2018-02-24 09:19:15 +00:00
./bin/neo-go contract opdump -i mycontract.go
2018-02-24 09:06:48 +00:00
```
This will result in something like this:
```
INDEX OPCODE DESC
0 0x52 OpPush2
1 0xc5 OpNewArray
2 0x6b OpToAltStack
3 0x 0 OpPush0
4 0x6c OpFromAltStack
5 0x76 OpDup
6 0x6b OpToAltStack
7 0x 0 OpPush0
8 0x52 OpPush2
9 0x7a OpRoll
10 0xc4 OpSetItem
2018-02-24 09:19:15 +00:00
```