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
|
||||
chains/
|
||||
chain/
|
||||
blockchain/
|
||||
blockchains/
|
||||
|
||||
# patch
|
||||
*.orig
|
||||
|
|
|
@ -110,7 +110,9 @@ mode, after it ends the node can be started normally.
|
|||
Please refer to [neo-go smart contract development
|
||||
workshop](https://github.com/nspcc-dev/neo-go-sc-wrkshp) that shows some
|
||||
simple contracts that can be compiled/deployed/run using neo-go compiler, SDK
|
||||
and private network.
|
||||
and private network. For details on how Go code is translated to Neo VM
|
||||
bytecode and what you can and can not do in smart contract please refer to the
|
||||
[compiler documentation](docs/compiler.md).
|
||||
|
||||
# Developer notes
|
||||
Nodes have such features as [Prometheus](https://prometheus.io/docs/guides/go-application) and
|
||||
|
|
173
docs/compiler.md
173
docs/compiler.md
|
@ -2,66 +2,39 @@
|
|||
|
||||
The neo-go compiler compiles Go programs to bytecode that the NEO virtual machine can understand.
|
||||
|
||||
## Currently supported
|
||||
## Language compatibility
|
||||
|
||||
### Go internals
|
||||
- type checking
|
||||
- multiple assignments
|
||||
- global variables
|
||||
- types int, string, byte and booleans
|
||||
- struct types + method receives
|
||||
- functions
|
||||
- composite literals `[]int, []string, []byte`
|
||||
- basic if statements
|
||||
- binary expressions
|
||||
- return statements
|
||||
- for loops
|
||||
- imports
|
||||
The compiler is mostly compatible with regular Go language specification, but
|
||||
there are some important deviations that you need to be aware of that make it
|
||||
a dialect of Go rather than a complete port of the language:
|
||||
* `make()` ane `new()` are not supported, most of the time you can substitute
|
||||
them with composite literals
|
||||
* there is no real distinction between different integer types, all of them
|
||||
work as big.Int in Go with a limit of 256 bit in width, so you can use
|
||||
`int` for just about anything. This is the way integers work in Neo VM and
|
||||
adding proper Go types emulation is considered to be too costly.
|
||||
* goroutines, channels and garbage collection are not supported and will
|
||||
never be because emulating that aspects of Go runtime on top of Neo VM is
|
||||
close to impossible
|
||||
* even though `panic()` is supported, `recover()` is not, `panic` shuts the
|
||||
VM down
|
||||
* lambdas are not supported
|
||||
* global variables can't be changed in functions (#638)
|
||||
* it's not possible to rename imported interop packages, they won't work this
|
||||
way (#397, #913)
|
||||
* nested selectors are not yet supported (#957)
|
||||
* using value variable in range-based loops is not yet supported (#958)
|
||||
|
||||
### Go builtins
|
||||
- len
|
||||
- append
|
||||
|
||||
### VM API (interop layer)
|
||||
## VM API (interop layer)
|
||||
Compiler translates interop function calls into NEO VM syscalls or (for custom
|
||||
functions) into NEO VM instructions. [Refer to GoDoc](https://godoc.org/github.com/nspcc-dev/neo-go/pkg/interop) for full API documentation.
|
||||
|
||||
#### Standard NEO Smart Contract API
|
||||
- account
|
||||
- asset
|
||||
- attribute
|
||||
- block
|
||||
- blockchain
|
||||
- contract
|
||||
- engine
|
||||
- header
|
||||
- input
|
||||
- iterator
|
||||
- output
|
||||
- runtime
|
||||
- storage
|
||||
- transaction
|
||||
|
||||
#### Custom VM utility helper functions
|
||||
- crypto:
|
||||
- `SHA1`
|
||||
- `SHA256`
|
||||
- `Hash256`
|
||||
- `Hash160`
|
||||
- enumerator
|
||||
- util:
|
||||
- `Equals` (to emit `EQUALS` opcode, not needed usually)
|
||||
- `FromAddress(address string) []byte`
|
||||
|
||||
## Not supported
|
||||
Due to the limitations of the NEO virtual machine, features listed below will not be supported.
|
||||
- channels
|
||||
- goroutines
|
||||
- returning multiple values from functions
|
||||
functions) into NEO VM instructions. [Refer to
|
||||
pkg.go.dev](https://pkg.go.dev/github.com/nspcc-dev/neo-go/pkg/interop)
|
||||
for full API documentation. In general it provides the same level of
|
||||
functionality as Neo .net Framework library.
|
||||
|
||||
## Quick start
|
||||
|
||||
### Compile a smart contract
|
||||
### Compiling
|
||||
|
||||
```
|
||||
./bin/neo-go contract compile -i mycontract.go
|
||||
|
@ -73,7 +46,7 @@ By default the filename will be the name of your .go file with the .avm extensio
|
|||
./bin/neo-go contract compile -i mycontract.go --out /Users/foo/bar/contract.avm
|
||||
```
|
||||
|
||||
### Debugging your smart contract
|
||||
### Debugging
|
||||
You can dump the opcodes generated by the compiler with the following command:
|
||||
|
||||
```
|
||||
|
@ -112,33 +85,89 @@ INDEX OPCODE DESC
|
|||
25 0x66 RET
|
||||
```
|
||||
|
||||
### Test invoke a compiled contract
|
||||
You can simulate a test invocation of your compiled contract by the VM, to know the total gas cost for example, with the following command:
|
||||
#### Neo Smart Contract Debugger support
|
||||
|
||||
It's possible to debug contracts written in Go using standard [Neo Smart
|
||||
Contract Debugger](https://github.com/neo-project/neo-debugger/) which is a
|
||||
part of [Neo Blockchain
|
||||
Toolkit](https://github.com/neo-project/neo-blockchain-toolkit/). To do that
|
||||
you need to generate debug information using `--debug` option, like this:
|
||||
|
||||
```
|
||||
./bin/neo-go contract testinvoke -i mycompiledcontract.avm
|
||||
$ ./bin/neo-go contract compile -i contract.go -o contract.avm --debug contract.debug.json
|
||||
```
|
||||
|
||||
Will output something like:
|
||||
```
|
||||
{
|
||||
"state": "HALT, BREAK",
|
||||
"gas_consumed": "0.006",
|
||||
"Stack": [
|
||||
{
|
||||
"type": "Integer",
|
||||
"value": "9"
|
||||
}
|
||||
]
|
||||
}
|
||||
This file can then be used by debugger and set up to work just like for any
|
||||
other supported language.
|
||||
|
||||
### Deploying
|
||||
|
||||
Deploying a contract to blockchain with neo-go requires a configuration file
|
||||
with contract's metadata in YAML format, like the following:
|
||||
|
||||
```
|
||||
project:
|
||||
author: Jack Smith
|
||||
email: jack@example.com
|
||||
version: 1.0
|
||||
name: 'Smart contract'
|
||||
description: 'Even smarter than Jack himself'
|
||||
hasstorage: true
|
||||
hasdynamicinvocation: false
|
||||
ispayable: false
|
||||
returntype: ByteArray
|
||||
parameters: ['String', 'Array']
|
||||
```
|
||||
|
||||
At the moment this is implemented via RPC call to the remote server.
|
||||
It's passed to the `deploy` command via `-c` option:
|
||||
|
||||
```
|
||||
$ ./bin/neo-go contract deploy -i contract.avm -c contract.yml -e http://localhost:20331 -w wallet.json -g 0.001
|
||||
```
|
||||
|
||||
Deployment works via an RPC server, an address of which is passed via `-e`
|
||||
option and should be signed using a wallet from `-w` option. More details can
|
||||
be found in `deploy` command help.
|
||||
|
||||
#### Neo Express support
|
||||
|
||||
It's possible to deploy contracts written in Go using [Neo
|
||||
Express](https://github.com/neo-project/neo-express) which is a part of [Neo
|
||||
Blockchain
|
||||
Toolkit](https://github.com/neo-project/neo-blockchain-toolkit/). To do that
|
||||
you need to generate a different metadata file using YAML written for
|
||||
deployment with neo-go. It's done in the same step with compilation via
|
||||
`--config` input parameter and `--abi` output parameter, combined with debug
|
||||
support the command line will look like this:
|
||||
|
||||
```
|
||||
$ ./bin/neo-go contract compile -i contract.go --config contract.yml -o contract.avm --debug contract.debug.json --abi contract.abi.json
|
||||
```
|
||||
|
||||
This file can then be used by toolkit to deploy contract the same way
|
||||
contracts in other languagues are deployed.
|
||||
|
||||
|
||||
### Invoking
|
||||
You can import your contract into the standalone VM and run it there (see [VM
|
||||
documentation](vm.md) for more info), but that only works for simple contracts
|
||||
that don't use blockchain a lot. For more real contracts you need to deploy
|
||||
them first and then do test invocations and regular invocations with `contract
|
||||
testinvokefunction` and `contract invokefunction` commands (or their variants,
|
||||
see `contract` command help for more details. They all work via RPC, so it's a
|
||||
mandatory parameter.
|
||||
|
||||
Example call (contract `f84d6a337fbc3d3a201d41da99e86b479e7a2554` with method
|
||||
`balanceOf` and method's parameter `AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y` using
|
||||
given RPC server and wallet and paying 0.00001 GAS for this transaction):
|
||||
|
||||
```
|
||||
$ ./bin/neo-go contract invokefunction -e http://localhost:20331 -w my_wallet.json -g 0.00001 f84d6a337fbc3d3a201d41da99e86b479e7a2554 balanceOf AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y
|
||||
```
|
||||
|
||||
## Smart contract examples
|
||||
|
||||
Some examples are provided in the [examples directory](examples).
|
||||
Some examples are provided in the [examples directory](../examples).
|
||||
|
||||
### Check if the invoker of the contract is the owning address
|
||||
|
||||
|
|
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` |
|
||||
| `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
|
||||
|
||||
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 |
|
||||
| `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`
|
||||
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.
|
||||
#### Websocket server
|
||||
|
||||
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
|
||||
|
||||
|
|
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",
|
||||
"VerifySignature", "AppCall",
|
||||
"FromAddress", "Equals",
|
||||
"panic",
|
||||
"panic", "DynAppCall",
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -1085,15 +1085,24 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
|
|||
emit.Opcode(c.prog.BinWriter, opcode.HASH160)
|
||||
case "VerifySignature":
|
||||
emit.Opcode(c.prog.BinWriter, opcode.VERIFY)
|
||||
case "AppCall":
|
||||
numArgs := len(expr.Args) - 1
|
||||
case "AppCall", "DynAppCall":
|
||||
numArgs := len(expr.Args)
|
||||
if name == "AppCall" {
|
||||
numArgs--
|
||||
}
|
||||
c.emitReverse(numArgs)
|
||||
|
||||
emit.Opcode(c.prog.BinWriter, opcode.APPCALL)
|
||||
buf := c.getByteArray(expr.Args[0])
|
||||
var buf []byte
|
||||
if name == "AppCall" {
|
||||
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)
|
||||
case "Equals":
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"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/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
@ -52,6 +53,19 @@ func TestFromAddress(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 := `
|
||||
package foo
|
||||
func Main(a []byte, b []byte) []byte {
|
||||
|
@ -62,14 +76,31 @@ func TestAppCall(t *testing.T) {
|
|||
inner, err := compiler.Compile(strings.NewReader(srcInner))
|
||||
require.NoError(t, err)
|
||||
|
||||
dynapp, err := compiler.Compile(strings.NewReader(srcDynApp))
|
||||
require.NoError(t, err)
|
||||
|
||||
ih := hash.Hash160(inner)
|
||||
dh := hash.Hash160(dynapp)
|
||||
getScript := func(u util.Uint160) ([]byte, bool) {
|
||||
if u.Equals(ih) {
|
||||
return inner, true
|
||||
}
|
||||
if u.Equals(dh) {
|
||||
return dynapp, hasDynamicInvoke
|
||||
}
|
||||
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) {
|
||||
src := getAppCallScript(fmt.Sprintf("%#v", ih.BytesBE()))
|
||||
v := vmAndCompile(t, src)
|
||||
|
@ -118,6 +149,38 @@ func TestAppCall(t *testing.T) {
|
|||
|
||||
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 {
|
||||
|
|
|
@ -1,12 +1,30 @@
|
|||
package compiler
|
||||
|
||||
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": {
|
||||
"GetContext": "Neo.Storage.GetContext",
|
||||
"Put": "Neo.Storage.Put",
|
||||
"Get": "Neo.Storage.Get",
|
||||
"ConvertContextToReadOnly": "Neo.StorageContext.AsReadOnly",
|
||||
"Delete": "Neo.Storage.Delete",
|
||||
"Find": "Neo.Storage.Find",
|
||||
"Get": "Neo.Storage.Get",
|
||||
"GetContext": "Neo.Storage.GetContext",
|
||||
"GetReadOnlyContext": "Neo.Storage.GetReadOnlyContext",
|
||||
"Put": "Neo.Storage.Put",
|
||||
},
|
||||
"runtime": {
|
||||
"GetTrigger": "Neo.Runtime.GetTrigger",
|
||||
|
@ -18,14 +36,15 @@ var syscalls = map[string]map[string]string{
|
|||
"Deserialize": "Neo.Runtime.Deserialize",
|
||||
},
|
||||
"blockchain": {
|
||||
"GetHeight": "Neo.Blockchain.GetHeight",
|
||||
"GetHeader": "Neo.Blockchain.GetHeader",
|
||||
"GetBlock": "Neo.Blockchain.GetBlock",
|
||||
"GetTransaction": "Neo.Blockchain.GetTransaction",
|
||||
"GetContract": "Neo.Blockchain.GetContract",
|
||||
"GetAccount": "Neo.Blockchain.GetAccount",
|
||||
"GetValidators": "Neo.Blockchain.GetValidators",
|
||||
"GetAsset": "Neo.Blockchain.GetAsset",
|
||||
"GetBlock": "Neo.Blockchain.GetBlock",
|
||||
"GetContract": "Neo.Blockchain.GetContract",
|
||||
"GetHeader": "Neo.Blockchain.GetHeader",
|
||||
"GetHeight": "Neo.Blockchain.GetHeight",
|
||||
"GetTransaction": "Neo.Blockchain.GetTransaction",
|
||||
"GetTransactionHeight": "Neo.Blockchain.GetTransactionHeight",
|
||||
"GetValidators": "Neo.Blockchain.GetValidators",
|
||||
},
|
||||
"header": {
|
||||
"GetIndex": "Neo.Header.GetIndex",
|
||||
|
@ -43,20 +62,25 @@ var syscalls = map[string]map[string]string{
|
|||
"GetTransaction": "Neo.Block.GetTransaction",
|
||||
},
|
||||
"transaction": {
|
||||
"GetHash": "Neo.Transaction.GetHash",
|
||||
"GetType": "Neo.Transaction.GetType",
|
||||
"GetAttributes": "Neo.Transaction.GetAttributes",
|
||||
"GetHash": "Neo.Transaction.GetHash",
|
||||
"GetInputs": "Neo.Transaction.GetInputs",
|
||||
"GetOutputs": "Neo.Transaction.GetOutputs",
|
||||
"GetReferences": "Neo.Transaction.GetReferences",
|
||||
"GetUnspentCoins": "Neo.Transaction.GetUnspentCoins",
|
||||
"GetScript": "Neo.Transaction.GetScript",
|
||||
"GetScript": "Neo.InvocationTransaction.GetScript",
|
||||
"GetType": "Neo.Transaction.GetType",
|
||||
"GetWitnesses": "Neo.Transaction.GetWitnesses",
|
||||
},
|
||||
"asset": {
|
||||
"Create": "Neo.Asset.Create",
|
||||
"GetAdmin": "Neo.Asset.GetAdmin",
|
||||
"GetAmount": "Neo.Asset.GetAmount",
|
||||
"GetAssetID": "Neo.Asset.GetAssetID",
|
||||
"GetAssetType": "Neo.Asset.GetAssetType",
|
||||
"GetAmount": "Neo.Asset.GetAmount",
|
||||
"Create": "Neo.Asset.Create",
|
||||
"GetAvailable": "Neo.Asset.GetAvailable",
|
||||
"GetIssuer": "Neo.Asset.GetIssuer",
|
||||
"GetOwner": "Neo.Asset.GetOwner",
|
||||
"GetPrecision": "Neo.Asset.GetPrecision",
|
||||
"Renew": "Neo.Asset.Renew",
|
||||
},
|
||||
"contract": {
|
||||
|
@ -83,6 +107,7 @@ var syscalls = map[string]map[string]string{
|
|||
"GetExecutingScriptHash": "System.ExecutionEngine.GetExecutingScriptHash",
|
||||
},
|
||||
"iterator": {
|
||||
"Concat": "Neo.Iterator.Concat",
|
||||
"Create": "Neo.Iterator.Create",
|
||||
"Key": "Neo.Iterator.Key",
|
||||
"Keys": "Neo.Iterator.Keys",
|
||||
|
@ -90,4 +115,7 @@ var syscalls = map[string]map[string]string{
|
|||
"Value": "Neo.Iterator.Value",
|
||||
"Values": "Neo.Iterator.Values",
|
||||
},
|
||||
"witness": {
|
||||
"GetVerificationScript": "Neo.Witness.GetVerificationScript",
|
||||
},
|
||||
}
|
||||
|
|
|
@ -236,7 +236,14 @@ func (ic *interopContext) witnessGetVerificationScript(v *vm.VM) error {
|
|||
|
||||
// bcGetValidators returns validators.
|
||||
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)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -575,8 +575,12 @@ func (ic *interopContext) contractGetStorageContext(v *vm.VM) error {
|
|||
if !ok {
|
||||
return fmt.Errorf("%T is not a contract state", cs)
|
||||
}
|
||||
contractState, err := ic.dao.GetContractState(cs.ScriptHash())
|
||||
if contractState == nil || err != nil {
|
||||
_, err := ic.dao.GetContractState(cs.ScriptHash())
|
||||
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")
|
||||
}
|
||||
stc := &StorageContext{
|
||||
|
|
|
@ -27,6 +27,7 @@ type interopContext struct {
|
|||
block *block.Block
|
||||
tx *transaction.Transaction
|
||||
dao *dao.Cached
|
||||
lowerDao dao.DAO
|
||||
notifications []state.NotificationEvent
|
||||
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 {
|
||||
dao := dao.NewCached(d)
|
||||
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
|
||||
|
|
|
@ -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 provides function signatures that can be used inside
|
||||
// smart contracts that are written in the neo-go framework.
|
||||
|
||||
// Account stubs a NEO account type.
|
||||
// Account represents NEO account type that is used in interop functions, it's
|
||||
// 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
|
||||
// framework.
|
||||
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 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetVotes returns the votes of the given account which should be a slice of
|
||||
// public key raw bytes.
|
||||
// GetVotes returns current votes of the given account represented as a slice of
|
||||
// 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 {
|
||||
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 {
|
||||
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 provides function signatures that can be used inside
|
||||
// smart contracts that are written in the neo-go framework.
|
||||
|
||||
// Asset stubs a NEO asset type.
|
||||
// Asset represents NEO asset type that is used in interop functions, it's
|
||||
// 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
|
||||
// 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{}
|
||||
|
||||
// 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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create registers a new asset on the blockchain.
|
||||
func Create(assetType byte, name string, amount int, precision byte, owner, admin, issuer []byte) {}
|
||||
// Create registers a new asset on the blockchain (similar to old Register
|
||||
// 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.
|
||||
func Renew(asset Asset, years int) {}
|
||||
// Renew renews (make available for use) existing asset by the specified number
|
||||
// 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 provides function signatures that can be used inside
|
||||
// smart contracts that are written in the neo-go framework.
|
||||
|
||||
// Attribute stubs a NEO transaction attribute type.
|
||||
// Attribute represents transaction attribute in Neo, it's an opaque data
|
||||
// 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
|
||||
// framework. To use it you need to get is first using transaction.GetAttributes.
|
||||
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 {
|
||||
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 {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,25 +1,30 @@
|
|||
/*
|
||||
Package block provides getters for Neo Block structure.
|
||||
*/
|
||||
package block
|
||||
|
||||
import "github.com/nspcc-dev/neo-go/pkg/interop/transaction"
|
||||
|
||||
// Package block provides function signatures that can be used inside
|
||||
// smart contracts that are written in the neo-go framework.
|
||||
|
||||
// Block stubs a NEO block type.
|
||||
// Block represents a NEO block, it's an opaque data structure that you can get
|
||||
// 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
|
||||
// blockchain.GetBlock function call.
|
||||
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 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// GetTransactions returns a slice of transactions recorded in the given block.
|
||||
// It uses `Neo.Block.GetTransactions` syscall internally.
|
||||
func GetTransactions(b Block) []transaction.Transaction {
|
||||
return []transaction.Transaction{}
|
||||
}
|
||||
|
||||
// GetTransaction returns a transaction from the given a block hash of the
|
||||
// transaction.
|
||||
func GetTransaction(b Block, hash []byte) transaction.Transaction {
|
||||
// GetTransaction returns transaction from the given block by its index. It
|
||||
// uses `Neo.Block.GetTransaction` syscall internally.
|
||||
func GetTransaction(b Block, index int) transaction.Transaction {
|
||||
return transaction.Transaction{}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
/*
|
||||
Package blockchain provides functions to access various blockchain data.
|
||||
*/
|
||||
package blockchain
|
||||
|
||||
import (
|
||||
|
@ -9,45 +12,72 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/interop/transaction"
|
||||
)
|
||||
|
||||
// Package blockchain provides function signatures that can be used inside
|
||||
// smart contracts that are written in the neo-go framework.
|
||||
|
||||
// GetHeight returns the height of te block recorded in the current execution scope.
|
||||
// GetHeight returns current block height (index of the last accepted block).
|
||||
// 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
|
||||
// the previous (already accepted) block. This function uses
|
||||
// `Neo.Blockchain.GetHeight` syscall.
|
||||
func GetHeight() int {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
return asset.Asset{}
|
||||
}
|
||||
|
|
|
@ -1,55 +1,85 @@
|
|||
/*
|
||||
Package contract provides functions to work with contracts.
|
||||
*/
|
||||
package contract
|
||||
|
||||
import "github.com/nspcc-dev/neo-go/pkg/interop/storage"
|
||||
|
||||
// Package contract provides function signatures that can be used inside
|
||||
// smart contracts that are written in the neo-go framework.
|
||||
|
||||
// Contract stubs a NEO contract type.
|
||||
// Contract represents a Neo contract and is used in interop functions. It's
|
||||
// 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
|
||||
// framework.
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
return storage.Context{}
|
||||
}
|
||||
|
||||
// Create creates a new contract.
|
||||
// @FIXME What is the type of the returnType here?
|
||||
// Create creates a new contract using a set of input parameters:
|
||||
// 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(
|
||||
script []byte,
|
||||
params []interface{},
|
||||
params []byte,
|
||||
returnType byte,
|
||||
properties interface{},
|
||||
properties byte,
|
||||
name,
|
||||
version,
|
||||
author,
|
||||
email,
|
||||
description string) {
|
||||
description string) Contract {
|
||||
return Contract{}
|
||||
}
|
||||
|
||||
// Migrate migrates a new contract.
|
||||
// @FIXME What is the type of the returnType here?
|
||||
// Migrate migrates calling contract (that is the one that calls Migrate) to
|
||||
// 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(
|
||||
script []byte,
|
||||
params []interface{},
|
||||
params []byte,
|
||||
returnType byte,
|
||||
properties interface{},
|
||||
properties byte,
|
||||
name,
|
||||
version,
|
||||
author,
|
||||
email,
|
||||
description string) {
|
||||
description string) Contract {
|
||||
return Contract{}
|
||||
}
|
||||
|
||||
// Destroy deletes a contract that is registered on the blockchain.
|
||||
func Destroy(c Contract) {}
|
||||
// Destroy deletes calling contract (the one that calls Destroy) from the
|
||||
// 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 provides function signatures that can be used inside
|
||||
// smart contracts that are written in the neo-go framework.
|
||||
|
||||
// SHA1 computes the sha1 hash of b.
|
||||
// SHA1 computes SHA1 hash of b. It uses `SHA1` VM instruction.
|
||||
func SHA1(b []byte) []byte {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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
|
||||
|
||||
import "github.com/nspcc-dev/neo-go/pkg/interop/transaction"
|
||||
|
||||
// Package engine provides function signatures that can be used inside
|
||||
// smart contracts that are written in the neo-go framework.
|
||||
|
||||
// GetScriptContainer returns the transaction that is in the execution context.
|
||||
// GetScriptContainer returns the transaction that initially triggered current
|
||||
// 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
|
||||
// returned value. This function uses `System.ExecutionEngine.GetScriptContainer`
|
||||
// syscall.
|
||||
func GetScriptContainer() transaction.Transaction {
|
||||
return transaction.Transaction{}
|
||||
}
|
||||
|
||||
// GetExecutingScriptHash returns the script hash of the contract that is
|
||||
// currently being executed.
|
||||
// GetExecutingScriptHash returns script hash (160 bit in BE form represented
|
||||
// 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 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetCallingScriptHash returns the script hash of the contract that started
|
||||
// the execution of the current script.
|
||||
// GetCallingScriptHash returns script hash (160 bit in BE form represented
|
||||
// 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 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetEntryScriptHash returns the script hash of the contract that started the
|
||||
// execution from the start.
|
||||
// GetEntryScriptHash returns script hash (160 bit in BE form represented
|
||||
// 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 {
|
||||
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{} {
|
||||
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 provides function signatures that can be used inside
|
||||
// smart contracts that are written in the neo-go framework.
|
||||
|
||||
// TODO: Check enumerator use cases and add them to the examples folder.
|
||||
|
||||
// Enumerator stubs a NEO enumerator type.
|
||||
// Enumerator represents NEO enumerator type, it's an opaque data structure
|
||||
// that can be used with functions from this package. It's similar to more
|
||||
// widely used Iterator (see `iterator` package), but ranging over arrays
|
||||
// or structures that have values with no explicit keys.
|
||||
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 {
|
||||
return Enumerator{}
|
||||
}
|
||||
|
||||
// Next returns the next item in the iteration.
|
||||
func Next(e Enumerator) interface{} {
|
||||
return nil
|
||||
// Next moves position of the given enumerator by one and returns a bool that
|
||||
// tells whether there is a new value present in this new position. If it is,
|
||||
// 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{} {
|
||||
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 {
|
||||
return Enumerator{}
|
||||
}
|
||||
|
|
|
@ -1,47 +1,61 @@
|
|||
/*
|
||||
Package header contains functions working with block headers.
|
||||
*/
|
||||
package header
|
||||
|
||||
// Package header provides function signatures that can be used inside
|
||||
// smart contracts that are written in the neo-go framework.
|
||||
|
||||
// Header stubs a NEO block header type.
|
||||
// Header represents Neo block header type, it's an opaque data structure that
|
||||
// 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
|
||||
// of the Neo .net framework.
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
/*
|
||||
Package input provides functions dealing with transaction inputs.
|
||||
*/
|
||||
package input
|
||||
|
||||
// Package input provides function signatures that can be used inside
|
||||
// smart contracts that are written in the neo-go framework.
|
||||
|
||||
// Input stubs the input of a NEO transaction.
|
||||
// Input is an opaque data structure that can only be created by
|
||||
// transaction.GetInputs and it represents transaction's input. It's similar
|
||||
// to Neo .net framework's TransactionInput.
|
||||
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 {
|
||||
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 {
|
||||
return 0
|
||||
}
|
||||
|
|
|
@ -1,39 +1,63 @@
|
|||
/*
|
||||
Package iterator provides functions to work with Neo iterators.
|
||||
*/
|
||||
package iterator
|
||||
|
||||
// Package iterator provides function signatures that can be used inside
|
||||
// smart contracts that are written in the neo-go framework.
|
||||
import "github.com/nspcc-dev/neo-go/pkg/interop/enumerator"
|
||||
|
||||
// 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{}
|
||||
|
||||
// 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 {
|
||||
return Iterator{}
|
||||
}
|
||||
|
||||
// Key returns the iterator key.
|
||||
// TODO: Better description for this.
|
||||
// Concat concatenates two given iterators returning one that will range on
|
||||
// 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{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Keys returns the iterator keys.
|
||||
func Keys(it Iterator) []interface{} {
|
||||
return nil
|
||||
// Keys returns Enumerator ranging over keys or the given Iterator. Note that
|
||||
// this Enumerator is actually directly tied to the underlying Iterator, so that
|
||||
// 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
|
||||
// and false otherwise.
|
||||
// Next advances the iterator returning true if it is was successful (and you
|
||||
// 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 {
|
||||
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{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Values returns the iterator values.
|
||||
func Values(it Iterator) []interface{} {
|
||||
return nil
|
||||
// Values returns Enumerator ranging over values or the given Iterator. Note that
|
||||
// this Enumerator is actually directly tied to the underlying Iterator, so that
|
||||
// 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 provides function signatures that can be used inside
|
||||
// smart contracts that are written in the neo-go framework.
|
||||
|
||||
// Output stubs the output of a NEO transaction.
|
||||
// Output is an opaque data structure that can only be created by
|
||||
// transaction.GetOutputs and it represents transaction's output. It's similar
|
||||
// to Neo .net framework's TransactionOutput.
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 provides function signatures that can be used inside
|
||||
// smart contracts that are written in the neo-go framework.
|
||||
|
||||
// CheckWitness verifies if the given hash is the invoker of the contract.
|
||||
func CheckWitness(hash []byte) bool {
|
||||
// CheckWitness verifies if the given script hash (160-bit BE value in a 20 byte
|
||||
// slice) or key (compressed serialized 33-byte form) is one of the signers of
|
||||
// this invocation. It uses `Neo.Runtime.CheckWitness` syscall.
|
||||
func CheckWitness(hashOrKey []byte) bool {
|
||||
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) {}
|
||||
|
||||
// Notify an event to the VM.
|
||||
func Notify(arg ...interface{}) int {
|
||||
return 0
|
||||
}
|
||||
// Notify sends a notification (collecting all arguments in an array) to the
|
||||
// executing environment. Unlike Log it can accept any data and resulting
|
||||
// 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 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// GetTrigger returns the smart contract invoke trigger which can be either
|
||||
// verification or application.
|
||||
// GetTrigger returns the smart contract invocation trigger which can be either
|
||||
// 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 {
|
||||
return 0x00
|
||||
}
|
||||
|
||||
// Application returns the Application trigger type
|
||||
// Application returns the Application trigger type value to compare with
|
||||
// GetTrigger return value.
|
||||
func Application() byte {
|
||||
return 0x10
|
||||
}
|
||||
|
||||
// Verification returns the Verification trigger type
|
||||
// Verification returns the Verification trigger type value to compare with
|
||||
// GetTrigger return value.
|
||||
func Verification() byte {
|
||||
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 {
|
||||
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{} {
|
||||
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
|
||||
|
||||
import "github.com/nspcc-dev/neo-go/pkg/interop/iterator"
|
||||
|
||||
// Package storage provides function signatures that can be used inside
|
||||
// smart contracts that are written in the neo-go framework.
|
||||
|
||||
// Context represents the storage context.
|
||||
// Context represents storage context that is mandatory for Put/Get/Delete
|
||||
// operations. It's an opaque type that can only be created properly by
|
||||
// GetContext, GetReadOnlyContext or ConvertContextToReadOnly. It's similar
|
||||
// to Neo .net framework's StorageContext class.
|
||||
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{} }
|
||||
|
||||
// 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{}) {}
|
||||
|
||||
// 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 }
|
||||
|
||||
// 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{}) {}
|
||||
|
||||
// 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{} }
|
||||
|
|
|
@ -1,50 +1,82 @@
|
|||
/*
|
||||
Package transaction provides functions to work with transactions.
|
||||
*/
|
||||
package transaction
|
||||
|
||||
import (
|
||||
"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/output"
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/witness"
|
||||
)
|
||||
|
||||
// Package transaction provides function signatures that can be used inside
|
||||
// smart contracts that are written in the neo-go framework.
|
||||
|
||||
// Transaction stubs a NEO transaction type.
|
||||
// Transaction represents a NEO transaction, it's an opaque data structure
|
||||
// that can be used with functions from this package. It's similar to
|
||||
// Transaction class in Neo .net framework.
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
return []attribute.Attribute{}
|
||||
}
|
||||
|
||||
// GetReferences returns a slice of references for the given transaction.
|
||||
// FIXME: What is the correct return type for this?
|
||||
// GetReferences returns a slice of references for a given Transaction. Elements
|
||||
// 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{} {
|
||||
return []interface{}{}
|
||||
}
|
||||
|
||||
// GetUnspentCoins returns the unspent coins for the given transaction.
|
||||
// FIXME: What is the correct return type for this?
|
||||
func GetUnspentCoins(t Transaction) interface{} {
|
||||
return 0
|
||||
}
|
||||
|
||||
// GetInputs returns the inputs of the given transaction.
|
||||
// GetInputs returns a slice of inputs of a given Transaction. Refer to input
|
||||
// package on how to use them. This function uses `Neo.Transaction.GetInputs`
|
||||
// syscall.
|
||||
func GetInputs(t Transaction) []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 {
|
||||
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
|
||||
|
||||
// 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 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Equals compares a with b and will return true whether a and b
|
||||
// are equal.
|
||||
// Equals compares a with b and will return true when a and b are equal. It's
|
||||
// implemented as an EQUAL VM opcode, so the rules of comparison are those
|
||||
// of EQUAL.
|
||||
func Equals(a, b interface{}) bool {
|
||||
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