mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-12-05 03:58:23 +00:00
Merge pull request #956 from nspcc-dev/doc-update-2.x
Documentation update for 2.x
This commit is contained in:
commit
f0d6b0a639
32 changed files with 1192 additions and 824 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -31,8 +31,6 @@ TAGS
|
||||||
# leveldb
|
# leveldb
|
||||||
chains/
|
chains/
|
||||||
chain/
|
chain/
|
||||||
blockchain/
|
|
||||||
blockchains/
|
|
||||||
|
|
||||||
# patch
|
# patch
|
||||||
*.orig
|
*.orig
|
||||||
|
|
|
@ -110,7 +110,9 @@ mode, after it ends the node can be started normally.
|
||||||
Please refer to [neo-go smart contract development
|
Please refer to [neo-go smart contract development
|
||||||
workshop](https://github.com/nspcc-dev/neo-go-sc-wrkshp) that shows some
|
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
|
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
|
# Developer notes
|
||||||
Nodes have such features as [Prometheus](https://prometheus.io/docs/guides/go-application) and
|
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.
|
The neo-go compiler compiles Go programs to bytecode that the NEO virtual machine can understand.
|
||||||
|
|
||||||
## Currently supported
|
## Language compatibility
|
||||||
|
|
||||||
### Go internals
|
The compiler is mostly compatible with regular Go language specification, but
|
||||||
- type checking
|
there are some important deviations that you need to be aware of that make it
|
||||||
- multiple assignments
|
a dialect of Go rather than a complete port of the language:
|
||||||
- global variables
|
* `make()` ane `new()` are not supported, most of the time you can substitute
|
||||||
- types int, string, byte and booleans
|
them with composite literals
|
||||||
- struct types + method receives
|
* there is no real distinction between different integer types, all of them
|
||||||
- functions
|
work as big.Int in Go with a limit of 256 bit in width, so you can use
|
||||||
- composite literals `[]int, []string, []byte`
|
`int` for just about anything. This is the way integers work in Neo VM and
|
||||||
- basic if statements
|
adding proper Go types emulation is considered to be too costly.
|
||||||
- binary expressions
|
* goroutines, channels and garbage collection are not supported and will
|
||||||
- return statements
|
never be because emulating that aspects of Go runtime on top of Neo VM is
|
||||||
- for loops
|
close to impossible
|
||||||
- imports
|
* 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
|
## VM API (interop layer)
|
||||||
- len
|
|
||||||
- append
|
|
||||||
|
|
||||||
### VM API (interop layer)
|
|
||||||
Compiler translates interop function calls into NEO VM syscalls or (for custom
|
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.
|
functions) into NEO VM instructions. [Refer to
|
||||||
|
pkg.go.dev](https://pkg.go.dev/github.com/nspcc-dev/neo-go/pkg/interop)
|
||||||
#### Standard NEO Smart Contract API
|
for full API documentation. In general it provides the same level of
|
||||||
- account
|
functionality as Neo .net Framework library.
|
||||||
- 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
|
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
|
|
||||||
### Compile a smart contract
|
### Compiling
|
||||||
|
|
||||||
```
|
```
|
||||||
./bin/neo-go contract compile -i mycontract.go
|
./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
|
./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:
|
You can dump the opcodes generated by the compiler with the following command:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -112,33 +85,89 @@ INDEX OPCODE DESC
|
||||||
25 0x66 RET
|
25 0x66 RET
|
||||||
```
|
```
|
||||||
|
|
||||||
### Test invoke a compiled contract
|
#### Neo Smart Contract Debugger support
|
||||||
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:
|
|
||||||
|
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:
|
This file can then be used by debugger and set up to work just like for any
|
||||||
```
|
other supported language.
|
||||||
{
|
|
||||||
"state": "HALT, BREAK",
|
### Deploying
|
||||||
"gas_consumed": "0.006",
|
|
||||||
"Stack": [
|
Deploying a contract to blockchain with neo-go requires a configuration file
|
||||||
{
|
with contract's metadata in YAML format, like the following:
|
||||||
"type": "Integer",
|
|
||||||
"value": "9"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
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
|
## 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
|
### Check if the invoker of the contract is the owning address
|
||||||
|
|
||||||
|
|
339
docs/notifications.md
Normal file
339
docs/notifications.md
Normal file
|
@ -0,0 +1,339 @@
|
||||||
|
# Notification subsystem
|
||||||
|
|
||||||
|
Original motivation, requirements and general solution strategy are described
|
||||||
|
in the issue #895.
|
||||||
|
|
||||||
|
This extension allows a websocket client to subscribe to various events and
|
||||||
|
receive them as JSON-RPC notifications from the server.
|
||||||
|
|
||||||
|
## Events
|
||||||
|
Currently supported events:
|
||||||
|
* new block added
|
||||||
|
Contents: block.
|
||||||
|
Filters: none.
|
||||||
|
* new transaction in the block
|
||||||
|
Contents: transaction.
|
||||||
|
Filters: type.
|
||||||
|
* notification generated during execution
|
||||||
|
Contents: container hash, contract script hash, stack item.
|
||||||
|
Filters: contract script hash.
|
||||||
|
* transaction executed
|
||||||
|
Contents: application execution result.
|
||||||
|
Filters: VM state.
|
||||||
|
|
||||||
|
## Ordering and persistence guarantees
|
||||||
|
* new block is only announced after its processing is complete and the chain
|
||||||
|
is updated to the new height
|
||||||
|
* no disk-level persistence guarantees are given
|
||||||
|
* new in-block transaction is announced after block processing, but before
|
||||||
|
announcing the block itself
|
||||||
|
* transaction notifications are only announced for successful transactions
|
||||||
|
* all announcements are being done in the same order they happen on the chain
|
||||||
|
At first transaction execution is announced, then followed by notifications
|
||||||
|
generated during this execution, then followed by transaction announcement.
|
||||||
|
Transaction announcements are ordered the same way they're in the block.
|
||||||
|
* unsubscription may not cancel pending, but not yet sent events
|
||||||
|
|
||||||
|
## Subscription management
|
||||||
|
|
||||||
|
Errors are not described down below, but they can be returned as standard
|
||||||
|
JSON-RPC errors (most often caused by invalid parameters).
|
||||||
|
|
||||||
|
### `subscribe` method
|
||||||
|
|
||||||
|
Parameters: event stream name, stream-specific filter rules hash (can be
|
||||||
|
omitted if empty).
|
||||||
|
|
||||||
|
Recognized stream names:
|
||||||
|
* `block_added`
|
||||||
|
No filter parameters defined.
|
||||||
|
* `transaction_added`
|
||||||
|
Filter: `type` as a string containing standard transaction types
|
||||||
|
(MinerTransaction, InvocationTransaction, etc)
|
||||||
|
* `notification_from_execution`
|
||||||
|
Filter: `contract` field containing string with hex-encoded Uint160 (LE
|
||||||
|
representation).
|
||||||
|
* `transaction_executed`
|
||||||
|
Filter: `state` field containing `HALT` or `FAULT` string for successful
|
||||||
|
and failed executions respectively.
|
||||||
|
|
||||||
|
Response: returns subscription ID (string) as a result. This ID can be used to
|
||||||
|
cancel this subscription and has no meaning other than that.
|
||||||
|
|
||||||
|
Example request (subscribe to notifications from contract
|
||||||
|
0x6293a440ed80a427038e175a507d3def1e04fb67 generated when executing
|
||||||
|
transactions):
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": "subscribe",
|
||||||
|
"params": ["notification_from_execution", {"contract": "6293a440ed80a427038e175a507d3def1e04fb67"}],
|
||||||
|
"id": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 1,
|
||||||
|
"result": "55aaff00"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `unsubscribe` method
|
||||||
|
|
||||||
|
Parameters: subscription ID as a string.
|
||||||
|
|
||||||
|
Response: boolean true.
|
||||||
|
|
||||||
|
Example request (unsubscribe from "55aaff00"):
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": "unsubscribe",
|
||||||
|
"params": ["55aaff00"],
|
||||||
|
"id": 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 1,
|
||||||
|
"result": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Events
|
||||||
|
|
||||||
|
Events are sent as JSON-RPC notifications from the server with `method` field
|
||||||
|
being used for notification names. Notification names are identical to stream
|
||||||
|
names described for `subscribe` method with one important addition for
|
||||||
|
`event_missed` which can be sent for any subscription to signify that some
|
||||||
|
events were not delivered (usually when client isn't able to keep up with
|
||||||
|
event flow).
|
||||||
|
|
||||||
|
Verbose responses for various structures like blocks and transactions are used
|
||||||
|
to simplify working with notifications on client side. Returned structures
|
||||||
|
mostly follow the one used by standard Neo RPC calls, but may have some minor
|
||||||
|
differences.
|
||||||
|
|
||||||
|
### `block_added` notification
|
||||||
|
As a first parameter (`params` section) contains block converted to JSON
|
||||||
|
structure which is similar to verbose `getblock` response but with the
|
||||||
|
following differences:
|
||||||
|
* it doesn't have `size` field (you can calculate it client-side)
|
||||||
|
* it doesn't have `nextblockhash` field (it's supposed to be the latest one
|
||||||
|
anyway)
|
||||||
|
* it doesn't have `confirmations` field (see previous)
|
||||||
|
* transactions contained don't have `net_fee` and `sys_fee` fields
|
||||||
|
|
||||||
|
No other parameters are sent.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"jsonrpc" : "2.0",
|
||||||
|
"method" : "block_added",
|
||||||
|
"params" : [
|
||||||
|
{
|
||||||
|
"previousblockhash" : "0x33f3e0e24542b2ec3b6420e6881c31f6460a39a4e733d88f7557cbcc3b5ed560",
|
||||||
|
"nextconsensus" : "AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU",
|
||||||
|
"index" : 205,
|
||||||
|
"nonce" : "0000000000000457",
|
||||||
|
"version" : 0,
|
||||||
|
"tx" : [
|
||||||
|
{
|
||||||
|
"version" : 0,
|
||||||
|
"attributes" : [],
|
||||||
|
"txid" : "0xf9adfde059810f37b3d0686d67f6b29034e0c669537df7e59b40c14a0508b9ed",
|
||||||
|
"size" : 10,
|
||||||
|
"vin" : [],
|
||||||
|
"type" : "MinerTransaction",
|
||||||
|
"scripts" : [],
|
||||||
|
"vout" : []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version" : 1,
|
||||||
|
"txid" : "0x93670859cc8a42f6ea994869c944879678d33d7501d388f5a446a8c7de147df7",
|
||||||
|
"attributes" : [],
|
||||||
|
"size" : 60,
|
||||||
|
"script" : "097465737476616c756507746573746b657952c103507574676f20ccfbd5f01d5b9633387428b8bab95a9e78c2",
|
||||||
|
"vin" : [],
|
||||||
|
"scripts" : [],
|
||||||
|
"type" : "InvocationTransaction",
|
||||||
|
"vout" : []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time" : 1586154525,
|
||||||
|
"hash" : "0x48fba8aebf88278818a3dc0caecb230873d1d4ce1ea8bf473634317f94a609e5",
|
||||||
|
"script" : {
|
||||||
|
"invocation" : "4047a444a51218ac856f1cbc629f251c7c88187910534d6ba87847c86a9a73ed4951d203fd0a87f3e65657a7259269473896841f65c0a0c8efc79d270d917f4ff640435ee2f073c94a02f0276dfe4465037475e44e1c34c0decb87ec9c2f43edf688059fc4366a41c673d72ba772b4782c39e79f01cb981247353216d52d2df1651140527eb0dfd80a800fdd7ac8fbe68fc9366db2d71655d8ba235525a97a69a7181b1e069b82091be711c25e504a17c3c55eee6e76e6af13cb488fbe35d5c5d025c34041f39a02ebe9bb08be0e4aaa890f447dc9453209bbfb4705d8f2d869c2b55ee2d41dbec2ee476a059d77fb7c26400284328d05aece5f3168b48f1db1c6f7be0b",
|
||||||
|
"verification" : "532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae"
|
||||||
|
},
|
||||||
|
"merkleroot" : "0x9d922c5cfd4c8cd1da7a6b2265061998dc438bd0dea7145192e2858155e6c57a"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `transaction_added` notification
|
||||||
|
|
||||||
|
In the first parameter (`params` section) contains transaction converted to
|
||||||
|
JSON which is similar to verbose `getrawtransaction` response, but with the
|
||||||
|
following differences:
|
||||||
|
* `net_fee` and `sys_fee` fields are always missing
|
||||||
|
* block's metadata is missing (`blockhash`, `confirmations`, `blocktime`)
|
||||||
|
|
||||||
|
No other parameters are sent.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"params" : [
|
||||||
|
{
|
||||||
|
"vin" : [],
|
||||||
|
"scripts" : [],
|
||||||
|
"attributes" : [],
|
||||||
|
"txid" : "0x93670859cc8a42f6ea994869c944879678d33d7501d388f5a446a8c7de147df7",
|
||||||
|
"size" : 60,
|
||||||
|
"vout" : [],
|
||||||
|
"type" : "InvocationTransaction",
|
||||||
|
"version" : 1,
|
||||||
|
"script" : "097465737476616c756507746573746b657952c103507574676f20ccfbd5f01d5b9633387428b8bab95a9e78c2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"method" : "transaction_added",
|
||||||
|
"jsonrpc" : "2.0"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `notification_from_execution` notification
|
||||||
|
|
||||||
|
Contains three parameters: container hash (hex-encoded LE Uint256 in a
|
||||||
|
string), contract script hash (hex-encoded LE Uint160 in a string) and stack
|
||||||
|
item (encoded the same way as `state` field contents for notifications from
|
||||||
|
`getapplicationlog` response).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"method" : "notification_from_execution",
|
||||||
|
"jsonrpc" : "2.0",
|
||||||
|
"params" : [
|
||||||
|
{
|
||||||
|
"state" : {
|
||||||
|
"value" : [
|
||||||
|
{
|
||||||
|
"value" : "636f6e74726163742063616c6c",
|
||||||
|
"type" : "ByteArray"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value" : "507574",
|
||||||
|
"type" : "ByteArray"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value" : [
|
||||||
|
{
|
||||||
|
"type" : "ByteArray",
|
||||||
|
"value" : "746573746b6579"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value" : "7465737476616c7565",
|
||||||
|
"type" : "ByteArray"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type" : "Array"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type" : "Array"
|
||||||
|
},
|
||||||
|
"contract" : "0xc2789e5ab9bab828743833965b1df0d5fbcc206f"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `transaction_executed` notification
|
||||||
|
|
||||||
|
Contains the same result as from `getapplicationlog` method in the first
|
||||||
|
parameter and no other parameters. One difference from `getapplicationlog` is
|
||||||
|
that it always contains zero in the `contract` field.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"method" : "transaction_executed",
|
||||||
|
"params" : [
|
||||||
|
{
|
||||||
|
"executions" : [
|
||||||
|
{
|
||||||
|
"vmstate" : "HALT",
|
||||||
|
"contract" : "0x0000000000000000000000000000000000000000",
|
||||||
|
"notifications" : [
|
||||||
|
{
|
||||||
|
"state" : {
|
||||||
|
"type" : "Array",
|
||||||
|
"value" : [
|
||||||
|
{
|
||||||
|
"type" : "ByteArray",
|
||||||
|
"value" : "636f6e74726163742063616c6c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type" : "ByteArray",
|
||||||
|
"value" : "507574"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value" : [
|
||||||
|
{
|
||||||
|
"value" : "746573746b6579",
|
||||||
|
"type" : "ByteArray"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type" : "ByteArray",
|
||||||
|
"value" : "7465737476616c7565"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type" : "Array"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"contract" : "0xc2789e5ab9bab828743833965b1df0d5fbcc206f"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"gas_consumed" : "1.048",
|
||||||
|
"stack" : [
|
||||||
|
{
|
||||||
|
"type" : "Integer",
|
||||||
|
"value" : "1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"trigger" : "Application"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"txid" : "0x93670859cc8a42f6ea994869c944879678d33d7501d388f5a446a8c7de147df7"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"jsonrpc" : "2.0"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `event_missed` notification
|
||||||
|
|
||||||
|
Never has any parameters. Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": "event_missed",
|
||||||
|
"params": []
|
||||||
|
}
|
||||||
|
```
|
35
docs/rpc.md
35
docs/rpc.md
|
@ -65,6 +65,18 @@ which would yield the response:
|
||||||
| `submitblock` |
|
| `submitblock` |
|
||||||
| `validateaddress` |
|
| `validateaddress` |
|
||||||
|
|
||||||
|
#### Implementation notices
|
||||||
|
|
||||||
|
##### `invokefunction` and `invoke`
|
||||||
|
|
||||||
|
neo-go's implementation of `invokefunction` and `invoke` does not return `tx`
|
||||||
|
field in the answer because that requires signing the transaction with some
|
||||||
|
key in the server which doesn't fit the model of our node-client interactions.
|
||||||
|
Lacking this signature the transaction is almost useless, so there is no point
|
||||||
|
in returning it.
|
||||||
|
|
||||||
|
Both methods also don't currently support arrays in function parameters.
|
||||||
|
|
||||||
### Unsupported methods
|
### Unsupported methods
|
||||||
|
|
||||||
Methods listed down below are not going to be supported for various reasons
|
Methods listed down below are not going to be supported for various reasons
|
||||||
|
@ -86,17 +98,24 @@ and we're not accepting issues related to them.
|
||||||
| `sendmany` | Not applicable to neo-go, see `claimgas` comment |
|
| `sendmany` | Not applicable to neo-go, see `claimgas` comment |
|
||||||
| `sendtoaddress` | Not applicable to neo-go, see `claimgas` comment |
|
| `sendtoaddress` | Not applicable to neo-go, see `claimgas` comment |
|
||||||
|
|
||||||
#### Implementation notices
|
### Extensions
|
||||||
|
|
||||||
##### `invokefunction` and `invoke`
|
Some additional extensions are implemented as a part of this RPC server.
|
||||||
|
|
||||||
neo-go's implementation of `invokefunction` and `invoke` does not return `tx`
|
#### Websocket server
|
||||||
field in the answer because that requires signing the transaction with some
|
|
||||||
key in the server which doesn't fit the model of our node-client interactions.
|
|
||||||
Lacking this signature the transaction is almost useless, so there is no point
|
|
||||||
in returning it.
|
|
||||||
|
|
||||||
Both methods also don't currently support arrays in function parameters.
|
This server accepts websocket connections on `ws://$BASE_URL/ws` address. You
|
||||||
|
can use it to perform regular RPC calls over websockets (it's supposed to be a
|
||||||
|
little faster than going regular HTTP route) and you can also use it for
|
||||||
|
additional functionality provided only via websockets (like notifications).
|
||||||
|
|
||||||
|
#### Notification subsystem
|
||||||
|
|
||||||
|
Notification subsystem consists of two additional RPC methods (`subscribe` and
|
||||||
|
`unsubscribe` working only over websocket connection) that allow to subscribe
|
||||||
|
to various blockchain events (with simple event filtering) and receive them on
|
||||||
|
the client as JSON-RPC notifications. More details on that are written in the
|
||||||
|
[notifications specification](notifications.md).
|
||||||
|
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
|
|
523
docs/runtime.md
523
docs/runtime.md
|
@ -1,523 +0,0 @@
|
||||||
# Runtime
|
|
||||||
A brief overview of NEO smart contract API's that can be used in the neo-go framework.
|
|
||||||
|
|
||||||
# Overview
|
|
||||||
1. [Account]()
|
|
||||||
2. [Asset]()
|
|
||||||
3. [Attribute]()
|
|
||||||
4. [Block]()
|
|
||||||
5. [Blockchain]()
|
|
||||||
6. [Contract]()
|
|
||||||
7. [Crypto]()
|
|
||||||
8. [Engine]()
|
|
||||||
9. [Enumerator]()
|
|
||||||
10. [Iterator]()
|
|
||||||
11. [Header]()
|
|
||||||
12. [Input]()
|
|
||||||
13. [Output]()
|
|
||||||
14. [Runtime]()
|
|
||||||
15. [Storage]()
|
|
||||||
16. [Transaction]()
|
|
||||||
17. [Util]()
|
|
||||||
|
|
||||||
## Account
|
|
||||||
#### GetScriptHash
|
|
||||||
```
|
|
||||||
GetScriptHash(a Account) []byte
|
|
||||||
```
|
|
||||||
Returns the script hash of the given account.
|
|
||||||
|
|
||||||
#### GetVotes
|
|
||||||
```
|
|
||||||
GetVotes(a Account) [][]byte
|
|
||||||
```
|
|
||||||
Returns the the votes (a slice of public keys) of the given account.
|
|
||||||
|
|
||||||
#### GetBalance
|
|
||||||
```
|
|
||||||
GetBalance(a Account, assetID []byte) int
|
|
||||||
```
|
|
||||||
Returns the balance of the given asset id for the given account.
|
|
||||||
|
|
||||||
## Asset
|
|
||||||
#### GetAssetID
|
|
||||||
```
|
|
||||||
GetAssetID(a Asset) []byte
|
|
||||||
```
|
|
||||||
Returns the id of the given asset.
|
|
||||||
|
|
||||||
#### GetAmount
|
|
||||||
```
|
|
||||||
GetAmount(a Asset) int
|
|
||||||
```
|
|
||||||
Returns the amount of the given asset id.
|
|
||||||
|
|
||||||
#### GetAvailable
|
|
||||||
```
|
|
||||||
GetAvailable(a Asset) int
|
|
||||||
```
|
|
||||||
Returns the available amount of the given asset.
|
|
||||||
|
|
||||||
#### GetPrecision
|
|
||||||
```
|
|
||||||
GetPrecision(a Asset) byte
|
|
||||||
```
|
|
||||||
Returns the precision of the given Asset.
|
|
||||||
|
|
||||||
#### GetOwner
|
|
||||||
```
|
|
||||||
GetOwner(a Asset) []byte
|
|
||||||
```
|
|
||||||
Returns the owner of the given asset.
|
|
||||||
|
|
||||||
#### GetAdmin
|
|
||||||
```
|
|
||||||
GetAdmin(a Asset) []byte
|
|
||||||
```
|
|
||||||
Returns the admin of the given asset.
|
|
||||||
|
|
||||||
#### GetIssuer
|
|
||||||
```
|
|
||||||
GetIssuer(a Asset) []byte
|
|
||||||
```
|
|
||||||
Returns the issuer of the given asset.
|
|
||||||
|
|
||||||
#### Create
|
|
||||||
```
|
|
||||||
Create(type byte, name string, amount int, precision byte, owner, admin, issuer []byte)
|
|
||||||
```
|
|
||||||
Creates a new asset on the blockchain.
|
|
||||||
|
|
||||||
#### Renew
|
|
||||||
```
|
|
||||||
Renew(asset Asset, years int)
|
|
||||||
```
|
|
||||||
Renews the given asset as long as the given years.
|
|
||||||
|
|
||||||
## Attribute
|
|
||||||
#### GetUsage
|
|
||||||
```
|
|
||||||
GetUsage(attr Attribute) []byte
|
|
||||||
```
|
|
||||||
Returns the usage of the given attribute.
|
|
||||||
|
|
||||||
#### GetData
|
|
||||||
```
|
|
||||||
GetData(attr Attribute) []byte
|
|
||||||
```
|
|
||||||
Returns the data of the given attribute.
|
|
||||||
|
|
||||||
## Block
|
|
||||||
#### GetTransactionCount
|
|
||||||
```
|
|
||||||
GetTransactionCount(b Block) int
|
|
||||||
```
|
|
||||||
Returns the number of transactions that are recorded in the given block.
|
|
||||||
|
|
||||||
#### GetTransactions
|
|
||||||
```
|
|
||||||
GetTransactions(b Block) []transaction.Transaction
|
|
||||||
```
|
|
||||||
Returns a slice of the transactions that are recorded in the given block.
|
|
||||||
|
|
||||||
#### GetTransaction
|
|
||||||
```
|
|
||||||
GetTransaction(b Block, hash []byte) transaction.Transaction
|
|
||||||
```
|
|
||||||
Returns the transaction by the given hash that is recorded in the given block.
|
|
||||||
|
|
||||||
## Blockchain
|
|
||||||
#### GetHeight
|
|
||||||
```
|
|
||||||
GetHeight() int
|
|
||||||
```
|
|
||||||
Returns the current height of the blockchain.
|
|
||||||
|
|
||||||
#### GetHeader
|
|
||||||
```
|
|
||||||
GetHeader(heightOrHash []interface{}) header.Header
|
|
||||||
```
|
|
||||||
Return the header by the given hash or index.
|
|
||||||
|
|
||||||
#### GetBlock
|
|
||||||
```
|
|
||||||
GetBlock(heightOrHash interface{}) block.Block
|
|
||||||
```
|
|
||||||
Returns the block by the given hash or index.
|
|
||||||
|
|
||||||
#### GetTransaction
|
|
||||||
```
|
|
||||||
GetTransaction(hash []byte) transaction.Transaction
|
|
||||||
```
|
|
||||||
Returns a transaction by the given hash.
|
|
||||||
|
|
||||||
#### GetContract
|
|
||||||
```
|
|
||||||
GetContract(scriptHash []byte) contract.Contract
|
|
||||||
```
|
|
||||||
Returns the contract found by the given script hash.
|
|
||||||
|
|
||||||
#### GetAccount
|
|
||||||
```
|
|
||||||
GetAccount(scriptHash []byte) account.Account
|
|
||||||
```
|
|
||||||
Returns the account found by the given script hash.
|
|
||||||
|
|
||||||
#### GetValiditors
|
|
||||||
```
|
|
||||||
GetValidators() [][]byte
|
|
||||||
```
|
|
||||||
Returns a list of validators public keys.
|
|
||||||
|
|
||||||
#### GetAsset
|
|
||||||
```
|
|
||||||
GetAsset(assetID []byte) asset.Asset
|
|
||||||
```
|
|
||||||
Returns the asset found by the given asset id.
|
|
||||||
|
|
||||||
## Contract
|
|
||||||
#### GetScript
|
|
||||||
```
|
|
||||||
GetScript(c Contract) []byte
|
|
||||||
```
|
|
||||||
Return the script of the given contract.
|
|
||||||
|
|
||||||
#### IsPayable
|
|
||||||
```
|
|
||||||
IsPayable(c Contract) bool
|
|
||||||
```
|
|
||||||
Returns whether the given contract is payable.
|
|
||||||
|
|
||||||
#### GetStorageContext
|
|
||||||
```
|
|
||||||
GetStorageContext(c Contract)
|
|
||||||
```
|
|
||||||
Returns the storage context of the given contract.
|
|
||||||
|
|
||||||
#### Create
|
|
||||||
```
|
|
||||||
Create(
|
|
||||||
script []byte,
|
|
||||||
params []interface{},
|
|
||||||
returnType byte,
|
|
||||||
properties interface{},
|
|
||||||
name,
|
|
||||||
version,
|
|
||||||
author,
|
|
||||||
email,
|
|
||||||
description string)
|
|
||||||
```
|
|
||||||
Creates a new contract on the blockchain.
|
|
||||||
|
|
||||||
#### Migrate
|
|
||||||
```
|
|
||||||
Migrate(
|
|
||||||
script []byte,
|
|
||||||
params []interface{},
|
|
||||||
returnType byte,
|
|
||||||
properties interface{},
|
|
||||||
name,
|
|
||||||
version,
|
|
||||||
author,
|
|
||||||
email,
|
|
||||||
description string)
|
|
||||||
```
|
|
||||||
Migrates a contract on the blockchain.
|
|
||||||
|
|
||||||
#### Destroy
|
|
||||||
```
|
|
||||||
Destroy(c Contract)
|
|
||||||
```
|
|
||||||
Deletes the given contract from the blockchain.
|
|
||||||
|
|
||||||
## Crypto
|
|
||||||
#### SHA1
|
|
||||||
```
|
|
||||||
SHA1(data []byte) []byte
|
|
||||||
```
|
|
||||||
Computes the sha1 hash of the given bytes
|
|
||||||
|
|
||||||
#### SHA256
|
|
||||||
```
|
|
||||||
SHA256(data []byte) []byte
|
|
||||||
```
|
|
||||||
Computes the sha256 hash of the given bytes
|
|
||||||
|
|
||||||
#### Hash256
|
|
||||||
```
|
|
||||||
Hash256(data []byte) []byte
|
|
||||||
```
|
|
||||||
Computes the sha256^2 of the given data.
|
|
||||||
|
|
||||||
#### Hash160
|
|
||||||
```
|
|
||||||
Hash160(data []byte) []byte) []byte
|
|
||||||
```
|
|
||||||
Computes the ripemd160 over the sha256 hash of the given data.
|
|
||||||
|
|
||||||
## Engine
|
|
||||||
#### GetScriptContainer
|
|
||||||
```
|
|
||||||
GetScriptContainer() transaction.Transaction
|
|
||||||
```
|
|
||||||
Returns the transaction that is in the context of the VM execution.
|
|
||||||
|
|
||||||
#### GetExecutingScriptHash
|
|
||||||
```
|
|
||||||
GetExecutingScriptHash() []byte
|
|
||||||
```
|
|
||||||
Returns the script hash of the contract that is currently being executed.
|
|
||||||
|
|
||||||
#### GetCallingScriptHash
|
|
||||||
```
|
|
||||||
GetCallingScriptHash() []byte
|
|
||||||
```
|
|
||||||
Returns the script hash of the contract that has started the execution of the current script.
|
|
||||||
|
|
||||||
#### GetEntryScriptHash
|
|
||||||
```
|
|
||||||
GetEntryScriptHash() []byte
|
|
||||||
```
|
|
||||||
Returns the script hash of the contract that started the execution from the start.
|
|
||||||
|
|
||||||
## Enumerator
|
|
||||||
#### Create
|
|
||||||
```
|
|
||||||
Create(items []inteface{}) Enumerator
|
|
||||||
```
|
|
||||||
Create a enumerator from the given items.
|
|
||||||
|
|
||||||
#### Next
|
|
||||||
```
|
|
||||||
Next(e Enumerator) interface{}
|
|
||||||
```
|
|
||||||
Returns the next item from the given enumerator.
|
|
||||||
|
|
||||||
#### Value
|
|
||||||
```
|
|
||||||
Value(e Enumerator) interface{}
|
|
||||||
```
|
|
||||||
Returns the enumerator value.
|
|
||||||
|
|
||||||
## Iterator
|
|
||||||
#### Create
|
|
||||||
```
|
|
||||||
Create(items []inteface{}) Iterator
|
|
||||||
```
|
|
||||||
Creates an iterator from the given items.
|
|
||||||
|
|
||||||
#### Key
|
|
||||||
```
|
|
||||||
Key(it Iterator) interface{}
|
|
||||||
```
|
|
||||||
Return the key from the given iterator.
|
|
||||||
|
|
||||||
#### Keys
|
|
||||||
```
|
|
||||||
Keys(it Iterator) []interface{}
|
|
||||||
```
|
|
||||||
Returns the iterator's keys
|
|
||||||
|
|
||||||
#### Values
|
|
||||||
```
|
|
||||||
Values(it Iterator) []interface{}
|
|
||||||
```
|
|
||||||
Returns the iterator's values
|
|
||||||
|
|
||||||
## Header
|
|
||||||
#### GetIndex
|
|
||||||
```
|
|
||||||
GetIndex(h Header) int
|
|
||||||
```
|
|
||||||
Returns the height of the given header.
|
|
||||||
|
|
||||||
#### GetHash
|
|
||||||
```
|
|
||||||
GetHash(h Header) []byte
|
|
||||||
```
|
|
||||||
Returns the hash of the given header.
|
|
||||||
|
|
||||||
#### GetPrevHash
|
|
||||||
```
|
|
||||||
GetPrevhash(h Header) []byte
|
|
||||||
```
|
|
||||||
Returns the previous hash of the given header.
|
|
||||||
|
|
||||||
#### GetTimestamp
|
|
||||||
```
|
|
||||||
GetTimestamp(h Header) int
|
|
||||||
```
|
|
||||||
Returns the timestamp of the given header.
|
|
||||||
|
|
||||||
#### GetVersion
|
|
||||||
```
|
|
||||||
GetVersion(h Header) int
|
|
||||||
```
|
|
||||||
Returns the version of the given header.
|
|
||||||
|
|
||||||
#### GetMerkleroot
|
|
||||||
```
|
|
||||||
GetMerkleRoot(h Header) []byte
|
|
||||||
```
|
|
||||||
Returns the merkle root of the given header.
|
|
||||||
|
|
||||||
#### GetConsensusData
|
|
||||||
```
|
|
||||||
GetConsensusData(h Header) int
|
|
||||||
```
|
|
||||||
Returns the consensus data of the given header.
|
|
||||||
|
|
||||||
#### GetNextConsensus
|
|
||||||
```
|
|
||||||
GetNextConsensus(h Header) []byte
|
|
||||||
```
|
|
||||||
Returns the next consensus of the given header.
|
|
||||||
|
|
||||||
## Input
|
|
||||||
#### GetHash
|
|
||||||
```
|
|
||||||
GetHash(in Input) []byte
|
|
||||||
```
|
|
||||||
Returns the hash field of the given input.
|
|
||||||
|
|
||||||
#### GetIndex
|
|
||||||
```
|
|
||||||
GetIndex(in Input) int
|
|
||||||
```
|
|
||||||
Returns the index field of the given input.
|
|
||||||
|
|
||||||
## Output
|
|
||||||
#### GetAssetID
|
|
||||||
```
|
|
||||||
GetAssetId(out Output) []byte
|
|
||||||
```
|
|
||||||
Returns the asset id field of the given output.
|
|
||||||
|
|
||||||
#### GetValue
|
|
||||||
```
|
|
||||||
GetValue(out Output) int
|
|
||||||
```
|
|
||||||
Returns the value field of the given output.
|
|
||||||
|
|
||||||
#### GetScriptHash
|
|
||||||
```
|
|
||||||
GetScriptHash(out Output) []byte
|
|
||||||
```
|
|
||||||
Returns the script hash field of the given output.
|
|
||||||
|
|
||||||
## Runtime
|
|
||||||
#### CheckWitness
|
|
||||||
```
|
|
||||||
CheckWitness(hash []byte) bool
|
|
||||||
```
|
|
||||||
Verifies if the given hash is the hash of the contract owner.
|
|
||||||
|
|
||||||
#### Log
|
|
||||||
```
|
|
||||||
Log(message string)
|
|
||||||
```
|
|
||||||
Logs the given message.
|
|
||||||
|
|
||||||
#### Notify
|
|
||||||
```
|
|
||||||
Notify(args ...interface{}) int
|
|
||||||
```
|
|
||||||
Notify any number of arguments to the VM.
|
|
||||||
|
|
||||||
#### GetTime
|
|
||||||
```
|
|
||||||
GetTime() int
|
|
||||||
```
|
|
||||||
Returns the current time based on the highest block in the chain.
|
|
||||||
|
|
||||||
#### GetTrigger
|
|
||||||
```
|
|
||||||
GetTrigger() byte
|
|
||||||
```
|
|
||||||
Returns the trigger type of the execution.
|
|
||||||
|
|
||||||
#### Serialize
|
|
||||||
```
|
|
||||||
Serialize(item interface{}) []byte
|
|
||||||
```
|
|
||||||
Serialize the given stack item to a slice of bytes.
|
|
||||||
|
|
||||||
#### Deserialize
|
|
||||||
```
|
|
||||||
Deserialize(data []byte) interface{}
|
|
||||||
```
|
|
||||||
Deserializes the given data to a stack item.
|
|
||||||
|
|
||||||
## Storage
|
|
||||||
#### GetContext
|
|
||||||
```
|
|
||||||
GetContext() Context
|
|
||||||
```
|
|
||||||
Returns the current storage context.
|
|
||||||
|
|
||||||
#### Put
|
|
||||||
```
|
|
||||||
Put(ctx Context, key, value []interface{})
|
|
||||||
```
|
|
||||||
Stores the given value at the given key.
|
|
||||||
|
|
||||||
#### Get
|
|
||||||
```
|
|
||||||
Get(ctx Context, key interface{}) interface{}
|
|
||||||
```
|
|
||||||
Returns the value found at the given key.
|
|
||||||
|
|
||||||
#### Delete
|
|
||||||
```
|
|
||||||
Delete(ctx Context, key interface{})
|
|
||||||
```
|
|
||||||
Delete's the given key from storage.
|
|
||||||
|
|
||||||
#### Find
|
|
||||||
```
|
|
||||||
Find(ctx Context, key interface{}) iterator.Iterator
|
|
||||||
```
|
|
||||||
Find returns an iterator key-values that match the given key.
|
|
||||||
|
|
||||||
## Transaction
|
|
||||||
#### GetHash
|
|
||||||
```
|
|
||||||
GetHash(t Transacfion) []byte
|
|
||||||
```
|
|
||||||
Returns the hash for the given transaction.
|
|
||||||
|
|
||||||
#### GetType
|
|
||||||
```
|
|
||||||
GetType(t Transacfion) byte
|
|
||||||
```
|
|
||||||
Returns the type of the given transaction.
|
|
||||||
|
|
||||||
#### GetAttributes
|
|
||||||
```
|
|
||||||
GetAttributes(t Transacfion) []attribute.Attribute
|
|
||||||
```
|
|
||||||
Returns the attributes of the given transaction.
|
|
||||||
|
|
||||||
#### GetReferences
|
|
||||||
```
|
|
||||||
GetReferences(t Transacfion) interface{}
|
|
||||||
```
|
|
||||||
Returns the references of the given transaction.
|
|
||||||
|
|
||||||
#### GetUnspentCoins
|
|
||||||
```
|
|
||||||
GetUnspentCoins(t Transacfion) interface{}
|
|
||||||
```
|
|
||||||
Returns the unspent coins of the given transaction.
|
|
||||||
|
|
||||||
#### GetOutputs
|
|
||||||
```
|
|
||||||
GetOutputs(t Transacfion) []output.Output
|
|
||||||
```
|
|
||||||
Returns the outputs of the given transaction
|
|
||||||
|
|
||||||
#### GetInputs
|
|
||||||
```
|
|
||||||
GetInputs(t Transacfion) []input.Input
|
|
||||||
```
|
|
||||||
Returns the inputs of the given transaction
|
|
|
@ -16,7 +16,7 @@ var (
|
||||||
"SHA1", "Hash256", "Hash160",
|
"SHA1", "Hash256", "Hash160",
|
||||||
"VerifySignature", "AppCall",
|
"VerifySignature", "AppCall",
|
||||||
"FromAddress", "Equals",
|
"FromAddress", "Equals",
|
||||||
"panic",
|
"panic", "DynAppCall",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1085,14 +1085,23 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
|
||||||
emit.Opcode(c.prog.BinWriter, opcode.HASH160)
|
emit.Opcode(c.prog.BinWriter, opcode.HASH160)
|
||||||
case "VerifySignature":
|
case "VerifySignature":
|
||||||
emit.Opcode(c.prog.BinWriter, opcode.VERIFY)
|
emit.Opcode(c.prog.BinWriter, opcode.VERIFY)
|
||||||
case "AppCall":
|
case "AppCall", "DynAppCall":
|
||||||
numArgs := len(expr.Args) - 1
|
numArgs := len(expr.Args)
|
||||||
|
if name == "AppCall" {
|
||||||
|
numArgs--
|
||||||
|
}
|
||||||
c.emitReverse(numArgs)
|
c.emitReverse(numArgs)
|
||||||
|
|
||||||
emit.Opcode(c.prog.BinWriter, opcode.APPCALL)
|
emit.Opcode(c.prog.BinWriter, opcode.APPCALL)
|
||||||
buf := c.getByteArray(expr.Args[0])
|
var buf []byte
|
||||||
if len(buf) != 20 {
|
if name == "AppCall" {
|
||||||
c.prog.Err = errors.New("invalid script hash")
|
buf = c.getByteArray(expr.Args[0])
|
||||||
|
if len(buf) != 20 {
|
||||||
|
c.prog.Err = errors.New("invalid script hash")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Zeroes for DynAppCall.
|
||||||
|
buf = make([]byte, 20)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.prog.WriteBytes(buf)
|
c.prog.WriteBytes(buf)
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -52,6 +53,19 @@ func TestFromAddress(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAppCall(t *testing.T) {
|
func TestAppCall(t *testing.T) {
|
||||||
|
const srcDynApp = `
|
||||||
|
package foo
|
||||||
|
import "github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
||||||
|
func Main(h []byte) []byte {
|
||||||
|
x := []byte{1, 2}
|
||||||
|
y := []byte{3, 4}
|
||||||
|
result := engine.DynAppCall(h, x, y)
|
||||||
|
return result.([]byte)
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
var hasDynamicInvoke bool
|
||||||
|
|
||||||
srcInner := `
|
srcInner := `
|
||||||
package foo
|
package foo
|
||||||
func Main(a []byte, b []byte) []byte {
|
func Main(a []byte, b []byte) []byte {
|
||||||
|
@ -62,14 +76,31 @@ func TestAppCall(t *testing.T) {
|
||||||
inner, err := compiler.Compile(strings.NewReader(srcInner))
|
inner, err := compiler.Compile(strings.NewReader(srcInner))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
dynapp, err := compiler.Compile(strings.NewReader(srcDynApp))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
ih := hash.Hash160(inner)
|
ih := hash.Hash160(inner)
|
||||||
|
dh := hash.Hash160(dynapp)
|
||||||
getScript := func(u util.Uint160) ([]byte, bool) {
|
getScript := func(u util.Uint160) ([]byte, bool) {
|
||||||
if u.Equals(ih) {
|
if u.Equals(ih) {
|
||||||
return inner, true
|
return inner, true
|
||||||
}
|
}
|
||||||
|
if u.Equals(dh) {
|
||||||
|
return dynapp, hasDynamicInvoke
|
||||||
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dynEntryScript := `
|
||||||
|
package foo
|
||||||
|
import "github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
||||||
|
func Main(h []byte) interface{} {
|
||||||
|
return engine.AppCall(` + fmt.Sprintf("%#v", dh.BytesBE()) + `, h)
|
||||||
|
}
|
||||||
|
`
|
||||||
|
dynentry, err := compiler.Compile(strings.NewReader(dynEntryScript))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
t.Run("valid script", func(t *testing.T) {
|
t.Run("valid script", func(t *testing.T) {
|
||||||
src := getAppCallScript(fmt.Sprintf("%#v", ih.BytesBE()))
|
src := getAppCallScript(fmt.Sprintf("%#v", ih.BytesBE()))
|
||||||
v := vmAndCompile(t, src)
|
v := vmAndCompile(t, src)
|
||||||
|
@ -118,6 +149,38 @@ func TestAppCall(t *testing.T) {
|
||||||
|
|
||||||
assertResult(t, v, []byte{1, 2, 3, 4})
|
assertResult(t, v, []byte{1, 2, 3, 4})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("dynamic", func(t *testing.T) {
|
||||||
|
t.Run("valid script", func(t *testing.T) {
|
||||||
|
hasDynamicInvoke = true
|
||||||
|
v := vm.New()
|
||||||
|
v.Load(dynentry)
|
||||||
|
v.SetScriptGetter(getScript)
|
||||||
|
v.Estack().PushVal(ih.BytesBE())
|
||||||
|
|
||||||
|
require.NoError(t, v.Run())
|
||||||
|
|
||||||
|
assertResult(t, v, []byte{1, 2, 3, 4})
|
||||||
|
})
|
||||||
|
t.Run("invalid script", func(t *testing.T) {
|
||||||
|
hasDynamicInvoke = true
|
||||||
|
v := vm.New()
|
||||||
|
v.Load(dynentry)
|
||||||
|
v.SetScriptGetter(getScript)
|
||||||
|
v.Estack().PushVal([]byte{1})
|
||||||
|
|
||||||
|
require.Error(t, v.Run())
|
||||||
|
})
|
||||||
|
t.Run("no dynamic invoke", func(t *testing.T) {
|
||||||
|
hasDynamicInvoke = false
|
||||||
|
v := vm.New()
|
||||||
|
v.Load(dynentry)
|
||||||
|
v.SetScriptGetter(getScript)
|
||||||
|
v.Estack().PushVal(ih.BytesBE())
|
||||||
|
|
||||||
|
require.Error(t, v.Run())
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAppCallScript(h string) string {
|
func getAppCallScript(h string) string {
|
||||||
|
|
|
@ -1,12 +1,30 @@
|
||||||
package compiler
|
package compiler
|
||||||
|
|
||||||
var syscalls = map[string]map[string]string{
|
var syscalls = map[string]map[string]string{
|
||||||
|
"account": {
|
||||||
|
"GetBalance": "Neo.Account.GetBalance",
|
||||||
|
"GetScriptHash": "Neo.Account.GetScriptHash",
|
||||||
|
"GetVotes": "Neo.Account.GetVotes",
|
||||||
|
"IsStandard": "Neo.Account.IsStandard",
|
||||||
|
},
|
||||||
|
"attribute": {
|
||||||
|
"GetUsage": "Neo.Attribute.GetUsage",
|
||||||
|
"GetData": "Neo.Attribute.GetData",
|
||||||
|
},
|
||||||
|
"enumerator": {
|
||||||
|
"Concat": "Neo.Enumerator.Concat",
|
||||||
|
"Create": "Neo.Enumerator.Create",
|
||||||
|
"Next": "Neo.Enumerator.Next",
|
||||||
|
"Value": "Neo.Enumerator.Value",
|
||||||
|
},
|
||||||
"storage": {
|
"storage": {
|
||||||
"GetContext": "Neo.Storage.GetContext",
|
"ConvertContextToReadOnly": "Neo.StorageContext.AsReadOnly",
|
||||||
"Put": "Neo.Storage.Put",
|
"Delete": "Neo.Storage.Delete",
|
||||||
"Get": "Neo.Storage.Get",
|
"Find": "Neo.Storage.Find",
|
||||||
"Delete": "Neo.Storage.Delete",
|
"Get": "Neo.Storage.Get",
|
||||||
"Find": "Neo.Storage.Find",
|
"GetContext": "Neo.Storage.GetContext",
|
||||||
|
"GetReadOnlyContext": "Neo.Storage.GetReadOnlyContext",
|
||||||
|
"Put": "Neo.Storage.Put",
|
||||||
},
|
},
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"GetTrigger": "Neo.Runtime.GetTrigger",
|
"GetTrigger": "Neo.Runtime.GetTrigger",
|
||||||
|
@ -18,14 +36,15 @@ var syscalls = map[string]map[string]string{
|
||||||
"Deserialize": "Neo.Runtime.Deserialize",
|
"Deserialize": "Neo.Runtime.Deserialize",
|
||||||
},
|
},
|
||||||
"blockchain": {
|
"blockchain": {
|
||||||
"GetHeight": "Neo.Blockchain.GetHeight",
|
"GetAccount": "Neo.Blockchain.GetAccount",
|
||||||
"GetHeader": "Neo.Blockchain.GetHeader",
|
"GetAsset": "Neo.Blockchain.GetAsset",
|
||||||
"GetBlock": "Neo.Blockchain.GetBlock",
|
"GetBlock": "Neo.Blockchain.GetBlock",
|
||||||
"GetTransaction": "Neo.Blockchain.GetTransaction",
|
"GetContract": "Neo.Blockchain.GetContract",
|
||||||
"GetContract": "Neo.Blockchain.GetContract",
|
"GetHeader": "Neo.Blockchain.GetHeader",
|
||||||
"GetAccount": "Neo.Blockchain.GetAccount",
|
"GetHeight": "Neo.Blockchain.GetHeight",
|
||||||
"GetValidators": "Neo.Blockchain.GetValidators",
|
"GetTransaction": "Neo.Blockchain.GetTransaction",
|
||||||
"GetAsset": "Neo.Blockchain.GetAsset",
|
"GetTransactionHeight": "Neo.Blockchain.GetTransactionHeight",
|
||||||
|
"GetValidators": "Neo.Blockchain.GetValidators",
|
||||||
},
|
},
|
||||||
"header": {
|
"header": {
|
||||||
"GetIndex": "Neo.Header.GetIndex",
|
"GetIndex": "Neo.Header.GetIndex",
|
||||||
|
@ -43,20 +62,25 @@ var syscalls = map[string]map[string]string{
|
||||||
"GetTransaction": "Neo.Block.GetTransaction",
|
"GetTransaction": "Neo.Block.GetTransaction",
|
||||||
},
|
},
|
||||||
"transaction": {
|
"transaction": {
|
||||||
"GetHash": "Neo.Transaction.GetHash",
|
"GetAttributes": "Neo.Transaction.GetAttributes",
|
||||||
"GetType": "Neo.Transaction.GetType",
|
"GetHash": "Neo.Transaction.GetHash",
|
||||||
"GetAttributes": "Neo.Transaction.GetAttributes",
|
"GetInputs": "Neo.Transaction.GetInputs",
|
||||||
"GetInputs": "Neo.Transaction.GetInputs",
|
"GetOutputs": "Neo.Transaction.GetOutputs",
|
||||||
"GetOutputs": "Neo.Transaction.GetOutputs",
|
"GetReferences": "Neo.Transaction.GetReferences",
|
||||||
"GetReferences": "Neo.Transaction.GetReferences",
|
"GetScript": "Neo.InvocationTransaction.GetScript",
|
||||||
"GetUnspentCoins": "Neo.Transaction.GetUnspentCoins",
|
"GetType": "Neo.Transaction.GetType",
|
||||||
"GetScript": "Neo.Transaction.GetScript",
|
"GetWitnesses": "Neo.Transaction.GetWitnesses",
|
||||||
},
|
},
|
||||||
"asset": {
|
"asset": {
|
||||||
|
"Create": "Neo.Asset.Create",
|
||||||
|
"GetAdmin": "Neo.Asset.GetAdmin",
|
||||||
|
"GetAmount": "Neo.Asset.GetAmount",
|
||||||
"GetAssetID": "Neo.Asset.GetAssetID",
|
"GetAssetID": "Neo.Asset.GetAssetID",
|
||||||
"GetAssetType": "Neo.Asset.GetAssetType",
|
"GetAssetType": "Neo.Asset.GetAssetType",
|
||||||
"GetAmount": "Neo.Asset.GetAmount",
|
"GetAvailable": "Neo.Asset.GetAvailable",
|
||||||
"Create": "Neo.Asset.Create",
|
"GetIssuer": "Neo.Asset.GetIssuer",
|
||||||
|
"GetOwner": "Neo.Asset.GetOwner",
|
||||||
|
"GetPrecision": "Neo.Asset.GetPrecision",
|
||||||
"Renew": "Neo.Asset.Renew",
|
"Renew": "Neo.Asset.Renew",
|
||||||
},
|
},
|
||||||
"contract": {
|
"contract": {
|
||||||
|
@ -83,6 +107,7 @@ var syscalls = map[string]map[string]string{
|
||||||
"GetExecutingScriptHash": "System.ExecutionEngine.GetExecutingScriptHash",
|
"GetExecutingScriptHash": "System.ExecutionEngine.GetExecutingScriptHash",
|
||||||
},
|
},
|
||||||
"iterator": {
|
"iterator": {
|
||||||
|
"Concat": "Neo.Iterator.Concat",
|
||||||
"Create": "Neo.Iterator.Create",
|
"Create": "Neo.Iterator.Create",
|
||||||
"Key": "Neo.Iterator.Key",
|
"Key": "Neo.Iterator.Key",
|
||||||
"Keys": "Neo.Iterator.Keys",
|
"Keys": "Neo.Iterator.Keys",
|
||||||
|
@ -90,4 +115,7 @@ var syscalls = map[string]map[string]string{
|
||||||
"Value": "Neo.Iterator.Value",
|
"Value": "Neo.Iterator.Value",
|
||||||
"Values": "Neo.Iterator.Values",
|
"Values": "Neo.Iterator.Values",
|
||||||
},
|
},
|
||||||
|
"witness": {
|
||||||
|
"GetVerificationScript": "Neo.Witness.GetVerificationScript",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,7 +236,14 @@ func (ic *interopContext) witnessGetVerificationScript(v *vm.VM) error {
|
||||||
|
|
||||||
// bcGetValidators returns validators.
|
// bcGetValidators returns validators.
|
||||||
func (ic *interopContext) bcGetValidators(v *vm.VM) error {
|
func (ic *interopContext) bcGetValidators(v *vm.VM) error {
|
||||||
validators := ic.dao.GetValidators()
|
valStates := ic.dao.GetValidators()
|
||||||
|
if len(valStates) > vm.MaxArraySize {
|
||||||
|
return errors.New("too many validators")
|
||||||
|
}
|
||||||
|
validators := make([]vm.StackItem, 0, len(valStates))
|
||||||
|
for _, val := range valStates {
|
||||||
|
validators = append(validators, vm.NewByteArrayItem(val.PublicKey.Bytes()))
|
||||||
|
}
|
||||||
v.Estack().PushVal(validators)
|
v.Estack().PushVal(validators)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -575,8 +575,12 @@ func (ic *interopContext) contractGetStorageContext(v *vm.VM) error {
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("%T is not a contract state", cs)
|
return fmt.Errorf("%T is not a contract state", cs)
|
||||||
}
|
}
|
||||||
contractState, err := ic.dao.GetContractState(cs.ScriptHash())
|
_, err := ic.dao.GetContractState(cs.ScriptHash())
|
||||||
if contractState == nil || err != nil {
|
if err != nil {
|
||||||
|
return fmt.Errorf("non-existent contract")
|
||||||
|
}
|
||||||
|
_, err = ic.lowerDao.GetContractState(cs.ScriptHash())
|
||||||
|
if err == nil {
|
||||||
return fmt.Errorf("contract was not created in this transaction")
|
return fmt.Errorf("contract was not created in this transaction")
|
||||||
}
|
}
|
||||||
stc := &StorageContext{
|
stc := &StorageContext{
|
||||||
|
|
|
@ -27,6 +27,7 @@ type interopContext struct {
|
||||||
block *block.Block
|
block *block.Block
|
||||||
tx *transaction.Transaction
|
tx *transaction.Transaction
|
||||||
dao *dao.Cached
|
dao *dao.Cached
|
||||||
|
lowerDao dao.DAO
|
||||||
notifications []state.NotificationEvent
|
notifications []state.NotificationEvent
|
||||||
log *zap.Logger
|
log *zap.Logger
|
||||||
}
|
}
|
||||||
|
@ -34,7 +35,7 @@ type interopContext struct {
|
||||||
func newInteropContext(trigger trigger.Type, bc Blockchainer, d dao.DAO, block *block.Block, tx *transaction.Transaction, log *zap.Logger) *interopContext {
|
func newInteropContext(trigger trigger.Type, bc Blockchainer, d dao.DAO, block *block.Block, tx *transaction.Transaction, log *zap.Logger) *interopContext {
|
||||||
dao := dao.NewCached(d)
|
dao := dao.NewCached(d)
|
||||||
nes := make([]state.NotificationEvent, 0)
|
nes := make([]state.NotificationEvent, 0)
|
||||||
return &interopContext{bc, trigger, block, tx, dao, nes, log}
|
return &interopContext{bc, trigger, block, tx, dao, d, nes, log}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SpawnVM returns a VM with script getter and interop functions set
|
// SpawnVM returns a VM with script getter and interop functions set
|
||||||
|
|
|
@ -1,23 +1,43 @@
|
||||||
|
/*
|
||||||
|
Package account provides getter functions for Account interop structure.
|
||||||
|
To use these functions you need to get an Account first via blockchain.GetAccount
|
||||||
|
call.
|
||||||
|
*/
|
||||||
package account
|
package account
|
||||||
|
|
||||||
// Package account provides function signatures that can be used inside
|
// Account represents NEO account type that is used in interop functions, it's
|
||||||
// smart contracts that are written in the neo-go framework.
|
// an opaque data structure that you can get data from only using functions from
|
||||||
|
// this package. It's similar in function to the Account class in the Neo .net
|
||||||
// Account stubs a NEO account type.
|
// framework.
|
||||||
type Account struct{}
|
type Account struct{}
|
||||||
|
|
||||||
// GetScriptHash returns the script hash of the given account.
|
// GetScriptHash returns the script hash of the given Account (20 bytes in BE
|
||||||
|
// representation). It uses `Neo.Account.GetBalance` syscall internally.
|
||||||
func GetScriptHash(a Account) []byte {
|
func GetScriptHash(a Account) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVotes returns the votes of the given account which should be a slice of
|
// GetVotes returns current votes of the given account represented as a slice of
|
||||||
// public key raw bytes.
|
// public keys. Keys are serialized into byte slices in their compressed form (33
|
||||||
|
// bytes long each). This function uses `Neo.Account.GetVotes` syscall
|
||||||
|
// internally.
|
||||||
func GetVotes(a Account) [][]byte {
|
func GetVotes(a Account) [][]byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBalance returns the balance of for the given account and asset id.
|
// GetBalance returns current balance of the given asset (by its ID, 256 bit
|
||||||
|
// hash in BE form) for the given account. Only native UTXO assets can be
|
||||||
|
// queiried via this function, for NEP-5 ones use respective contract calls.
|
||||||
|
// The value returned is represented as an integer with original value multiplied
|
||||||
|
// by 10⁸ so you can work with fractional parts of the balance too. This function
|
||||||
|
// uses `Neo.Account.GetBalance` syscall internally.
|
||||||
func GetBalance(a Account, assetID []byte) int {
|
func GetBalance(a Account, assetID []byte) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsStandard checks whether given account uses standard (CHECKSIG or
|
||||||
|
// CHECKMULTISIG) contract. It only works for deployed contracts and uses
|
||||||
|
// `Neo.Account.IsStandard` syscall internally.
|
||||||
|
func IsStandard(a Account) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
|
@ -1,53 +1,97 @@
|
||||||
|
/*
|
||||||
|
Package asset provides functions to work with regular UTXO assets (like NEO or GAS).
|
||||||
|
Mostly these are getters for Asset structure, but you can also create new assets
|
||||||
|
and renew them (although it's recommended to use NEP-5 standard for new tokens).
|
||||||
|
*/
|
||||||
package asset
|
package asset
|
||||||
|
|
||||||
// Package asset provides function signatures that can be used inside
|
// Asset represents NEO asset type that is used in interop functions, it's
|
||||||
// smart contracts that are written in the neo-go framework.
|
// an opaque data structure that you can get data from only using functions from
|
||||||
|
// this package. It's similar in function to the Asset class in the Neo .net
|
||||||
// Asset stubs a NEO asset type.
|
// framework. To be able to use it you either need to get an existing Asset via
|
||||||
|
// blockchain.GetAsset function or create a new one via Create.
|
||||||
type Asset struct{}
|
type Asset struct{}
|
||||||
|
|
||||||
// GetAssetID returns the id of the given asset.
|
// GetAssetID returns ID (256-bit ID of Register transaction for this asset in BE
|
||||||
|
// representation) of the given asset. It uses `Neo.Asset.GetAssetId` syscall
|
||||||
|
// internally.
|
||||||
func GetAssetID(a Asset) []byte {
|
func GetAssetID(a Asset) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAssetType returns the type of the given asset.
|
// GetAssetType returns type of the given asset as a byte value. The value
|
||||||
|
// returned can be interpreted as a bit field with the following meaning:
|
||||||
|
// CreditFlag = 0x40
|
||||||
|
// DutyFlag = 0x80
|
||||||
|
// SystemShare = 0x00
|
||||||
|
// SystemCoin = 0x01
|
||||||
|
// Currency = 0x08
|
||||||
|
// Share = DutyFlag | 0x10
|
||||||
|
// Invoice = DutyFlag | 0x18
|
||||||
|
// Token = CreditFlag | 0x20
|
||||||
|
// It uses `Neo.Asset.GetAssetType` syscall internally.
|
||||||
func GetAssetType(a Asset) byte {
|
func GetAssetType(a Asset) byte {
|
||||||
return 0x00
|
return 0x00
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAmount returns the amount of the given asset.
|
// GetAmount returns the total amount of the given asset as an integer
|
||||||
|
// multiplied by 10⁸. This value is the maximum possible circulating quantity of
|
||||||
|
// Asset. The function uses `Neo.Asset.GetAmount` syscall internally.
|
||||||
func GetAmount(a Asset) int {
|
func GetAmount(a Asset) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAvailable returns the available of the given asset.
|
// GetAvailable returns the amount of Asset currently available on the
|
||||||
|
// blockchain. It uses the same encoding as the result of GetAmount and its
|
||||||
|
// value can never exceed the value returned by GetAmount. This function uses
|
||||||
|
// `Neo.Asset.GetAvailable` syscall internally.
|
||||||
func GetAvailable(a Asset) int {
|
func GetAvailable(a Asset) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPrecision returns the precision of the given asset.
|
// GetPrecision returns precision of the given Asset. It uses
|
||||||
|
// `Neo.Asset.GetPrecision` syscall internally.
|
||||||
func GetPrecision(a Asset) byte {
|
func GetPrecision(a Asset) byte {
|
||||||
return 0x00
|
return 0x00
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOwner returns the owner of the given asset.
|
// GetOwner returns the owner of the given Asset. It's represented as a
|
||||||
|
// serialized (in compressed form) public key (33 bytes long). This function
|
||||||
|
// uses `Neo.Asset.GetOwner` syscall internally.
|
||||||
func GetOwner(a Asset) []byte {
|
func GetOwner(a Asset) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAdmin returns the admin of the given asset.
|
// GetAdmin returns the admin of the given Asset represented as a 160 bit hash
|
||||||
|
// in BE form (contract script hash). Admin can modify attributes of this Asset.
|
||||||
|
// This function uses `Neo.Asset.GetAdmin` syscall internally.
|
||||||
func GetAdmin(a Asset) []byte {
|
func GetAdmin(a Asset) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetIssuer returns the issuer of the given asset.
|
// GetIssuer returns the issuer of the given Asset represented as a 160 bit hash
|
||||||
|
// in BE form (contract script hash). Issuer can issue new tokens for this Asset.
|
||||||
|
// This function uses `Neo.Asset.GetIssuer` syscall internally.
|
||||||
func GetIssuer(a Asset) []byte {
|
func GetIssuer(a Asset) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create registers a new asset on the blockchain.
|
// Create registers a new asset on the blockchain (similar to old Register
|
||||||
func Create(assetType byte, name string, amount int, precision byte, owner, admin, issuer []byte) {}
|
// transaction). `assetType` parameter has the same set of possible values as
|
||||||
|
// GetAssetType result, `amount` must be multiplied by 10⁸, `precision` limits
|
||||||
|
// the smallest possible amount of new Asset to 10⁻ⁿ (where n is precision which
|
||||||
|
// can't exceed 8), `owner` is a public key of the owner in compressed serialized
|
||||||
|
// form (33 bytes), `admin` and `issuer` should be represented as 20-byte slices
|
||||||
|
// storing 160-bit hash in BE form. Created Asset is set to expire in one year,
|
||||||
|
// so you need to renew it in time. If successful, this function returns a new
|
||||||
|
// Asset. It uses `Neo.Asset.Create` syscall internally.
|
||||||
|
func Create(assetType byte, name string, amount int, precision byte, owner, admin, issuer []byte) Asset {
|
||||||
|
return Asset{}
|
||||||
|
}
|
||||||
|
|
||||||
// Renew renews the existence of an asset by the given years.
|
// Renew renews (make available for use) existing asset by the specified number
|
||||||
func Renew(asset Asset, years int) {}
|
// of years. It returns the last block number when this asset will be active.
|
||||||
|
// It uses `Neo.Asset.Renew` syscall internally.
|
||||||
|
func Renew(asset Asset, years int) int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
|
@ -1,17 +1,65 @@
|
||||||
|
/*
|
||||||
|
Package attribute provides getters for transaction attributes.
|
||||||
|
*/
|
||||||
package attribute
|
package attribute
|
||||||
|
|
||||||
// Package attribute provides function signatures that can be used inside
|
// Attribute represents transaction attribute in Neo, it's an opaque data
|
||||||
// smart contracts that are written in the neo-go framework.
|
// structure that you can get data from only using functions from this package.
|
||||||
|
// It's similar in function to the TransactionAttribute class in the Neo .net
|
||||||
// Attribute stubs a NEO transaction attribute type.
|
// framework. To use it you need to get is first using transaction.GetAttributes.
|
||||||
type Attribute struct{}
|
type Attribute struct{}
|
||||||
|
|
||||||
// GetUsage returns the usage of the given attribute.
|
// GetUsage returns the Usage field of the given attribute. It is an enumeration
|
||||||
|
// with the following possible values:
|
||||||
|
// ContractHash = 0x00
|
||||||
|
// ECDH02 = 0x02
|
||||||
|
// ECDH03 = 0x03
|
||||||
|
// Script = 0x20
|
||||||
|
// Vote = 0x30
|
||||||
|
// CertURL = 0x80
|
||||||
|
// DescriptionURL = 0x81
|
||||||
|
// Description = 0x90
|
||||||
|
//
|
||||||
|
// Hash1 = 0xa1
|
||||||
|
// Hash2 = 0xa2
|
||||||
|
// Hash3 = 0xa3
|
||||||
|
// Hash4 = 0xa4
|
||||||
|
// Hash5 = 0xa5
|
||||||
|
// Hash6 = 0xa6
|
||||||
|
// Hash7 = 0xa7
|
||||||
|
// Hash8 = 0xa8
|
||||||
|
// Hash9 = 0xa9
|
||||||
|
// Hash10 = 0xaa
|
||||||
|
// Hash11 = 0xab
|
||||||
|
// Hash12 = 0xac
|
||||||
|
// Hash13 = 0xad
|
||||||
|
// Hash14 = 0xae
|
||||||
|
// Hash15 = 0xaf
|
||||||
|
//
|
||||||
|
// Remark = 0xf0
|
||||||
|
// Remark1 = 0xf1
|
||||||
|
// Remark2 = 0xf2
|
||||||
|
// Remark3 = 0xf3
|
||||||
|
// Remark4 = 0xf4
|
||||||
|
// Remark5 = 0xf5
|
||||||
|
// Remark6 = 0xf6
|
||||||
|
// Remark7 = 0xf7
|
||||||
|
// Remark8 = 0xf8
|
||||||
|
// Remark9 = 0xf9
|
||||||
|
// Remark10 = 0xfa
|
||||||
|
// Remark11 = 0xfb
|
||||||
|
// Remark12 = 0xfc
|
||||||
|
// Remark13 = 0xfd
|
||||||
|
// Remark14 = 0xfe
|
||||||
|
// Remark15 = 0xff
|
||||||
|
// This function uses `Neo.Attribute.GetUsage` syscall internally.
|
||||||
func GetUsage(attr Attribute) byte {
|
func GetUsage(attr Attribute) byte {
|
||||||
return 0x00
|
return 0x00
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetData returns the data of the given attribute.
|
// GetData returns the data of the given attribute, exact interpretation of this
|
||||||
|
// data depends on attribute's Usage type. It uses `Neo.Attribute.GetData`
|
||||||
|
// syscall internally.
|
||||||
func GetData(attr Attribute) []byte {
|
func GetData(attr Attribute) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,30 @@
|
||||||
|
/*
|
||||||
|
Package block provides getters for Neo Block structure.
|
||||||
|
*/
|
||||||
package block
|
package block
|
||||||
|
|
||||||
import "github.com/nspcc-dev/neo-go/pkg/interop/transaction"
|
import "github.com/nspcc-dev/neo-go/pkg/interop/transaction"
|
||||||
|
|
||||||
// Package block provides function signatures that can be used inside
|
// Block represents a NEO block, it's an opaque data structure that you can get
|
||||||
// smart contracts that are written in the neo-go framework.
|
// data from only using functions from this package. It's similar in function to
|
||||||
|
// the Block class in the Neo .net framework. To use it you need to get it via
|
||||||
// Block stubs a NEO block type.
|
// blockchain.GetBlock function call.
|
||||||
type Block struct{}
|
type Block struct{}
|
||||||
|
|
||||||
// GetTransactionCount returns the number of recorded transactions in the given block.
|
// GetTransactionCount returns the number of recorded transactions in the given
|
||||||
|
// block. It uses `Neo.Block.GetTransactionCount` syscall internally.
|
||||||
func GetTransactionCount(b Block) int {
|
func GetTransactionCount(b Block) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTransactions returns a slice of transactions recorded in the given block.
|
// GetTransactions returns a slice of transactions recorded in the given block.
|
||||||
|
// It uses `Neo.Block.GetTransactions` syscall internally.
|
||||||
func GetTransactions(b Block) []transaction.Transaction {
|
func GetTransactions(b Block) []transaction.Transaction {
|
||||||
return []transaction.Transaction{}
|
return []transaction.Transaction{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTransaction returns a transaction from the given a block hash of the
|
// GetTransaction returns transaction from the given block by its index. It
|
||||||
// transaction.
|
// uses `Neo.Block.GetTransaction` syscall internally.
|
||||||
func GetTransaction(b Block, hash []byte) transaction.Transaction {
|
func GetTransaction(b Block, index int) transaction.Transaction {
|
||||||
return transaction.Transaction{}
|
return transaction.Transaction{}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
/*
|
||||||
|
Package blockchain provides functions to access various blockchain data.
|
||||||
|
*/
|
||||||
package blockchain
|
package blockchain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -9,45 +12,72 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/interop/transaction"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Package blockchain provides function signatures that can be used inside
|
// GetHeight returns current block height (index of the last accepted block).
|
||||||
// smart contracts that are written in the neo-go framework.
|
// Note that when transaction is being run as a part of new block this block is
|
||||||
|
// considered as not yet accepted (persisted) and thus you'll get an index of
|
||||||
// GetHeight returns the height of te block recorded in the current execution scope.
|
// the previous (already accepted) block. This function uses
|
||||||
|
// `Neo.Blockchain.GetHeight` syscall.
|
||||||
func GetHeight() int {
|
func GetHeight() int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHeader returns the header found by the given hash or index.
|
// GetHeader returns header found by the given hash (256 bit hash in BE format
|
||||||
|
// represented as a slice of 32 bytes) or index (integer). Refer to the `header`
|
||||||
|
// package for possible uses of returned structure. This function uses
|
||||||
|
// `Neo.Blockchain.GetHeader` syscall.
|
||||||
func GetHeader(heightOrHash interface{}) header.Header {
|
func GetHeader(heightOrHash interface{}) header.Header {
|
||||||
return header.Header{}
|
return header.Header{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlock returns the block found by the given hash or index.
|
// GetBlock returns block found by the given hash or index (with the same
|
||||||
|
// encoding as for GetHeader). Refer to the `block` package for possible uses
|
||||||
|
// of returned structure. This function uses `Neo.Blockchain.GetBlock` syscall.
|
||||||
func GetBlock(heightOrHash interface{}) block.Block {
|
func GetBlock(heightOrHash interface{}) block.Block {
|
||||||
return block.Block{}
|
return block.Block{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTransaction returns the transaction found by the given hash.
|
// GetTransaction returns transaction found by the given (256 bit in BE format
|
||||||
|
// represented as a slice of 32 bytes). Refer to the `transaction` package for
|
||||||
|
// possible uses of returned structure. This function uses
|
||||||
|
// `Neo.Blockchain.GetTransaction` syscall.
|
||||||
func GetTransaction(hash []byte) transaction.Transaction {
|
func GetTransaction(hash []byte) transaction.Transaction {
|
||||||
return transaction.Transaction{}
|
return transaction.Transaction{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetContract returns the contract found by the given script hash.
|
// GetTransactionHeight returns transaction's height (index of the block that
|
||||||
|
// includes it) by the given ID (256 bit in BE format represented as a slice of
|
||||||
|
// 32 bytes). This function uses `Neo.Blockchain.GetTransactionHeight` syscall.
|
||||||
|
func GetTransactionHeight(hash []byte) int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetContract returns contract found by the given script hash (160 bit in BE
|
||||||
|
// format represented as a slice of 20 bytes). Refer to the `contract` package
|
||||||
|
// for details on how to use the returned structure. This function uses
|
||||||
|
// `Neo.Blockchain.GetContract` syscall.
|
||||||
func GetContract(scriptHash []byte) contract.Contract {
|
func GetContract(scriptHash []byte) contract.Contract {
|
||||||
return contract.Contract{}
|
return contract.Contract{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccount returns the account found by the given script hash.
|
// GetAccount returns account found by the given script hash (160 bit in BE
|
||||||
|
// format represented as a slice of 20 bytes). Refer to the `account` package
|
||||||
|
// for details on how to use the returned structure. This function uses
|
||||||
|
// `Neo.Blockchain.GetAccount` syscall.
|
||||||
func GetAccount(scriptHash []byte) account.Account {
|
func GetAccount(scriptHash []byte) account.Account {
|
||||||
return account.Account{}
|
return account.Account{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetValidators returns a slice of validator addresses.
|
// GetValidators returns a slice of current validators public keys represented
|
||||||
|
// as a compressed serialized byte slice (33 bytes long). This function uses
|
||||||
|
// `Neo.Blockchain.GetValidators` syscall.
|
||||||
func GetValidators() [][]byte {
|
func GetValidators() [][]byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAsset returns the asset found by the given asset id.
|
// GetAsset returns asset found by the given asset ID (256 bit in BE format
|
||||||
|
// represented as a slice of 32 bytes). Refer to the `asset` package for
|
||||||
|
// possible uses of returned structure. This function uses
|
||||||
|
// `Neo.Blockchain.GetAsset` syscall.
|
||||||
func GetAsset(assetID []byte) asset.Asset {
|
func GetAsset(assetID []byte) asset.Asset {
|
||||||
return asset.Asset{}
|
return asset.Asset{}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +1,85 @@
|
||||||
|
/*
|
||||||
|
Package contract provides functions to work with contracts.
|
||||||
|
*/
|
||||||
package contract
|
package contract
|
||||||
|
|
||||||
import "github.com/nspcc-dev/neo-go/pkg/interop/storage"
|
import "github.com/nspcc-dev/neo-go/pkg/interop/storage"
|
||||||
|
|
||||||
// Package contract provides function signatures that can be used inside
|
// Contract represents a Neo contract and is used in interop functions. It's
|
||||||
// smart contracts that are written in the neo-go framework.
|
// an opaque data structure that you can manipulate with using functions from
|
||||||
|
// this package. It's similar in function to the Contract class in the Neo .net
|
||||||
// Contract stubs a NEO contract type.
|
// framework.
|
||||||
type Contract struct{}
|
type Contract struct{}
|
||||||
|
|
||||||
// GetScript returns the script of the given contract.
|
// GetScript returns the script of the given contract. It uses
|
||||||
|
// `Neo.Contract.GetScript` syscall.
|
||||||
func GetScript(c Contract) []byte {
|
func GetScript(c Contract) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsPayable returns whether the given contract is payable.
|
// IsPayable returns whether the given contract is payable (able to accept
|
||||||
|
// asset transfers to its address). It uses `Neo.Contract.IsPayable` syscall.
|
||||||
func IsPayable(c Contract) bool {
|
func IsPayable(c Contract) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetStorageContext returns the storage context for the given contract.
|
// GetStorageContext returns storage context for the given contract. It only
|
||||||
|
// works for contracts created in this transaction (so you can't take a storage
|
||||||
|
// context for arbitrary contract). Refer to the `storage` package on how to
|
||||||
|
// use this context. This function uses `Neo.Contract.GetStorageContext` syscall.
|
||||||
func GetStorageContext(c Contract) storage.Context {
|
func GetStorageContext(c Contract) storage.Context {
|
||||||
return storage.Context{}
|
return storage.Context{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates a new contract.
|
// Create creates a new contract using a set of input parameters:
|
||||||
// @FIXME What is the type of the returnType here?
|
// script contract's bytecode (limited in length by 1M)
|
||||||
|
// params contract's input parameter types, one byte per parameter, see
|
||||||
|
// ParamType in the `smartcontract` package for value
|
||||||
|
// definitions. Maximum number of parameters: 252.
|
||||||
|
// returnType return value type, also a ParamType constant
|
||||||
|
// properties bit field with contract's permissions (storage, dynamic
|
||||||
|
// invoke, payable), see PropertyState in the `smartcontract`
|
||||||
|
// package
|
||||||
|
// name human-readable contract name (no longer than 252 bytes)
|
||||||
|
// version human-readable contract version (no longer than 252 bytes)
|
||||||
|
// author contract's author (no longer than 252 bytes)
|
||||||
|
// email contract's author/support e-mail (no longer than 252 bytes)
|
||||||
|
// description human-readable contract description (no longer than 64K bytes)
|
||||||
|
// It returns this new created Contract when successful (and fails transaction
|
||||||
|
// if not). It uses `Neo.Contract.Create` syscall.
|
||||||
func Create(
|
func Create(
|
||||||
script []byte,
|
script []byte,
|
||||||
params []interface{},
|
params []byte,
|
||||||
returnType byte,
|
returnType byte,
|
||||||
properties interface{},
|
properties byte,
|
||||||
name,
|
name,
|
||||||
version,
|
version,
|
||||||
author,
|
author,
|
||||||
email,
|
email,
|
||||||
description string) {
|
description string) Contract {
|
||||||
|
return Contract{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate migrates a new contract.
|
// Migrate migrates calling contract (that is the one that calls Migrate) to
|
||||||
// @FIXME What is the type of the returnType here?
|
// the new contract. Its parameters have exactly the same semantics as for
|
||||||
|
// Create. The old contract will be deleted by this call, if it has any storage
|
||||||
|
// associated it will be migrated to the new contract. New contract is returned.
|
||||||
|
// This function uses `Neo.Contract.Migrate` syscall.
|
||||||
func Migrate(
|
func Migrate(
|
||||||
script []byte,
|
script []byte,
|
||||||
params []interface{},
|
params []byte,
|
||||||
returnType byte,
|
returnType byte,
|
||||||
properties interface{},
|
properties byte,
|
||||||
name,
|
name,
|
||||||
version,
|
version,
|
||||||
author,
|
author,
|
||||||
email,
|
email,
|
||||||
description string) {
|
description string) Contract {
|
||||||
|
return Contract{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy deletes a contract that is registered on the blockchain.
|
// Destroy deletes calling contract (the one that calls Destroy) from the
|
||||||
func Destroy(c Contract) {}
|
// blockchain, so it's only possible to do that from the contract itself and
|
||||||
|
// not by any outside code. When contract is deleted all associated storage
|
||||||
|
// items are deleted too. This function uses `Neo.Contract.Destroy` syscall.
|
||||||
|
func Destroy() {}
|
||||||
|
|
|
@ -1,29 +1,32 @@
|
||||||
|
/*
|
||||||
|
Package crypto provides an interface to VM cryptographic instructions.
|
||||||
|
*/
|
||||||
package crypto
|
package crypto
|
||||||
|
|
||||||
// Package crypto provides function signatures that can be used inside
|
// SHA1 computes SHA1 hash of b. It uses `SHA1` VM instruction.
|
||||||
// smart contracts that are written in the neo-go framework.
|
|
||||||
|
|
||||||
// SHA1 computes the sha1 hash of b.
|
|
||||||
func SHA1(b []byte) []byte {
|
func SHA1(b []byte) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SHA256 computes the sha256 hash of b.
|
// SHA256 computes SHA256 hash of b. It uses `SHA256` VM instruction.
|
||||||
func SHA256(b []byte) []byte {
|
func SHA256(b []byte) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hash160 computes the sha256 + ripemd160 of b.
|
// Hash160 computes SHA256 + RIPEMD-160 of b, which is commonly used for
|
||||||
|
// script hashing and address generation. It uses `HASH160` VM instruction.
|
||||||
func Hash160(b []byte) []byte {
|
func Hash160(b []byte) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hash256 computes the sha256^2 hash of b.
|
// Hash256 computes double SHA256 hash of b (SHA256(SHA256(b))) which is used
|
||||||
|
// as ID for transactions, blocks and assets. It uses `HASH256` VM instruction.
|
||||||
func Hash256(b []byte) []byte {
|
func Hash256(b []byte) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifySignature checks that sig is msg's signature with pub.
|
// VerifySignature checks that sig is correct msg's signature for a given pub
|
||||||
|
// (serialized public key). It uses `VERIFY` VM instruction.
|
||||||
func VerifySignature(msg []byte, sig []byte, pub []byte) bool {
|
func VerifySignature(msg []byte, sig []byte, pub []byte) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
14
pkg/interop/doc.go
Normal file
14
pkg/interop/doc.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
Package interop contains smart contract API functions.
|
||||||
|
Its subpackages can be imported into smart contracts written in Go to provide
|
||||||
|
various functionality. Upon compilation, functions from these packages will
|
||||||
|
be substituted with appropriate NeoVM system calls implemented by Neo. Usually
|
||||||
|
these system calls have additional price in NeoVM, so they're explicitly written
|
||||||
|
in the documentation of respective functions.
|
||||||
|
|
||||||
|
Note that unless written otherwise structures defined in this packages can't be
|
||||||
|
correctly created by new() or composite literals, they should be received from
|
||||||
|
some interop functions (and then used as parameters for some other interop
|
||||||
|
functions).
|
||||||
|
*/
|
||||||
|
package interop
|
|
@ -1,34 +1,66 @@
|
||||||
|
/*
|
||||||
|
Package engine provides access to VM execution metadata and allows to make contract calls.
|
||||||
|
It's roughly similar in function to ExecutionEngine class in the Neo .net
|
||||||
|
framework.
|
||||||
|
*/
|
||||||
package engine
|
package engine
|
||||||
|
|
||||||
import "github.com/nspcc-dev/neo-go/pkg/interop/transaction"
|
import "github.com/nspcc-dev/neo-go/pkg/interop/transaction"
|
||||||
|
|
||||||
// Package engine provides function signatures that can be used inside
|
// GetScriptContainer returns the transaction that initially triggered current
|
||||||
// smart contracts that are written in the neo-go framework.
|
// execution context. It never changes in a single execution, no matter how deep
|
||||||
|
// this execution goes. See `transaction` package for details on how to use the
|
||||||
// GetScriptContainer returns the transaction that is in the execution context.
|
// returned value. This function uses `System.ExecutionEngine.GetScriptContainer`
|
||||||
|
// syscall.
|
||||||
func GetScriptContainer() transaction.Transaction {
|
func GetScriptContainer() transaction.Transaction {
|
||||||
return transaction.Transaction{}
|
return transaction.Transaction{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetExecutingScriptHash returns the script hash of the contract that is
|
// GetExecutingScriptHash returns script hash (160 bit in BE form represented
|
||||||
// currently being executed.
|
// as 20-byte slice) of the contract that is currently being executed. Any
|
||||||
|
// AppCall can change the value returned by this function if it calls a
|
||||||
|
// different contract. This function uses
|
||||||
|
// `System.ExecutionEngine.GetExecutingScriptHash` syscall.
|
||||||
func GetExecutingScriptHash() []byte {
|
func GetExecutingScriptHash() []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCallingScriptHash returns the script hash of the contract that started
|
// GetCallingScriptHash returns script hash (160 bit in BE form represented
|
||||||
// the execution of the current script.
|
// as 20-byte slice) of the contract that started the execution of the currently
|
||||||
|
// running context (caller of current contract or function), so it's one level
|
||||||
|
// above the GetExecutingScriptHash in the call stack. It uses
|
||||||
|
// `System.ExecutionEngine.GetCallingScriptHash` syscall.
|
||||||
func GetCallingScriptHash() []byte {
|
func GetCallingScriptHash() []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEntryScriptHash returns the script hash of the contract that started the
|
// GetEntryScriptHash returns script hash (160 bit in BE form represented
|
||||||
// execution from the start.
|
// as 20-byte slice) of the contract that initially started current execution
|
||||||
|
// (this is a script that is contained in a transaction returned by
|
||||||
|
// GetScriptContainer) execution from the start. This function uses
|
||||||
|
// `System.ExecutionEngine.GetEntryScriptHash` syscall.
|
||||||
func GetEntryScriptHash() []byte {
|
func GetEntryScriptHash() []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppCall executes script with specified hash using provided arguments.
|
// AppCall executes previously deployed blockchain contract with specified hash
|
||||||
|
// (160 bit in BE form represented as 20-byte slice) using provided arguments.
|
||||||
|
// It returns whatever this contract returns. Even though this function accepts
|
||||||
|
// a slice for scriptHash you can only use it for contracts known at
|
||||||
|
// compile time, because there is a significant difference between static and
|
||||||
|
// dynamic calls in Neo (contracts should have a special property declared
|
||||||
|
// and paid for to be able to use dynamic calls). This function uses `APPCALL`
|
||||||
|
// opcode.
|
||||||
func AppCall(scriptHash []byte, args ...interface{}) interface{} {
|
func AppCall(scriptHash []byte, args ...interface{}) interface{} {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DynAppCall executes previously deployed blockchain contract with specified
|
||||||
|
// hash (160 bit in BE form represented as 20-byte slice) using provided
|
||||||
|
// arguments. It returns whatever this contract returns. It differs from AppCall
|
||||||
|
// in that you can use it for truly dynamic scriptHash values, but at the same
|
||||||
|
// time using it requires HasDynamicInvoke property set for a contract doing
|
||||||
|
// this call. This function uses `APPCALL` opcode.
|
||||||
|
func DynAppCall(scriptHash []byte, args ...interface{}) interface{} {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,29 +1,41 @@
|
||||||
|
/*
|
||||||
|
Package enumerator provides functions to work with enumerators.
|
||||||
|
*/
|
||||||
package enumerator
|
package enumerator
|
||||||
|
|
||||||
// Package enumerator provides function signatures that can be used inside
|
// Enumerator represents NEO enumerator type, it's an opaque data structure
|
||||||
// smart contracts that are written in the neo-go framework.
|
// that can be used with functions from this package. It's similar to more
|
||||||
|
// widely used Iterator (see `iterator` package), but ranging over arrays
|
||||||
// TODO: Check enumerator use cases and add them to the examples folder.
|
// or structures that have values with no explicit keys.
|
||||||
|
|
||||||
// Enumerator stubs a NEO enumerator type.
|
|
||||||
type Enumerator struct{}
|
type Enumerator struct{}
|
||||||
|
|
||||||
// Create creates a new enumerator from the given items.
|
// Create creates a new enumerator from the given items (slice or structure).
|
||||||
|
// New enumerator points at index -1 of its items, so the user of it has to
|
||||||
|
// advance it first with Next. This function uses `Neo.Enumerator.Create`
|
||||||
|
// syscall.
|
||||||
func Create(items []interface{}) Enumerator {
|
func Create(items []interface{}) Enumerator {
|
||||||
return Enumerator{}
|
return Enumerator{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next returns the next item in the iteration.
|
// Next moves position of the given enumerator by one and returns a bool that
|
||||||
func Next(e Enumerator) interface{} {
|
// tells whether there is a new value present in this new position. If it is,
|
||||||
return nil
|
// you can use Value to get it, if not then there are no more values in this
|
||||||
|
// enumerator. This function uses `Neo.Enumerator.Next` syscall.
|
||||||
|
func Next(e Enumerator) bool {
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value returns the enumerator value.
|
// Value returns current enumerator's item value, it's only valid to call it
|
||||||
|
// after Next returning true. This function uses `Neo.Enumerator.Value` syscall.
|
||||||
func Value(e Enumerator) interface{} {
|
func Value(e Enumerator) interface{} {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Concat concatenates the 2 given enumerators.
|
// Concat concatenates two given enumerators returning one that will range on
|
||||||
|
// a first and then continue with b. Enumerator positions are not reset for a
|
||||||
|
// and b, so if any of them was already advanced by Next the resulting
|
||||||
|
// Enumerator will point at this new position and never go back to previous
|
||||||
|
// values. This function uses `Neo.Enumerator.Concat` syscall.
|
||||||
func Concat(a, b Enumerator) Enumerator {
|
func Concat(a, b Enumerator) Enumerator {
|
||||||
return Enumerator{}
|
return Enumerator{}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,47 +1,61 @@
|
||||||
|
/*
|
||||||
|
Package header contains functions working with block headers.
|
||||||
|
*/
|
||||||
package header
|
package header
|
||||||
|
|
||||||
// Package header provides function signatures that can be used inside
|
// Header represents Neo block header type, it's an opaque data structure that
|
||||||
// smart contracts that are written in the neo-go framework.
|
// can be used by functions from this package. You can create it with
|
||||||
|
// blockchain.GetHeader. In its function it's similar to the Header class
|
||||||
// Header stubs a NEO block header type.
|
// of the Neo .net framework.
|
||||||
type Header struct{}
|
type Header struct{}
|
||||||
|
|
||||||
// GetIndex returns the index of the given header.
|
// GetIndex returns the index (height) of the given header. It uses
|
||||||
|
// `Neo.Header.GetIndex` syscall.
|
||||||
func GetIndex(h Header) int {
|
func GetIndex(h Header) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHash returns the hash of the given header.
|
// GetHash returns the hash (256-bit BE value packed into 32 byte slice) of the
|
||||||
|
// given header (which also is a hash of the block). It uses `Neo.Header.GetHash`
|
||||||
|
// syscall.
|
||||||
func GetHash(h Header) []byte {
|
func GetHash(h Header) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPrevHash returns the previous hash of the given header.
|
// GetPrevHash returns the hash (256-bit BE value packed into 32 byte slice) of
|
||||||
|
// the previous block stored in the given header. It uses `Neo.Header.GetPrevHash`
|
||||||
|
// syscall.
|
||||||
func GetPrevHash(h Header) []byte {
|
func GetPrevHash(h Header) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTimestamp returns the timestamp of the given header.
|
// GetTimestamp returns the timestamp of the given header. It uses
|
||||||
|
// `Neo.Header.GetTimestamp` syscall.
|
||||||
func GetTimestamp(h Header) int {
|
func GetTimestamp(h Header) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVersion returns the version of the given header.
|
// GetVersion returns the version of the given header. It uses
|
||||||
|
// `Neo.Header.GetVersion` syscall.
|
||||||
func GetVersion(h Header) int {
|
func GetVersion(h Header) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMerkleRoot returns the merkle root of the given header.
|
// GetMerkleRoot returns the Merkle root (256-bit BE value packed into 32 byte
|
||||||
|
// slice) of the given header. It uses `Neo.Header.GetMerkleRoot` syscall.
|
||||||
func GetMerkleRoot(h Header) []byte {
|
func GetMerkleRoot(h Header) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetConsensusData returns the consensus data of the given header.
|
// GetConsensusData returns the consensus data (nonce) of the given header.
|
||||||
|
// It uses `Neo.Header.GetConsensusData` syscall.
|
||||||
func GetConsensusData(h Header) int {
|
func GetConsensusData(h Header) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNextConsensus returns the next consensus of the given header.
|
// GetNextConsensus returns the next consensus field (verification script hash,
|
||||||
|
// 160-bit BE value packed into 20 byte slice) of the given header. It uses
|
||||||
|
// `Neo.Header.GetNextConsensus` syscall.
|
||||||
func GetNextConsensus(h Header) []byte {
|
func GetNextConsensus(h Header) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
|
/*
|
||||||
|
Package input provides functions dealing with transaction inputs.
|
||||||
|
*/
|
||||||
package input
|
package input
|
||||||
|
|
||||||
// Package input provides function signatures that can be used inside
|
// Input is an opaque data structure that can only be created by
|
||||||
// smart contracts that are written in the neo-go framework.
|
// transaction.GetInputs and it represents transaction's input. It's similar
|
||||||
|
// to Neo .net framework's TransactionInput.
|
||||||
// Input stubs the input of a NEO transaction.
|
|
||||||
type Input struct{}
|
type Input struct{}
|
||||||
|
|
||||||
// GetHash returns the hash of the given input.
|
// GetHash returns the hash stored in the given input (which also is a
|
||||||
|
// transaction ID represented as 32 byte slice containing 256 bit BE value).
|
||||||
|
// It uses `Neo.Input.GetHash` syscall.
|
||||||
func GetHash(in Input) []byte {
|
func GetHash(in Input) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetIndex returns the index of the given input.
|
// GetIndex returns the index stored in the given input (which is a
|
||||||
|
// transaction's output number). It uses `Neo.Input.GetIndex` syscall.
|
||||||
func GetIndex(in Input) int {
|
func GetIndex(in Input) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +1,63 @@
|
||||||
|
/*
|
||||||
|
Package iterator provides functions to work with Neo iterators.
|
||||||
|
*/
|
||||||
package iterator
|
package iterator
|
||||||
|
|
||||||
// Package iterator provides function signatures that can be used inside
|
import "github.com/nspcc-dev/neo-go/pkg/interop/enumerator"
|
||||||
// smart contracts that are written in the neo-go framework.
|
|
||||||
|
|
||||||
// Iterator stubs a NEO iterator object type.
|
// Iterator represents a Neo iterator, it's an opaque data structure that can
|
||||||
|
// be properly created by Create or storage.Find. Unlike enumerators, iterators
|
||||||
|
// range over key-value pairs, so it's convenient to use them for maps. This
|
||||||
|
// structure is similar in function to Neo .net framework's Iterator.
|
||||||
type Iterator struct{}
|
type Iterator struct{}
|
||||||
|
|
||||||
// Create creates an iterator from the given items.
|
// Create creates an iterator from the given items (array, struct or map). A new
|
||||||
|
// iterator is set to point at element -1, so to access its first element you
|
||||||
|
// need to call Next first. This function uses `Neo.Iterator.Create` syscall.
|
||||||
func Create(items []interface{}) Iterator {
|
func Create(items []interface{}) Iterator {
|
||||||
return Iterator{}
|
return Iterator{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Key returns the iterator key.
|
// Concat concatenates two given iterators returning one that will range on
|
||||||
// TODO: Better description for this.
|
// a first and then continue with b. Iterator positions are not reset for a
|
||||||
|
// and b, so if any of them was already advanced by Next the resulting
|
||||||
|
// Iterator will point at this new position and never go back to previous
|
||||||
|
// key-value pairs. This function uses `Neo.Iterator.Concat` syscall.
|
||||||
|
func Concat(a, b Iterator) Iterator {
|
||||||
|
return Iterator{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Key returns iterator's key at current position. It's only valid to call after
|
||||||
|
// successful Next call. This function uses `Neo.Iterator.Key` syscall.
|
||||||
func Key(it Iterator) interface{} {
|
func Key(it Iterator) interface{} {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keys returns the iterator keys.
|
// Keys returns Enumerator ranging over keys or the given Iterator. Note that
|
||||||
func Keys(it Iterator) []interface{} {
|
// this Enumerator is actually directly tied to the underlying Iterator, so that
|
||||||
return nil
|
// advancing it with Next will actually advance the Iterator too. This function
|
||||||
|
// uses `Neo.Iterator.Keys` syscall.
|
||||||
|
func Keys(it Iterator) enumerator.Enumerator {
|
||||||
|
return enumerator.Enumerator{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next advances the iterator, return true if it is was successful
|
// Next advances the iterator returning true if it is was successful (and you
|
||||||
// and false otherwise.
|
// can use Key or Value) and false otherwise (and there are no more elements in
|
||||||
|
// this Iterator). This function uses `Neo.Iterator.Next` syscall.
|
||||||
func Next(it Iterator) bool {
|
func Next(it Iterator) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value returns the current iterator value.
|
// Value returns iterator's current value. It's only valid to call after
|
||||||
|
// successful Next call. This function uses `Neo.Iterator.Value` syscall.
|
||||||
func Value(it Iterator) interface{} {
|
func Value(it Iterator) interface{} {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Values returns the iterator values.
|
// Values returns Enumerator ranging over values or the given Iterator. Note that
|
||||||
func Values(it Iterator) []interface{} {
|
// this Enumerator is actually directly tied to the underlying Iterator, so that
|
||||||
return nil
|
// advancing it with Next will actually advance the Iterator too. This function
|
||||||
|
// uses `Neo.Iterator.Values` syscall.
|
||||||
|
func Values(it Iterator) enumerator.Enumerator {
|
||||||
|
return enumerator.Enumerator{}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,28 @@
|
||||||
|
/*
|
||||||
|
Package output provides functions dealing with transaction outputs.
|
||||||
|
*/
|
||||||
package output
|
package output
|
||||||
|
|
||||||
// Package output provides function signatures that can be used inside
|
// Output is an opaque data structure that can only be created by
|
||||||
// smart contracts that are written in the neo-go framework.
|
// transaction.GetOutputs and it represents transaction's output. It's similar
|
||||||
|
// to Neo .net framework's TransactionOutput.
|
||||||
// Output stubs the output of a NEO transaction.
|
|
||||||
type Output struct{}
|
type Output struct{}
|
||||||
|
|
||||||
// GetAssetID returns the asset id of the given output.
|
// GetAssetID returns the asset ID (256 bit BE value in a 32 byte slice) of the
|
||||||
|
// given output. It uses `Neo.Output.GetAssetId` syscall.
|
||||||
func GetAssetID(out Output) []byte {
|
func GetAssetID(out Output) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetValue returns the value of the given output.
|
// GetValue returns the value (asset quantity) of the given output. It uses
|
||||||
|
// `Neo.Output.GetValue` syscall.
|
||||||
func GetValue(out Output) int {
|
func GetValue(out Output) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetScriptHash returns the script hash of the given output.
|
// GetScriptHash returns the script hash (receiver's address represented as
|
||||||
|
// 20 byte slice containing 160 bit BE value) of the given output. It uses
|
||||||
|
// `Neo.Output.GetScriptHash` syscall.
|
||||||
func GetScriptHash(out Output) []byte {
|
func GetScriptHash(out Output) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,48 +1,70 @@
|
||||||
|
/*
|
||||||
|
Package runtime provides various service functions related to execution environment.
|
||||||
|
It has similar function to Runtime class in .net framwork for Neo.
|
||||||
|
*/
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
// Package runtime provides function signatures that can be used inside
|
// CheckWitness verifies if the given script hash (160-bit BE value in a 20 byte
|
||||||
// smart contracts that are written in the neo-go framework.
|
// slice) or key (compressed serialized 33-byte form) is one of the signers of
|
||||||
|
// this invocation. It uses `Neo.Runtime.CheckWitness` syscall.
|
||||||
// CheckWitness verifies if the given hash is the invoker of the contract.
|
func CheckWitness(hashOrKey []byte) bool {
|
||||||
func CheckWitness(hash []byte) bool {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log instucts the VM to log the given message.
|
// Log instructs VM to log the given message. It's mostly used for debugging
|
||||||
|
// purposes as these messages are not saved anywhere normally and usually are
|
||||||
|
// only visible in the VM logs. This function uses `Neo.Runtime.Log` syscall.
|
||||||
func Log(message string) {}
|
func Log(message string) {}
|
||||||
|
|
||||||
// Notify an event to the VM.
|
// Notify sends a notification (collecting all arguments in an array) to the
|
||||||
func Notify(arg ...interface{}) int {
|
// executing environment. Unlike Log it can accept any data and resulting
|
||||||
return 0
|
// notification is saved in application log. It's intended to be used as a
|
||||||
}
|
// part of contract's API to external systems, these events can be monitored
|
||||||
|
// from outside and act upon accordingly. This function uses
|
||||||
|
// `Neo.Runtime.Notify` syscall.
|
||||||
|
func Notify(arg ...interface{}) {}
|
||||||
|
|
||||||
// GetTime returns the timestamp of the most recent block.
|
// GetTime returns the timestamp of the most recent block. Note that when running
|
||||||
|
// script in test mode this would be the last accepted (persisted) block in the
|
||||||
|
// chain, but when running as a part of the new block the time returned is the
|
||||||
|
// time of this (currently being processed) block. This function uses
|
||||||
|
// `Neo.Runtime.GetTime` syscall.
|
||||||
func GetTime() int {
|
func GetTime() int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTrigger returns the smart contract invoke trigger which can be either
|
// GetTrigger returns the smart contract invocation trigger which can be either
|
||||||
// verification or application.
|
// verification or application. It can be used to differentiate running contract
|
||||||
|
// as a part of verification process from running it as a regular application.
|
||||||
|
// Some interop functions (especially ones that change the state in any way) are
|
||||||
|
// not available when running with verification trigger. This function uses
|
||||||
|
// `Neo.Runtime.GetTrigger` syscall.
|
||||||
func GetTrigger() byte {
|
func GetTrigger() byte {
|
||||||
return 0x00
|
return 0x00
|
||||||
}
|
}
|
||||||
|
|
||||||
// Application returns the Application trigger type
|
// Application returns the Application trigger type value to compare with
|
||||||
|
// GetTrigger return value.
|
||||||
func Application() byte {
|
func Application() byte {
|
||||||
return 0x10
|
return 0x10
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verification returns the Verification trigger type
|
// Verification returns the Verification trigger type value to compare with
|
||||||
|
// GetTrigger return value.
|
||||||
func Verification() byte {
|
func Verification() byte {
|
||||||
return 0x00
|
return 0x00
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serialize serializes and item into a bytearray.
|
// Serialize serializes any given item into a byte slice. It works for all
|
||||||
|
// regular VM types (not ones from interop package) and allows to save them in
|
||||||
|
// storage or pass into Notify and then Deserialize them on the next run or in
|
||||||
|
// the external event receiver. It uses `Neo.Runtime.Serialize` syscall.
|
||||||
func Serialize(item interface{}) []byte {
|
func Serialize(item interface{}) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deserialize an item from a bytearray.
|
// Deserialize unpacks previously serialized value from a byte slice, it's the
|
||||||
|
// opposite of Serialize. It uses `Neo.Runtime.Deserialize` syscall.
|
||||||
func Deserialize(b []byte) interface{} {
|
func Deserialize(b []byte) interface{} {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,54 @@
|
||||||
|
/*
|
||||||
|
Package storage provides functions to access and modify contract's storage.
|
||||||
|
Neo storage's model follows simple key-value DB pattern, this storage is a part
|
||||||
|
of blockchain state, so you can use it between various invocations of the same
|
||||||
|
contract.
|
||||||
|
*/
|
||||||
package storage
|
package storage
|
||||||
|
|
||||||
import "github.com/nspcc-dev/neo-go/pkg/interop/iterator"
|
import "github.com/nspcc-dev/neo-go/pkg/interop/iterator"
|
||||||
|
|
||||||
// Package storage provides function signatures that can be used inside
|
// Context represents storage context that is mandatory for Put/Get/Delete
|
||||||
// smart contracts that are written in the neo-go framework.
|
// operations. It's an opaque type that can only be created properly by
|
||||||
|
// GetContext, GetReadOnlyContext or ConvertContextToReadOnly. It's similar
|
||||||
// Context represents the storage context.
|
// to Neo .net framework's StorageContext class.
|
||||||
type Context struct{}
|
type Context struct{}
|
||||||
|
|
||||||
// GetContext returns the storage context.
|
// ConvertContextToReadOnly returns new context from the given one, but with
|
||||||
|
// writing capability turned off, so that you could only invoke Get and Find
|
||||||
|
// using this new Context. If Context is already read-only this function is a
|
||||||
|
// no-op. It uses `Neo.StorageContext.AsReadOnly` syscall.
|
||||||
|
func ConvertContextToReadOnly(ctx Context) Context { return Context{} }
|
||||||
|
|
||||||
|
// GetContext returns current contract's (that invokes this function) storage
|
||||||
|
// context. It uses `Neo.Storage.GetContext` syscall.
|
||||||
func GetContext() Context { return Context{} }
|
func GetContext() Context { return Context{} }
|
||||||
|
|
||||||
// Put value at given key.
|
// GetReadOnlyContext returns current contract's (that invokes this function)
|
||||||
|
// storage context in read-only mode, you can use this context for Get and Find
|
||||||
|
// functions, but using it for Put and Delete will fail. It uses
|
||||||
|
// `Neo.Storage.GetReadOnlyContext` syscall.
|
||||||
|
func GetReadOnlyContext() Context { return Context{} }
|
||||||
|
|
||||||
|
// Put saves given value with given key in the storage using given Context.
|
||||||
|
// Even though it accepts interface{} for both, you can only pass simple types
|
||||||
|
// there like string, []byte, int or bool (not structures or slices of more
|
||||||
|
// complex types). To put more complex types there serialize them first using
|
||||||
|
// runtime.Serialize. This function uses `Neo.Storage.Put` syscall.
|
||||||
func Put(ctx Context, key interface{}, value interface{}) {}
|
func Put(ctx Context, key interface{}, value interface{}) {}
|
||||||
|
|
||||||
// Get value matching given key.
|
// Get retrieves value stored for the given key using given Context. See Put
|
||||||
|
// documentation on possible key and value types. This function uses
|
||||||
|
// `Neo.Storage.Get` syscall.
|
||||||
func Get(ctx Context, key interface{}) interface{} { return 0 }
|
func Get(ctx Context, key interface{}) interface{} { return 0 }
|
||||||
|
|
||||||
// Delete key value pair from storage.
|
// Delete removes key-value pair from storage by the given key using given
|
||||||
|
// Context. See Put documentation on possible key types. This function uses
|
||||||
|
// `Neo.Storage.Delete` syscall.
|
||||||
func Delete(ctx Context, key interface{}) {}
|
func Delete(ctx Context, key interface{}) {}
|
||||||
|
|
||||||
// Find returns an iterator.Iterator over the keys that matched the given key.
|
// Find returns an iterator.Iterator over key-value pairs in the given Context
|
||||||
|
// that match the given key (contain it as a prefix). See Put documentation on
|
||||||
|
// possible key types and iterator package documentation on how to use the
|
||||||
|
// returned value. This function uses `Neo.Storage.Find` syscall.
|
||||||
func Find(ctx Context, key interface{}) iterator.Iterator { return iterator.Iterator{} }
|
func Find(ctx Context, key interface{}) iterator.Iterator { return iterator.Iterator{} }
|
||||||
|
|
|
@ -1,50 +1,82 @@
|
||||||
|
/*
|
||||||
|
Package transaction provides functions to work with transactions.
|
||||||
|
*/
|
||||||
package transaction
|
package transaction
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/attribute"
|
"github.com/nspcc-dev/neo-go/pkg/interop/attribute"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/input"
|
"github.com/nspcc-dev/neo-go/pkg/interop/input"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/output"
|
"github.com/nspcc-dev/neo-go/pkg/interop/output"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/interop/witness"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Package transaction provides function signatures that can be used inside
|
// Transaction represents a NEO transaction, it's an opaque data structure
|
||||||
// smart contracts that are written in the neo-go framework.
|
// that can be used with functions from this package. It's similar to
|
||||||
|
// Transaction class in Neo .net framework.
|
||||||
// Transaction stubs a NEO transaction type.
|
|
||||||
type Transaction struct{}
|
type Transaction struct{}
|
||||||
|
|
||||||
// GetHash returns the hash of the given transaction.
|
// GetHash returns the hash (256 bit BE value in a 32 byte slice) of the given
|
||||||
|
// transaction (which also is its ID). Is uses `Neo.Transaction.GetHash` syscall.
|
||||||
func GetHash(t Transaction) []byte {
|
func GetHash(t Transaction) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetType returns the type of the given transaction.
|
// GetType returns the type of the given transaction. Possible values:
|
||||||
|
// MinerTransaction = 0x00
|
||||||
|
// IssueTransaction = 0x01
|
||||||
|
// ClaimTransaction = 0x02
|
||||||
|
// EnrollmentTransaction = 0x20
|
||||||
|
// RegisterTransaction = 0x40
|
||||||
|
// ContractTransaction = 0x80
|
||||||
|
// StateType = 0x90
|
||||||
|
// AgencyTransaction = 0xb0
|
||||||
|
// PublishTransaction = 0xd0
|
||||||
|
// InvocationTransaction = 0xd1
|
||||||
|
// It uses `Neo.Transaction.GetType` syscall.
|
||||||
func GetType(t Transaction) byte {
|
func GetType(t Transaction) byte {
|
||||||
return 0x00
|
return 0x00
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAttributes returns a slice of attributes for the given transaction.
|
// GetAttributes returns a slice of attributes for agiven transaction. Refer to
|
||||||
|
// attribute package on how to use them. This function uses
|
||||||
|
// `Neo.Transaction.GetAttributes` syscall.
|
||||||
func GetAttributes(t Transaction) []attribute.Attribute {
|
func GetAttributes(t Transaction) []attribute.Attribute {
|
||||||
return []attribute.Attribute{}
|
return []attribute.Attribute{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetReferences returns a slice of references for the given transaction.
|
// GetReferences returns a slice of references for a given Transaction. Elements
|
||||||
// FIXME: What is the correct return type for this?
|
// of this slice can be casted to any of input.Input or output.Output, depending
|
||||||
|
// on which information you're interested in (as reference technically contains
|
||||||
|
// both input and corresponding output), refer to input and output package on
|
||||||
|
// how to use them. This function uses `Neo.Transaction.GetReferences` syscall.
|
||||||
func GetReferences(t Transaction) []interface{} {
|
func GetReferences(t Transaction) []interface{} {
|
||||||
return []interface{}{}
|
return []interface{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUnspentCoins returns the unspent coins for the given transaction.
|
// GetInputs returns a slice of inputs of a given Transaction. Refer to input
|
||||||
// FIXME: What is the correct return type for this?
|
// package on how to use them. This function uses `Neo.Transaction.GetInputs`
|
||||||
func GetUnspentCoins(t Transaction) interface{} {
|
// syscall.
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetInputs returns the inputs of the given transaction.
|
|
||||||
func GetInputs(t Transaction) []input.Input {
|
func GetInputs(t Transaction) []input.Input {
|
||||||
return []input.Input{}
|
return []input.Input{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOutputs returns the outputs of the given transaction.
|
// GetOutputs returns a slice of outputs of a given Transaction. Refer to output
|
||||||
|
// package on how to use them. This function uses `Neo.Transaction.GetOutputs`
|
||||||
|
// syscall.
|
||||||
func GetOutputs(t Transaction) []output.Output {
|
func GetOutputs(t Transaction) []output.Output {
|
||||||
return []output.Output{}
|
return []output.Output{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetScript returns the script stored in a given Invocation transaction.
|
||||||
|
// Calling it for any other Transaction type would lead to failure. It uses
|
||||||
|
// `Neo.InvocationTransaction.GetScript` syscall.
|
||||||
|
func GetScript(t Transaction) []byte {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWitnesses returns a slice of witnesses of a given Transaction. Refer to
|
||||||
|
// witness package on how to use them. This function uses
|
||||||
|
// `Neo.Transaction.GetWitnesses` syscall.
|
||||||
|
func GetWitnesses(t Transaction) []witness.Witness {
|
||||||
|
return []witness.Witness{}
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
|
/*
|
||||||
|
Package util contains some special useful functions that are provided by compiler and VM.
|
||||||
|
*/
|
||||||
package util
|
package util
|
||||||
|
|
||||||
// FromAddress is an utility function that converts an NEO address to its hash.
|
// FromAddress is an utility function that converts a Neo address to its hash
|
||||||
|
// (160 bit BE value in a 20 byte slice). It can only be used for strings known
|
||||||
|
// at compilation time, because the convertion is actually being done by the
|
||||||
|
// compiler.
|
||||||
func FromAddress(address string) []byte {
|
func FromAddress(address string) []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equals compares a with b and will return true whether a and b
|
// Equals compares a with b and will return true when a and b are equal. It's
|
||||||
// are equal.
|
// implemented as an EQUAL VM opcode, so the rules of comparison are those
|
||||||
|
// of EQUAL.
|
||||||
func Equals(a, b interface{}) bool {
|
func Equals(a, b interface{}) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
14
pkg/interop/witness/witness.go
Normal file
14
pkg/interop/witness/witness.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
Package witness provides functions dealing with transaction's witnesses.
|
||||||
|
*/
|
||||||
|
package witness
|
||||||
|
|
||||||
|
// Witness is an opaque data structure that can only be created by
|
||||||
|
// transaction.GetWitnesses and representing transaction's witness.
|
||||||
|
type Witness struct{}
|
||||||
|
|
||||||
|
// GetVerificationScript returns verification script stored in the given
|
||||||
|
// witness. It uses `Neo.Witness.GetVerificationScript` syscall.
|
||||||
|
func GetVerificationScript(w Witness) []byte {
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in a new issue