forked from TrueCloudLab/neoneo-go
Small RPC improvements (#57)
* Few tweaks to improve output of `getblock` * Adds few more fields and corrects witness * Bumps version * Only reverse when marshalling for moment * Adds README for rpc package * Few updates * Typo * Adds link in main readme * Fix readme link
This commit is contained in:
parent
c51a6d3e57
commit
0b023c5c5c
11 changed files with 179 additions and 20 deletions
2
Makefile
2
Makefile
|
@ -4,7 +4,7 @@ VERSION = $(shell cat ./VERSION)
|
|||
NETMODE ?= "privnet"
|
||||
|
||||
build:
|
||||
@go build -ldflags "-X github.com/CityOfZion/neo-go/pkg/network.Version=${VERSION}-dev -X github.com/CityOfZion/neo-go/pkg/network.BuildTime=${BUILD_TIME}" -o ./bin/neo-go ./cli/main.go
|
||||
@go build -ldflags "-X github.com/CityOfZion/neo-go/config.Version=${VERSION}-dev -X github.com/CityOfZion/neo-go/config.BuildTime=${BUILD_TIME}" -o ./bin/neo-go ./cli/main.go
|
||||
|
||||
check-version:
|
||||
git fetch && (! git rev-list ${VERSION})
|
||||
|
|
|
@ -29,7 +29,7 @@ This project aims to be a full port of the original C# [NEO project](https://git
|
|||
A complete toolkit for the NEO blockchain, including:
|
||||
|
||||
- consensus node
|
||||
- RPC node
|
||||
- [RPC node & client](https://github.com/CityOfZion/neo-go/tree/master/pkg/rpc/README.md)
|
||||
- RPC client
|
||||
- CLI tool
|
||||
- Smart contract compiler
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
0.35.1
|
||||
0.36.0
|
||||
|
|
|
@ -34,7 +34,7 @@ type BlockBase struct {
|
|||
ConsensusData uint64 `json:"nonce"`
|
||||
|
||||
// Contract addresss of the next miner
|
||||
NextConsensus util.Uint160 `json:"nextminer"`
|
||||
NextConsensus util.Uint160 `json:"next_consensus"`
|
||||
|
||||
// Padding that is fixed to 1
|
||||
_ uint8
|
||||
|
|
|
@ -16,7 +16,7 @@ type Transaction struct {
|
|||
Type TXType `json:"type"`
|
||||
|
||||
// The trading version which is currently 0.
|
||||
Version uint8 `json:"-"`
|
||||
Version uint8 `json:"version"`
|
||||
|
||||
// Data specific to the type of the transaction.
|
||||
// This is always a pointer to a <Type>Transaction.
|
||||
|
|
|
@ -2,6 +2,8 @@ package transaction
|
|||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
|
@ -9,32 +11,42 @@ import (
|
|||
|
||||
// Witness contains 2 scripts.
|
||||
type Witness struct {
|
||||
InvocationScript []byte `json:"stack"`
|
||||
VerificationScript []byte `json:"redeem"`
|
||||
InvocationScript []byte
|
||||
VerificationScript []byte
|
||||
}
|
||||
|
||||
// DecodeBinary implements the payload interface.
|
||||
func (wit *Witness) DecodeBinary(r io.Reader) error {
|
||||
func (w *Witness) DecodeBinary(r io.Reader) error {
|
||||
lenb := util.ReadVarUint(r)
|
||||
wit.InvocationScript = make([]byte, lenb)
|
||||
if err := binary.Read(r, binary.LittleEndian, wit.InvocationScript); err != nil {
|
||||
w.InvocationScript = make([]byte, lenb)
|
||||
if err := binary.Read(r, binary.LittleEndian, w.InvocationScript); err != nil {
|
||||
return err
|
||||
}
|
||||
lenb = util.ReadVarUint(r)
|
||||
wit.VerificationScript = make([]byte, lenb)
|
||||
return binary.Read(r, binary.LittleEndian, wit.VerificationScript)
|
||||
w.VerificationScript = make([]byte, lenb)
|
||||
return binary.Read(r, binary.LittleEndian, w.VerificationScript)
|
||||
}
|
||||
|
||||
// EncodeBinary implements the payload interface.
|
||||
func (wit *Witness) EncodeBinary(w io.Writer) error {
|
||||
if err := util.WriteVarUint(w, uint64(len(wit.InvocationScript))); err != nil {
|
||||
func (w *Witness) EncodeBinary(writer io.Writer) error {
|
||||
if err := util.WriteVarUint(writer, uint64(len(w.InvocationScript))); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := binary.Write(w, binary.LittleEndian, wit.InvocationScript); err != nil {
|
||||
if err := binary.Write(writer, binary.LittleEndian, w.InvocationScript); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := util.WriteVarUint(w, uint64(len(wit.VerificationScript))); err != nil {
|
||||
if err := util.WriteVarUint(writer, uint64(len(w.VerificationScript))); err != nil {
|
||||
return err
|
||||
}
|
||||
return binary.Write(w, binary.LittleEndian, wit.VerificationScript)
|
||||
return binary.Write(writer, binary.LittleEndian, w.VerificationScript)
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json marshaller interface.
|
||||
func (w *Witness) MarshalJSON() ([]byte, error) {
|
||||
data := map[string]interface{}{
|
||||
"invocation": hex.EncodeToString(w.InvocationScript),
|
||||
"verification": hex.EncodeToString(w.VerificationScript),
|
||||
}
|
||||
|
||||
return json.Marshal(data)
|
||||
}
|
||||
|
|
110
pkg/rpc/README.md
Normal file
110
pkg/rpc/README.md
Normal file
|
@ -0,0 +1,110 @@
|
|||
# RPC
|
||||
|
||||
## What
|
||||
|
||||
* Structs used by `JSON-RPC` server and for interacting with a `JSON-RPC` endpoint.
|
||||
* Server for running the `JSON-RPC` protocol based on port in configuration.
|
||||
|
||||
> This package is currently in `alpha` and is subject to change.
|
||||
|
||||
## Reference
|
||||
|
||||
* [JSON-RPC 2.0 Specification](http://www.jsonrpc.org/specification)
|
||||
* [NEO JSON-RPC 2.0 docs](http://docs.neo.org/en-us/node/api.html)
|
||||
|
||||
## Client
|
||||
|
||||
You can create a new client and start interacting with any NEO node that exposes their
|
||||
`JSON-RPC` endpoint. See [godocs](https://godoc.org/github.com/CityOfZion/neo-go/pkg/rpc) for example.
|
||||
|
||||
> Not all methods are currently supported in the client, please see table below for supported methods.
|
||||
|
||||
### TODO
|
||||
|
||||
* Merge structs so can be used by both server and client.
|
||||
* Add missing methods to client.
|
||||
* Allow client to connect using client cert.
|
||||
|
||||
### Supported methods
|
||||
|
||||
| Method | Implemented | Required to implement |
|
||||
| ------- | ------------| --------------------- |
|
||||
| `getblock` | Yes | - |
|
||||
| `getaccountstate` | Yes | - |
|
||||
| `invokescript` | Yes | - |
|
||||
| `invokefunction` | Yes | - |
|
||||
| `sendrawtransaction` | Yes | - |
|
||||
| `validateaddress` | No | Handler and result struct |
|
||||
| `getblocksysfee` | No | Handler and result struct |
|
||||
| `getcontractstate` | No | Handler and result struct |
|
||||
| `getrawmempool` | No | Handler and result struct |
|
||||
| `getrawtransaction` | No | Handler and result struct |
|
||||
| `getstorage` | No | Handler and result struct |
|
||||
| `submitblock` | No | Handler and result struct |
|
||||
| `gettxout` | No | Handler and result struct |
|
||||
| `invoke` | No | Handler and result struct |
|
||||
| `getassetstate` | No | Handler and result struct |
|
||||
| `getpeers` | No | Handler and result struct |
|
||||
| `getversion` | No | Handler and result struct |
|
||||
| `getconnectioncount` | No | Handler and result struct |
|
||||
| `getblockhash` | No | Handler and result struct |
|
||||
| `getblockcount` | No | Handler and result struct |
|
||||
| `getbestblockhash` | No | Handler and result struct |
|
||||
|
||||
## Server
|
||||
|
||||
The server is written to support as much of the [JSON-RPC 2.0 Spec](http://www.jsonrpc.org/specification) as possible. The server is run as part of the node currently.
|
||||
|
||||
### TODO
|
||||
|
||||
* Implement HTTPS server.
|
||||
* Add remaining methods (Documented below).
|
||||
* Add Swagger spec and test using dredd in circleCI.
|
||||
|
||||
### Example call
|
||||
|
||||
An example would be viewing the version of the node:
|
||||
|
||||
```bash
|
||||
curl -X POST -d '{"jsonrpc": "2.0", "method": "getversion", "params": [], "id": 1}" http://localhost:20332
|
||||
```
|
||||
|
||||
which would yield the response:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc" : "2.0",
|
||||
"id" : 1,
|
||||
"result" : {
|
||||
"port" : 20333,
|
||||
"useragent" : "/NEO-GO:0.36.0-dev/",
|
||||
"nonce" : 9318417
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Supported methods
|
||||
|
||||
| Method | Implemented | Required to implement |
|
||||
| ------- | ------------| --------------------- |
|
||||
| `getblock` | Yes | - |
|
||||
| `getaccountstate` | No | Result struct & wallet functionality |
|
||||
| `invokescript` | No | VM |
|
||||
| `invokefunction` | No | VM |
|
||||
| `sendrawtransaction` | No | Needs to be implemented in `pkg/core/blockchain.go` |
|
||||
| `validateaddress` | No | Needs to be implemented in `pkg/core/blockchain.go` |
|
||||
| `getblocksysfee` | No | N/A |
|
||||
| `getcontractstate` | No | Needs to be implemented in `pkg/core/blockchain.go` |
|
||||
| `getrawmempool` | No | Needs to be implemented on in `pkg/network/server.go` |
|
||||
| `getrawtransaction` | No | Needs to be implemented in `pkg/core/blockchain.go` |
|
||||
| `getstorage` | No | VM |
|
||||
| `submitblock` | No | Needs to be implemented in `pkg/core/blockchain.go` |
|
||||
| `gettxout` | No | Needs to be implemented in `pkg/core/blockchain.go` |
|
||||
| `invoke` | No | VM |
|
||||
| `getassetstate` | No | Needs to be implemented in `pkg/core/blockchain.go` |
|
||||
| `getpeers` | Yes | - |
|
||||
| `getversion` | Yes | - |
|
||||
| `getconnectioncount` | Yes | - |
|
||||
| `getblockhash` | Yes | - |
|
||||
| `getblockcount` | Yes | - |
|
||||
| `getbestblockhash` | Yes | - |
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/CityOfZion/neo-go/pkg/core"
|
||||
"github.com/CityOfZion/neo-go/pkg/network"
|
||||
"github.com/CityOfZion/neo-go/pkg/rpc/result"
|
||||
"github.com/CityOfZion/neo-go/pkg/rpc/wrappers"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
@ -133,12 +134,13 @@ Methods:
|
|||
break
|
||||
}
|
||||
|
||||
results, err = s.chain.GetBlock(hash)
|
||||
block, err := s.chain.GetBlock(hash)
|
||||
if err != nil {
|
||||
resultsErr = NewInternalServerError(fmt.Sprintf("Problem locating block with hash: %s", hash), err)
|
||||
break
|
||||
}
|
||||
|
||||
results = wrappers.NewBlock(block, s.chain)
|
||||
case "getblockcount":
|
||||
results = s.chain.BlockHeight()
|
||||
|
||||
|
|
33
pkg/rpc/wrappers/block.go
Normal file
33
pkg/rpc/wrappers/block.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
package wrappers
|
||||
|
||||
import (
|
||||
"github.com/CityOfZion/neo-go/pkg/core"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
type (
|
||||
// Block wrapper used for the representation of
|
||||
// core.Block / core.BlockBase on the RPC Server.
|
||||
Block struct {
|
||||
*core.Block
|
||||
Confirmations uint32 `json:"confirmations"`
|
||||
NextBlockHash util.Uint256 `json:"nextblockhash,omitempty"`
|
||||
Hash util.Uint256 `json:"hash"`
|
||||
}
|
||||
)
|
||||
|
||||
// NewBlock creates a new Block wrapper.
|
||||
func NewBlock(block *core.Block, chain core.Blockchainer) Block {
|
||||
blockWrapper := Block{
|
||||
Block: block,
|
||||
Hash: block.Hash(),
|
||||
}
|
||||
|
||||
hash := chain.GetHeaderHash(int(block.Index) + 1)
|
||||
if !hash.Equals(util.Uint256{}) {
|
||||
blockWrapper.NextBlockHash = hash
|
||||
}
|
||||
|
||||
blockWrapper.Confirmations = chain.BlockHeight() - block.Index - 1
|
||||
return blockWrapper
|
||||
}
|
|
@ -79,5 +79,7 @@ func (u Uint160) Equals(other Uint160) bool {
|
|||
|
||||
// MarshalJSON implements the json marshaller interface.
|
||||
func (u Uint160) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(u.String())
|
||||
return json.Marshal(
|
||||
fmt.Sprintf("0x%s", hex.EncodeToString(ArrayReverse(u.Bytes()))),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -61,5 +61,5 @@ func (u Uint256) String() string {
|
|||
|
||||
// MarshalJSON implements the json marshaller interface.
|
||||
func (u Uint256) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(u.String())
|
||||
return json.Marshal(fmt.Sprintf("0x%s", u.String()))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue