github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/docs/compiler.md (about)

     1  # NeoGo smart contract compiler
     2  
     3  The neo-go compiler compiles Go programs to a bytecode that the Neo virtual machine can understand.
     4  
     5  ## Language compatibility
     6  
     7  The compiler is mostly compatible with regular Go language specification. However,
     8  there are some important deviations that you need to be aware of that make it
     9  a dialect of Go rather than a complete port of the language:
    10   * `new()` is not supported, most of the time you can substitute structs with composite literals
    11   * `make()` is supported for maps and slices with elements of basic types
    12   * `copy()` is supported only for byte slices because of the underlying `MEMCPY` opcode
    13   * pointers are supported only for struct literals, one can't take an address
    14     of an arbitrary variable
    15   * there is no real distinction between different integer types, all of them
    16     work as big.Int in Go with a limit of 256 bit in width; so you can use
    17     `int` for just about anything. This is the way integers work in Neo VM and
    18     adding proper Go types emulation is considered to be too costly.
    19   * goroutines, channels and garbage collection are not supported and will
    20     never be because emulating that aspects of Go runtime on top of Neo VM is
    21     close to impossible
    22   * `defer` and `recover` are supported except for the cases where panic occurs in
    23     `return` statement because this complicates implementation and imposes runtime
    24      overhead for all contracts. This can easily be mitigated by first storing values
    25      in variables and returning the result.
    26   * lambdas are supported, but closures are not.
    27   * maps are supported, but valid map keys are booleans, integers and strings with length <= 64
    28   * converting value to interface type doesn't change the underlying type,
    29     original value will always be used, therefore it never panics and always "succeeds";
    30     it's up to the programmer whether it's a correct use of a value
    31   * type assertion with two return values is not supported; single return value (of the desired type)
    32     is supported; type assertion panics if value can't be asserted to the desired type, therefore
    33     it's up to the programmer whether assert can be performed successfully.
    34   * type aliases including the built-in `any` alias are supported.
    35   * generics are not supported, but eventually will be (at least, partially), ref. https://github.com/nspcc-dev/neo-go/issues/2376.
    36  
    37  ## VM API (interop layer)
    38  Compiler translates interop function calls into Neo VM syscalls or (for custom
    39  functions) into Neo VM instructions. [Refer to
    40  pkg.go.dev](https://pkg.go.dev/github.com/nspcc-dev/neo-go/pkg/interop)
    41  for full API documentation. In general it provides the same level of
    42  functionality as Neo .net Framework library.
    43  
    44  Compiler provides some helpful builtins in `util`, `convert` and `math` packages.
    45  Refer to them for detailed documentation. 
    46  
    47  `_deploy()` function has a special meaning and is executed when contract is deployed.
    48  It should return no value and accept two arguments: the first one is `data` containing
    49  all values `deploy` is aware of and able to make use of; the second one is a bool
    50  argument which will be true on contract update.
    51  `_deploy()` functions are called for every imported package in the same order as `init()`. 
    52  
    53  ## Quick start
    54  
    55  ### Go setup
    56  
    57  The compiler uses Go parser internally and depends on regular Go compiler
    58  presence, so make sure you have it installed and set up. On some distributions
    59  this requires you to set proper `GOROOT` environment variable, like
    60  ```
    61  export GOROOT=/usr/lib64/go/1.15
    62  ```
    63  
    64  The best way to create a new contract is to use `contract init` command. This will
    65  create an example source file, a config file and `go.mod` with `github.com/nspcc-dev/neo-go/pkg/interop` dependency.
    66  ```
    67  $ ./bin/neo-go contract init --name MyAwesomeContract
    68  $ cd MyAwesomeContract
    69  ```
    70  
    71  You'll also need to download dependency modules for your contract like this (in the
    72  directory containing contract package):
    73  ```
    74  $ go mod tidy
    75  ```
    76  
    77  ### Compiling
    78  
    79  ```
    80  ./bin/neo-go contract compile -i contract.go
    81  ```
    82  
    83  By default, the filename will be the name of your .go file with the .nef
    84  extension, the file will be located in the same directory with your Go contract.
    85  Along with the compiled contract and if the contract configuration file
    86  `contract.yml` exist, the following files will be generated:
    87  * smart-contract manifest file (`contract.manifest.json`) that is needed to deploy
    88    the contract to the network
    89  * bindings configuration file (`contract.bindings.yml`) that is needed to generate
    90    code-based or RPC contract bindings
    91  All of them will be located in the same directory with your Go contract.
    92  
    93  If you want another location for your compiled contract:
    94  
    95  ```
    96  ./bin/neo-go contract compile -i contract.go --out /Users/foo/bar/contract.nef
    97  ```
    98  
    99  If your contract is split across multiple files, you must provide a path
   100  to the directory where package files are contained instead of a single Go file
   101  (`out.nef` will be used as the default output file in this case):
   102  ```
   103  ./bin/neo-go contract compile -i ./path/to/contract
   104  ```
   105  
   106  ### Debugging
   107  You can dump the opcodes generated by the compiler with the following command:
   108  
   109  ```
   110  ./bin/neo-go contract inspect -i contract.go -c
   111  ```
   112  
   113  This will result in something like this:
   114  
   115  ```
   116  INDEX    OPCODE        PARAMETER                                                                                                                              
   117  0        INITSLOT      4 local, 2 arg                                                                                                                         <<
   118  3        LDARG1                                                                                                                                               
   119  4        NOT                                                                                                                                                  
   120  5        JMPIFNOT_L    151 (146/92000000)                                                                                                                     
   121  10       SYSCALL       System.Storage.GetContext (9bf667ce)                                                                                                   
   122  15       NOP                                                                                                                                                  
   123  16       STLOC0                                                                                                                                               
   124  17       PUSHDATA1     53746f72616765206b6579206e6f7420796574207365742e2053657474696e6720746f2030 ("Storage key not yet set. Setting to 0")                   
   125  56       CONVERT       Buffer (30)                                                                                                                            
   126  58       PUSH1                                                                                                                                                
   127  59       PACK                                                                                                                                                 
   128  60       STLOC1                                                                                                                                               
   129  61       PUSHDATA1     696e666f ("info")                                                                                                                      
   130  67       LDLOC1                                                                                                                                               
   131  68       SWAP                                                                                                                                                 
   132  69       SYSCALL       System.Runtime.Notify (95016f61)                                                                                                       
   133  74       NOP                                                                                                                                                  
   134  75       PUSH0                                                                                                                                                
   135  76       STLOC2                                                                                                                                               
   136  77       LDLOC0                                                                                                                                               
   137  78       PUSHDATA1     746573742d73746f726167652d6b6579 ("test-storage-key")                                                                                  
   138  96       LDLOC2                                                                                                                                               
   139  97       REVERSE3                                                                                                                                             
   140  98       SYSCALL       System.Storage.Put (e63f1884)                                                                                                          
   141  103      NOP                                                                                                                                                  
   142  104      PUSHDATA1     53746f72616765206b657920697320696e697469616c69736564 ("Storage key is initialised")                                                    
   143  132      CONVERT       Buffer (30)                                                                                                                            
   144  134      PUSH1                                                                                                                                                
   145  135      PACK                                                                                                                                                 
   146  136      STLOC3                                                                                                                                               
   147  137      PUSHDATA1     696e666f ("info")                                                                                                                      
   148  143      LDLOC3                                                                                                                                               
   149  144      SWAP                                                                                                                                                 
   150  145      SYSCALL       System.Runtime.Notify (95016f61)                                                                                                       
   151  150      NOP                                                                                                                                                  
   152  151      RET                                                                                                                                                  
   153  152      INITSLOT      5 local, 0 arg                                                                                                                         
   154  155      SYSCALL       System.Storage.GetContext (9bf667ce)                                                                                                   
   155  160      NOP                                                                                                                                                  
   156  161      STLOC0                                                                                                                                               
   157  162      LDLOC0                                                                                                                                               
   158  163      PUSHDATA1     746573742d73746f726167652d6b6579 ("test-storage-key")                                                                                  
   159  181      SWAP                                                                                                                                                 
   160  182      SYSCALL       System.Storage.Get (925de831)                                                                                                          
   161  187      NOP                                                                                                                                                  
   162  188      STLOC1                                                                                                                                               
   163  189      PUSHDATA1     56616c756520726561642066726f6d2073746f72616765 ("Value read from storage")                                                             
   164  214      CONVERT       Buffer (30)                                                                                                                            
   165  216      PUSH1                                                                                                                                                
   166  217      PACK                                                                                                                                                 
   167  218      STLOC2                                                                                                                                               
   168  219      PUSHDATA1     696e666f ("info")                                                                                                                      
   169  225      LDLOC2                                                                                                                                               
   170  226      SWAP                                                                                                                                                 
   171  227      SYSCALL       System.Runtime.Notify (95016f61)                                                                                                       
   172  232      NOP                                                                                                                                                  
   173  233      PUSHDATA1     53746f72616765206b657920616c7265616479207365742e20496e6372656d656e74696e672062792031 ("Storage key already set. Incrementing by 1")    
   174  277      CONVERT       Buffer (30)                                                                                                                            
   175  279      PUSH1                                                                                                                                                
   176  280      PACK                                                                                                                                                 
   177  281      STLOC3                                                                                                                                               
   178  282      PUSHDATA1     696e666f ("info")                                                                                                                      
   179  288      LDLOC3                                                                                                                                               
   180  289      SWAP                                                                                                                                                 
   181  290      SYSCALL       System.Runtime.Notify (95016f61)                                                                                                       
   182  295      NOP                                                                                                                                                  
   183  296      LDLOC1                                                                                                                                               
   184  297      CONVERT       Integer (21)                                                                                                                           
   185  299      PUSH1                                                                                                                                                
   186  300      ADD                                                                                                                                                  
   187  301      STLOC1                                                                                                                                               
   188  302      LDLOC0                                                                                                                                               
   189  303      PUSHDATA1     746573742d73746f726167652d6b6579 ("test-storage-key")                                                                                  
   190  321      LDLOC1                                                                                                                                               
   191  322      REVERSE3                                                                                                                                             
   192  323      SYSCALL       System.Storage.Put (e63f1884)                                                                                                          
   193  328      NOP                                                                                                                                                  
   194  329      PUSHDATA1     4e65772076616c7565207772697474656e20696e746f2073746f72616765 ("New value written into storage")                                        
   195  361      CONVERT       Buffer (30)                                                                                                                            
   196  363      PUSH1                                                                                                                                                
   197  364      PACK                                                                                                                                                 
   198  365      STLOC4                                                                                                                                               
   199  366      PUSHDATA1     696e666f ("info")                                                                                                                      
   200  372      LDLOC4                                                                                                                                               
   201  373      SWAP                                                                                                                                                 
   202  374      SYSCALL       System.Runtime.Notify (95016f61)                                                                                                       
   203  379      NOP                                                                                                                                                  
   204  380      LDLOC1                                                                                                                                               
   205  381      RET                         
   206  ```
   207  
   208  #### Neo Smart Contract Debugger support
   209  
   210  It's possible to debug contracts written in Go using standard [Neo Smart
   211  Contract Debugger](https://github.com/neo-project/neo-debugger/) which is a
   212  part of [Neo Blockchain
   213  Toolkit](https://github.com/neo-project/neo-blockchain-toolkit/). To do that
   214  you need to generate debug information using `--debug` option, like this:
   215  
   216  ```
   217  $ ./bin/neo-go contract compile -i contract.go -c contract.yml -m contract.manifest.json -o contract.nef --debug contract.debug.json
   218  ```
   219  
   220  This file can then be used by debugger and set up to work just like for any
   221  other supported language.
   222  
   223  ### Deploying
   224  
   225  Deploying a contract to blockchain with neo-go requires both NEF and JSON
   226  manifest generated by the compiler from a configuration file provided in YAML
   227  format. To create contract manifest, pass a YAML file with `-c` parameter and
   228  specify the manifest output file with `-m`:
   229  ```
   230  ./bin/neo-go contract compile -i contract.go -c config.yml -m contract.manifest.json
   231  ```
   232  
   233  Example of such YAML file contents:
   234  ```
   235  name: Contract
   236  safemethods: []
   237  supportedstandards: []
   238  events:
   239    - name: info
   240      parameters:
   241        - name: message
   242          type: String
   243  ```
   244  
   245  Then, the manifest can be passed to the `deploy` command via `-m` option:
   246  
   247  ```
   248  $ ./bin/neo-go contract deploy -i contract.nef -m contract.manifest.json -r http://localhost:20331 -w wallet.json
   249  ```
   250  
   251  Deployment works via an RPC server, an address of which is passed via `-r`
   252  option, and should be signed using a wallet from `-w` option. More details can
   253  be found in `deploy` command help.
   254  
   255  #### Config file
   256  Configuration file contains following options:
   257  
   258  | Parameter | Description | Example |
   259  | --- | --- | --- |
   260  | `name` | Contract name in the manifest. | `"My awesome contract"`
   261  | `safemethods` | List of methods which don't change contract state, don't emit notifications and are available for anyone to call. | `["balanceOf", "decimals"]`
   262  | `supportedstandards` | List of standards this contract implements. For example, `NEP-11` or `NEP-17` token standard. This will enable additional checks in compiler. The check can be disabled with `--no-standards` flag. | `["NEP-17"]`
   263  | `events` | Notifications emitted by this contract. | See [Events](#Events). |
   264  | `permissions` | Foreign calls allowed for this contract. | See [Permissions](#Permissions). |
   265  | `overloads` | Custom method names for this contract. | See [Overloads](#Overloads). |
   266  
   267  ##### Events
   268  Each event must have a name and 0 or more parameters. Parameters are specified using their name and type.
   269  Both event and parameter names must be strings.
   270  Parameter type can be one of the following:
   271  
   272  Type in code | Type in config file
   273  --- | ---
   274  `bool` | `Boolean` 
   275  `int`, `int64` etc.| `Integer`
   276  `[]byte` | `ByteArray` 
   277  `string` | `String` 
   278  Any non-byte slice `[]T`| `Array` 
   279  `map[K]V` | `Map` 
   280  `interop.Hash160` | `Hash160`
   281  `interop.Hash256` | `Hash256`
   282  `interop.Interface` | `InteropInterface`
   283  `interop.PublicKey` | `PublicKey`
   284  `interop.Signature` | `Signature`
   285  anything else | `Any` 
   286  
   287  `interop.*` types are defined as aliases in `github.com/nspcc-dev/neo-go/pkg/interop` module
   288  with the sole purpose of correct manifest generation.
   289  
   290  As an example, consider `Transfer` event from `NEP-17` standard:
   291  ```
   292  - name: Transfer
   293    parameters:
   294      - name: from
   295        type: Hash160
   296      - name: to
   297        type: Hash160
   298      - name: amount
   299        type: Integer
   300  ```
   301  
   302  By default, compiler performs some sanity checks. Most of the time
   303  it will report missing events and/or parameter type mismatch.
   304  It isn't prohibited to use a variable as an event name in code, but it will prevent
   305  the compiler from analyzing the event. It is better to use either constant or string literal.
   306  It isn't prohibited to use ellipsis expression as an event arguments, but it will also
   307  prevent the compiler from analyzing the event. It is better to provide arguments directly
   308  without `...`. The type conversion code will be emitted for checked events, it will cast
   309  argument types to ones specified in the contract manifest. These checks and conversion can
   310  be disabled with `--no-events` flag.
   311  
   312  ##### Permissions
   313  Each permission specifies contracts and methods allowed for this permission.
   314  If a contract is not specified in a rule, specified set of methods can be called on any contract.
   315  By default, no calls are allowed. The simplest permission is to allow everything:
   316  ```
   317  - methods: '*'
   318  ```
   319  
   320  Another common case is to allow calling `onNEP17Payment`, which is necessary
   321  for most of the NEP-17 token implementations:
   322  ```
   323  - methods: ["onNEP17Payment"]
   324  ```
   325  
   326  In addition to `methods`, permission can have one of these fields:
   327  1. `hash` contains hash and restricts a set of contracts to a single contract.
   328  2. `group` contains public key and restricts a set of contracts to those that
   329  have the corresponding group in their manifest.
   330  
   331  Consider an example:
   332  ```
   333  - methods: ["onNEP17Payment"]
   334  - hash: fffdc93764dbaddd97c48f252a53ea4643faa3fd
   335    methods: ["start", "stop"]
   336  - group: 03184b018d6b2bc093e535519732b3fd3f7551c8cffaf4621dd5a0b89482ca66c9
   337    methods: ["update"]
   338  ```
   339  
   340  This set of permissions allows calling:
   341  - `onNEP17Payment` method of any contract
   342  - `start` and `stop` methods of contract with hash `fffdc93764dbaddd97c48f252a53ea4643faa3fd`
   343  - `update` method of contract in group with public key `03184b018d6b2bc093e535519732b3fd3f7551c8cffaf4621dd5a0b89482ca66c9`
   344  
   345  Also note that a native contract must be included here too. For example, if your contract
   346  transfers NEO/GAS or gets some info from the `Ledger` contract, all of these
   347  calls must be allowed in permissions.
   348  
   349  The compiler does its best to ensure that correct permissions are specified in the config.
   350  Incorrect permissions will result in runtime invocation failures.
   351  Using either constant or literal for contract hash and method will allow the compiler
   352  to perform more extensive analysis.
   353  This check can be disabled with `--no-permissions` flag.
   354  
   355  ##### Overloads
   356  NeoVM allows a contract to have multiple methods with the same name
   357  but different parameters number. Go lacks this feature, but this can be circumvented
   358  with `overloads` section. Essentially, it is a mapping from default contract method names
   359  to the new ones.
   360  ```
   361  - overloads:
   362      oldName1: newName
   363      oldName2: newName
   364  ```
   365  Since the use-case for this is to provide multiple implementations with the same ABI name,
   366  `newName` is required to be already present in the compiled contract.
   367  
   368  As an example, consider [`NEP-11` standard](https://github.com/neo-project/proposals/blob/master/nep-11.mediawiki#transfer).
   369  It requires a divisible NFT contract to have 2 `transfer` methods. To achieve this, we might implement
   370  `Transfer` and `TransferDivisible` and specify the emitted name in the config:
   371  ```
   372  - overloads:
   373      transferDivisible:transfer
   374  ```
   375  
   376  
   377  #### Manifest file
   378  Any contract can be included in a group identified by a public key which is used in [permissions](#Permissions).
   379  This is achieved with `manifest add-group` command.
   380  ```
   381  ./bin/neo-go contract manifest add-group -n contract.nef -m contract.manifest.json --sender <sender> --wallet /path/to/wallet.json --account <account>
   382  ```
   383  It accepts contract `.nef` and manifest files emitted by `compile` command as well as
   384  sender and signer accounts. `--sender` is the account that will send deploy transaction later (not necessarily in wallet).
   385  `--account` is the wallet account which signs contract hash using group private key.
   386  
   387  #### Neo Express support
   388  
   389  It's possible to deploy contracts written in Go using [Neo
   390  Express](https://github.com/neo-project/neo-express), which is a part of [Neo
   391  Blockchain
   392  Toolkit](https://github.com/neo-project/neo-blockchain-toolkit/). To do that,
   393  you need to generate a different metadata file using YAML written for
   394  deployment with neo-go. It's done in the same step with compilation via
   395  `--config` input parameter and `--abi` output parameter, combined with debug
   396  support the command line will look like this:
   397  
   398  ```
   399  $ ./bin/neo-go contract compile -i contract.go --config contract.yml -o contract.nef --debug contract.debug.json --abi contract.abi.json 
   400  ```
   401  
   402  This file can then be used by toolkit to deploy contract the same way
   403  contracts in other languages are deployed.
   404  
   405  
   406  ### Invoking
   407  You can import your contract into a standalone VM and run it there (see [VM
   408  documentation](vm.md) for more info), but that only works for simple contracts
   409  that don't use blockchain a lot. For more real contracts you need to deploy
   410  them first and then do test invocations and regular invocations with `contract
   411  testinvokefunction` and `contract invokefunction` commands (or their variants,
   412  see `contract` command help for more details. They all work via RPC, so it's a
   413  mandatory parameter.
   414  
   415  Example call (contract `f84d6a337fbc3d3a201d41da99e86b479e7a2554` with method
   416  `balanceOf` and method's parameter `NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq` using
   417  given RPC server and wallet and paying 0.00001 extra GAS for this transaction):
   418  
   419  ```
   420  $ ./bin/neo-go contract invokefunction -r http://localhost:20331 -w my_wallet.json -g 0.00001 f84d6a337fbc3d3a201d41da99e86b479e7a2554 balanceOf NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq
   421  ```
   422  
   423  ### Generating contract bindings
   424  To be able to use deployed contract from another contract one needs to have
   425  its interface definition (exported methods and hash). While it is possible to
   426  use generic contract.Call interop interface, it's not very convenient and
   427  efficient. NeoGo can autogenerate contract bindings in Go language for any
   428  deployed contract based on its manifest, it creates a Go source file with all
   429  of the contract's methods that then can be imported and used as a regular Go
   430  package.
   431  
   432  ```
   433  $ ./bin/neo-go contract generate-wrapper --manifest manifest.json --out wrapper.go --hash 0x1b4357bff5a01bdf2a6581247cf9ed1e24629176
   434  ```
   435  
   436  Notice that some structured types can be omitted this way (when a function
   437  returns some structure it's just an "Array" type in the manifest with no
   438  internal details), but if the contract you're using is written in Go
   439  originally you can create a specific configuration file during compilation
   440  that will add this data for wrapper generator to use:
   441  
   442  ```
   443  $ ./bin/neo-go contract compile -i contract.go --config contract.yml -o contract.nef --manifest manifest.json --bindings contract.bindings.yml
   444  $ ./bin/neo-go contract generate-wrapper --manifest manifest.json --config contract.bindings.yml --out wrapper.go --hash 0x1b4357bff5a01bdf2a6581247cf9ed1e24629176
   445  ```
   446  
   447  ### Generating RPC contract bindings
   448  To simplify interacting with the contract via RPC you can generate
   449  contract-specific RPC bindings with the "generate-rpcwrapper" command. It
   450  generates ContractReader structure for safe methods that accept appropriate
   451  data for input and return things returned by the contract. State-changing
   452  methods are contained in Contract structure with each contract method
   453  represented by three wrapper methods that create/send transaction with a
   454  script performing appropriate action. This script invokes contract method and
   455  does not do anything else unless the method's returned value is of a boolean
   456  type, in this case an ASSERT is added to script making it fail when the method
   457  returns false.
   458  
   459  ```
   460  $ ./bin/neo-go contract generate-rpcwrapper --manifest manifest.json --out rpcwrapper.go --hash 0x1b4357bff5a01bdf2a6581247cf9ed1e24629176
   461  ```
   462  
   463  If your contract is NEP-11 or NEP-17 that's autodetected and an appropriate
   464  package is included as well. Notice that the type data available in the
   465  manifest is limited, so in some cases the interface generated may use generic
   466  stackitem types. Any InteropInterface returned from a method is treated as
   467  iterator and an appropriate unwrapper is used with UUID and iterator structure
   468  result. This pair can then be used in Invoker `TraverseIterator` method to
   469  retrieve actual resulting items.
   470  
   471  Go contracts can also make use of additional type data from bindings
   472  configuration file generated during compilation. This can cover arrays, maps
   473  and structures. Notice that structured types returned by methods can't be Null
   474  at the moment (see #2795).
   475  
   476  ```
   477  $ ./bin/neo-go contract compile -i contract.go --config contract.yml -o contract.nef --manifest manifest.json --bindings contract.bindings.yml --guess-eventtypes
   478  $ ./bin/neo-go contract generate-rpcwrapper --manifest manifest.json --config contract.bindings.yml --out rpcwrapper.go --hash 0x1b4357bff5a01bdf2a6581247cf9ed1e24629176
   479  ```
   480  
   481  Contract-specific RPC-bindings generated by "generate-rpcwrapper" command include
   482  structure wrappers for each event declared in the contract manifest as far as the
   483  set of helpers that allow to retrieve emitted event from the application log or
   484  from stackitem. By default, event wrappers builder use event structure that was
   485  described in the manifest. Since the type data available in the manifest is
   486  limited, in some cases the resulting generated event structure may use generic
   487  go types. Go contracts can make use of additional type data from bindings
   488  configuration file generated during compilation. Like for any other contract
   489  types, this can cover arrays, maps and structures. To reach the maximum
   490  resemblance between the emitted events and the generated event wrappers, we
   491  recommend either to fill in the extended events type information in the contract
   492  configuration file before the compilation or to use `--guess-eventtypes`
   493  compilation option.
   494  
   495  If using `--guess-eventtypes` compilation option, event parameter types will be
   496  guessed from the arguments of `runtime.Notify` calls for each emitted event. If
   497  multiple calls of `runtime.Notify` are found, then argument types will be checked
   498  for matching (guessed types must be the same across the particular event usages).
   499  After that, the extended types binding configuration will be generated according
   500  to the emitted events parameter types. `--guess-eventtypes` compilation option
   501  is able to recognize those events that has a constant name known at a compilation
   502  time and do not include variadic arguments usage. Thus, use this option if your
   503  contract suites these requirements. Otherwise, we recommend to manually specify
   504  extended event parameter types information in the contract configuration file.
   505  
   506  Extended event parameter type information can be provided manually via contract
   507  configuration file under the `events` section. Each event parameter specified in
   508  this section may be supplied with additional parameter type information specified
   509  under `extendedtype` subsection. The extended type information (`ExtendedType`)
   510  has the following structure:
   511  
   512  | Field       | Type                                                                                                                                  | Required                                                                             | Meaning                                                                                                                                          |
   513  |-------------|---------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
   514  | `base`      | Any valid [NEP-14 parameter type](https://github.com/neo-project/proposals/blob/master/nep-14.mediawiki#parametertype) except `Void`. | Always required.                                                                              | The base type of a parameter, e.g. `Array` for go structures and any nested arrays, `Map` for nested maps, `Hash160` for 160-bits integers, etc. |
   515  | `name`      | `string`                                                                                                                              | Required for structures, omitted for arrays, interfaces and maps.                    | Name of a structure that will be used in the resulting RPC binding.                                                                              |
   516  | `interface` | `string`                                                                                                                              | Required for `InteropInterface`-based types, currently `iterator` only is supported. | Underlying value of the `InteropInterface`.                                                                                                      |
   517  | `key`       | Any simple [NEP-14 parameter type](https://github.com/neo-project/proposals/blob/master/nep-14.mediawiki#parametertype).              | Required for `Map`-based types.                                                      | Key type for maps.                                                                                                                               |
   518  | `value`     | `ExtendedType`.                                                        | Required for iterators, arrays and maps.                                             | Value type of iterators, arrays and maps.                                                                                                        |
   519  | `fields`    | Array of `FieldExtendedType`.                                                                                                         | Required for structures.                                                             | Ordered type data for structure fields.                                                                                                          |
   520  
   521  The structure's field extended information (`FieldExtendedType`) has the following structure:
   522  
   523  | Field                  | Type           | Required         | Meaning                                                                     |
   524  |------------------------|----------------|------------------|-----------------------------------------------------------------------------|
   525  | `field`                | `string`       | Always required. | Name of the structure field that will be used in the resulting RPC binding. |
   526  | Inlined `ExtendedType` | `ExtendedType` | Always required. | The extended type information about structure field.                        |
   527  
   528  
   529  Any named structures used in the `ExtendedType` description must be manually
   530  specified in the contract configuration file under top-level `namedtypes` section
   531  in the form of `map[string]ExtendedType`, where the map key is a name of the
   532  described named structure that matches the one provided in the `name` field of
   533  the event parameter's extended type.
   534  
   535  Here's the example of manually-created contract configuration file that uses
   536  extended types for event parameters description:
   537  
   538  ```
   539  name: "HelloWorld contract"
   540  supportedstandards: []
   541  events:
   542    - name: Some simple notification
   543      parameters:
   544        - name: intP
   545          type: Integer
   546        - name: boolP
   547          type: Boolean
   548        - name: stringP
   549          type: String
   550    - name: Structure notification
   551      parameters:
   552        - name: structure parameter
   553          type: Array
   554          extendedtype:
   555            base: Array
   556            name: transferData
   557    - name: Map of structures notification
   558      parameters:
   559        - name: map parameter
   560          type: Map
   561          extendedtype:
   562            base: Map
   563            key: Integer
   564            value:
   565              base: Array
   566              name: transferData
   567    - name: Iterator notification
   568      parameters:
   569        - name: data
   570          type: InteropInterface
   571          extendedtype:
   572            base: InteropInterface
   573            interface: iterator
   574  namedtypes:
   575    transferData:
   576      base: Array
   577      fields:
   578        - field: IntField
   579          base: Integer
   580        - field: BoolField
   581          base: Boolean
   582  ```
   583  
   584  ## Smart contract examples
   585  
   586  Some examples are provided in the [examples directory](../examples). For more
   587  sophisticated real-world contracts written in Go check out [NeoFS
   588  contracts](https://github.com/nspcc-dev/neofs-contract/).
   589  
   590  ## How to report compiler bugs 
   591  1. Make a proper testcase (example testcases can be found in the tests folder)
   592  2. Create an issue on Github 
   593  3. Make a PR with a reference to the created issue, containing the testcase that proves the bug
   594  4. Either you fix the bug yourself or wait for patch that solves the problem