Merge pull request #715 from nspcc-dev/rpc-doc-and-client
Update RPC docs, implement client-side getblock and getrawtransaction
This commit is contained in:
commit
8141d49e5a
5 changed files with 188 additions and 113 deletions
26
docs/rpc.md
26
docs/rpc.md
|
@ -42,7 +42,9 @@ which would yield the response:
|
||||||
| `getblock` | Yes |
|
| `getblock` | Yes |
|
||||||
| `getblockcount` | Yes |
|
| `getblockcount` | Yes |
|
||||||
| `getblockhash` | Yes |
|
| `getblockhash` | Yes |
|
||||||
|
| `getblockheader` | No (#711) |
|
||||||
| `getblocksysfee` | Yes |
|
| `getblocksysfee` | Yes |
|
||||||
|
| `getclaimable` | Yes |
|
||||||
| `getconnectioncount` | Yes |
|
| `getconnectioncount` | Yes |
|
||||||
| `getcontractstate` | Yes |
|
| `getcontractstate` | Yes |
|
||||||
| `getnep5balances` | No (#498) |
|
| `getnep5balances` | No (#498) |
|
||||||
|
@ -51,8 +53,11 @@ which would yield the response:
|
||||||
| `getrawmempool` | Yes |
|
| `getrawmempool` | Yes |
|
||||||
| `getrawtransaction` | Yes |
|
| `getrawtransaction` | Yes |
|
||||||
| `getstorage` | Yes |
|
| `getstorage` | Yes |
|
||||||
|
| `gettransactionheight` | No (#713) |
|
||||||
| `gettxout` | Yes |
|
| `gettxout` | Yes |
|
||||||
|
| `getunclaimed` | No (#712) |
|
||||||
| `getunspents` | Yes |
|
| `getunspents` | Yes |
|
||||||
|
| `getvalidators` | No (#714) |
|
||||||
| `getversion` | Yes |
|
| `getversion` | Yes |
|
||||||
| `invoke` | Yes |
|
| `invoke` | Yes |
|
||||||
| `invokefunction` | Yes |
|
| `invokefunction` | Yes |
|
||||||
|
@ -61,6 +66,27 @@ which would yield the response:
|
||||||
| `submitblock` | No (#344) |
|
| `submitblock` | No (#344) |
|
||||||
| `validateaddress` | Yes |
|
| `validateaddress` | Yes |
|
||||||
|
|
||||||
|
### Unsupported methods
|
||||||
|
|
||||||
|
Methods listed down below are not going to be supported for various reasons
|
||||||
|
and we're not accepting issues related to them.
|
||||||
|
|
||||||
|
| Method | Reason |
|
||||||
|
| ------- | ------------|
|
||||||
|
| `claimgas` | Doesn't fit neo-go wallet model, use CLI to do that |
|
||||||
|
| `dumpprivkey` | Shouldn't exist for security reasons, see `claimgas` comment also |
|
||||||
|
| `getbalance` | Use `getaccountstate` instead, see `claimgas` comment also |
|
||||||
|
| `getmetricblocktimestamp` | Not really useful, use other means for node monitoring |
|
||||||
|
| `getnewaddress` | See `claimgas` comment |
|
||||||
|
| `getunclaimedgas` | Use `getunclaimed` instead, see `claimgas` comment also |
|
||||||
|
| `getwalletheight` | Not applicable to neo-go, see `claimgas` comment |
|
||||||
|
| `importprivkey` | Not applicable to neo-go, see `claimgas` comment |
|
||||||
|
| `listaddress` | Not applicable to neo-go, see `claimgas` comment |
|
||||||
|
| `listplugins` | neo-go doesn't have any plugins, so it makes no sense |
|
||||||
|
| `sendfrom` | Not applicable to neo-go, see `claimgas` comment |
|
||||||
|
| `sendmany` | Not applicable to neo-go, see `claimgas` comment |
|
||||||
|
| `sendtoaddress` | Not applicable to neo-go, see `claimgas` comment |
|
||||||
|
|
||||||
#### Implementation notices
|
#### Implementation notices
|
||||||
|
|
||||||
##### `invokefunction` and `invoke`
|
##### `invokefunction` and `invoke`
|
||||||
|
|
|
@ -11,59 +11,59 @@ Some of the methods also allow to pass a verbose bool. This will
|
||||||
return a more pretty printed response from the server instead of
|
return a more pretty printed response from the server instead of
|
||||||
a raw hex string.
|
a raw hex string.
|
||||||
|
|
||||||
An example:
|
|
||||||
endpoint := "http://seed5.bridgeprotocol.io:10332"
|
|
||||||
opts := client.Options{}
|
|
||||||
|
|
||||||
c, err := client.New(context.TODO(), endpoint, opts)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.Ping(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := c.GetAccountState("ATySFJAbLW7QHsZGHScLhxq6EyNBxx3eFP")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
log.Println(resp.Result.ScriptHash)
|
|
||||||
log.Println(resp.Result.Balances)
|
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
Merge structs so can be used by both server and client.
|
|
||||||
Add missing methods to client.
|
Add missing methods to client.
|
||||||
Allow client to connect using client cert.
|
Allow client to connect using client cert.
|
||||||
More in-depth examples.
|
More in-depth examples.
|
||||||
|
|
||||||
Supported methods
|
Supported methods
|
||||||
|
|
||||||
getblock
|
|
||||||
getaccountstate
|
getaccountstate
|
||||||
getunspents
|
getblock
|
||||||
invokescript
|
getclaimable
|
||||||
invokefunction
|
|
||||||
sendrawtransaction
|
|
||||||
invoke
|
|
||||||
getrawtransaction
|
getrawtransaction
|
||||||
|
getunspents
|
||||||
|
invoke
|
||||||
|
invokefunction
|
||||||
|
invokescript
|
||||||
|
sendrawtransaction
|
||||||
|
|
||||||
Unsupported methods
|
Unsupported methods
|
||||||
|
|
||||||
validateaddress
|
claimgas
|
||||||
|
dumpprivkey
|
||||||
|
getapplicationlog
|
||||||
|
getassetstate
|
||||||
|
getbalance
|
||||||
|
getbestblockhash
|
||||||
|
getblockcount
|
||||||
|
getblockhash
|
||||||
|
getblockheader
|
||||||
getblocksysfee
|
getblocksysfee
|
||||||
|
getconnectioncount
|
||||||
getcontractstate
|
getcontractstate
|
||||||
|
getmetricblocktimestamp
|
||||||
|
getnep5balances
|
||||||
|
getnep5transfers
|
||||||
|
getnewaddress
|
||||||
|
getpeers
|
||||||
getrawmempool
|
getrawmempool
|
||||||
getstorage
|
getstorage
|
||||||
submitblock
|
gettransactionheight
|
||||||
gettxout
|
gettxout
|
||||||
getassetstate
|
getunclaimed
|
||||||
getpeers
|
getunclaimedgas
|
||||||
|
getvalidators
|
||||||
getversion
|
getversion
|
||||||
getconnectioncount
|
getwalletheight
|
||||||
getblockhash
|
importprivkey
|
||||||
getblockcount
|
listaddress
|
||||||
getbestblockhash
|
listplugins
|
||||||
|
sendfrom
|
||||||
|
sendmany
|
||||||
|
sendtoaddress
|
||||||
|
submitblock
|
||||||
|
validateaddress
|
||||||
|
|
||||||
*/
|
*/
|
||||||
package client
|
package client
|
||||||
|
|
33
pkg/rpc/client/doc_test.go
Normal file
33
pkg/rpc/client/doc_test.go
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package client_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/rpc/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example() {
|
||||||
|
endpoint := "http://seed5.bridgeprotocol.io:10332"
|
||||||
|
opts := client.Options{}
|
||||||
|
|
||||||
|
c, err := client.New(context.TODO(), endpoint, opts)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.Ping(); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := c.GetAccountState("ATySFJAbLW7QHsZGHScLhxq6EyNBxx3eFP")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Println(resp.ScriptHash)
|
||||||
|
fmt.Println(resp.Balances)
|
||||||
|
}
|
|
@ -4,8 +4,10 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpc/request"
|
"github.com/nspcc-dev/neo-go/pkg/rpc/request"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
|
@ -14,23 +16,6 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// getBlock returns a block by its hash or index/height. If verbose is true
|
|
||||||
// the response will contain a pretty Block object instead of the raw hex string.
|
|
||||||
// missing output wrapper at the moment, thus commented out
|
|
||||||
// func (c *Client) getBlock(indexOrHash interface{}, verbose bool) (*response, error) {
|
|
||||||
// var (
|
|
||||||
// params = request.NewRawParams(indexOrHash)
|
|
||||||
// resp = &response{}
|
|
||||||
// )
|
|
||||||
// if verbose {
|
|
||||||
// params = request.NewRawParams(indexOrHash, 1)
|
|
||||||
// }
|
|
||||||
// if err := c.performRequest("getblock", params, resp); err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// return resp, nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
// GetAccountState returns detailed information about a NEO account.
|
// GetAccountState returns detailed information about a NEO account.
|
||||||
func (c *Client) GetAccountState(address string) (*result.AccountState, error) {
|
func (c *Client) GetAccountState(address string) (*result.AccountState, error) {
|
||||||
var (
|
var (
|
||||||
|
@ -43,6 +28,61 @@ func (c *Client) GetAccountState(address string) (*result.AccountState, error) {
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetBlockByIndex returns a block by its height.
|
||||||
|
func (c *Client) GetBlockByIndex(index uint32) (*block.Block, error) {
|
||||||
|
return c.getBlock(request.NewRawParams(index))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBlockByHash returns a block by its hash.
|
||||||
|
func (c *Client) GetBlockByHash(hash util.Uint256) (*block.Block, error) {
|
||||||
|
return c.getBlock(request.NewRawParams(hash.StringLE()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getBlock(params request.RawParams) (*block.Block, error) {
|
||||||
|
var (
|
||||||
|
resp string
|
||||||
|
err error
|
||||||
|
b *block.Block
|
||||||
|
)
|
||||||
|
if err = c.performRequest("getblock", params, &resp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
blockBytes, err := hex.DecodeString(resp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r := io.NewBinReaderFromBuf(blockBytes)
|
||||||
|
b = new(block.Block)
|
||||||
|
b.DecodeBinary(r)
|
||||||
|
if r.Err != nil {
|
||||||
|
return nil, r.Err
|
||||||
|
}
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBlockByIndexVerbose returns a block wrapper with additional metadata by
|
||||||
|
// its height.
|
||||||
|
func (c *Client) GetBlockByIndexVerbose(index uint32) (*result.Block, error) {
|
||||||
|
return c.getBlockVerbose(request.NewRawParams(index, 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBlockByHashVerbose returns a block wrapper with additional metadata by
|
||||||
|
// its hash.
|
||||||
|
func (c *Client) GetBlockByHashVerbose(hash util.Uint256) (*result.Block, error) {
|
||||||
|
return c.getBlockVerbose(request.NewRawParams(hash.StringLE(), 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getBlockVerbose(params request.RawParams) (*result.Block, error) {
|
||||||
|
var (
|
||||||
|
resp = &result.Block{}
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if err = c.performRequest("getblock", params, &resp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetClaimable returns tx outputs which can be claimed.
|
// GetClaimable returns tx outputs which can be claimed.
|
||||||
func (c *Client) GetClaimable(address string) (*result.ClaimableInfo, error) {
|
func (c *Client) GetClaimable(address string) (*result.ClaimableInfo, error) {
|
||||||
params := request.NewRawParams(address)
|
params := request.NewRawParams(address)
|
||||||
|
@ -53,6 +93,43 @@ func (c *Client) GetClaimable(address string) (*result.ClaimableInfo, error) {
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetRawTransaction returns a transaction by hash.
|
||||||
|
func (c *Client) GetRawTransaction(hash util.Uint256) (*transaction.Transaction, error) {
|
||||||
|
var (
|
||||||
|
params = request.NewRawParams(hash.StringLE())
|
||||||
|
resp string
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if err = c.performRequest("getrawtransaction", params, &resp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
txBytes, err := hex.DecodeString(resp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r := io.NewBinReaderFromBuf(txBytes)
|
||||||
|
tx := new(transaction.Transaction)
|
||||||
|
tx.DecodeBinary(r)
|
||||||
|
if r.Err != nil {
|
||||||
|
return nil, r.Err
|
||||||
|
}
|
||||||
|
return tx, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRawTransactionVerbose returns a transaction wrapper with additional
|
||||||
|
// metadata by transaction's hash.
|
||||||
|
func (c *Client) GetRawTransactionVerbose(hash util.Uint256) (*result.TransactionOutputRaw, error) {
|
||||||
|
var (
|
||||||
|
params = request.NewRawParams(hash.StringLE(), 1)
|
||||||
|
resp = &result.TransactionOutputRaw{}
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if err = c.performRequest("getrawtransaction", params, &resp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetUnspents returns UTXOs for the given NEO account.
|
// GetUnspents returns UTXOs for the given NEO account.
|
||||||
func (c *Client) GetUnspents(address string) (*result.Unspents, error) {
|
func (c *Client) GetUnspents(address string) (*result.Unspents, error) {
|
||||||
var (
|
var (
|
||||||
|
@ -105,19 +182,6 @@ func (c *Client) Invoke(script string, params []smartcontract.Parameter) (*resul
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getRawTransaction queries a transaction by hash.
|
|
||||||
// missing output wrapper at the moment, thus commented out
|
|
||||||
// func (c *Client) getRawTransaction(hash string, verbose bool) (*response, error) {
|
|
||||||
// var (
|
|
||||||
// params = request.NewRawParams(hash, verbose)
|
|
||||||
// resp = &response{}
|
|
||||||
// )
|
|
||||||
// if err := c.performRequest("getrawtransaction", params, resp); err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// return resp, nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
// SendRawTransaction broadcasts a transaction over the NEO network.
|
// SendRawTransaction broadcasts a transaction over the NEO network.
|
||||||
// The given hex string needs to be signed with a keypair.
|
// The given hex string needs to be signed with a keypair.
|
||||||
// When the result of the response object is true, the TX has successfully
|
// When the result of the response object is true, the TX has successfully
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
/*
|
|
||||||
Package server implements NEO-specific JSON-RPC 2.0 server.
|
|
||||||
This package is currently in alpha and is subject to change.
|
|
||||||
|
|
||||||
Server
|
|
||||||
|
|
||||||
The server is written to support as much of the JSON-RPC 2.0 Spec 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:
|
|
||||||
|
|
||||||
$ curl -X POST -d '{"jsonrpc": "2.0", "method": "getversion", "params": [], "id": 1}' http://localhost:20332
|
|
||||||
|
|
||||||
which would yield the response:
|
|
||||||
|
|
||||||
{
|
|
||||||
"jsonrpc" : "2.0",
|
|
||||||
"id" : 1,
|
|
||||||
"result" : {
|
|
||||||
"port" : 20333,
|
|
||||||
"useragent" : "/NEO-GO:0.36.0-dev/",
|
|
||||||
"nonce" : 9318417
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Unsupported methods
|
|
||||||
|
|
||||||
getblocksysfee
|
|
||||||
getcontractstate (needs to be implemented in pkg/core/blockchain.go)
|
|
||||||
getrawmempool (needs to be implemented on in pkg/network/server.go)
|
|
||||||
getrawtransaction (needs to be implemented in pkg/core/blockchain.go)
|
|
||||||
getstorage (lacks VM functionality)
|
|
||||||
gettxout (needs to be implemented in pkg/core/blockchain.go)
|
|
||||||
invoke (lacks VM functionality)
|
|
||||||
invokefunction (lacks VM functionality)
|
|
||||||
invokescript (lacks VM functionality)
|
|
||||||
sendrawtransaction (needs to be implemented in pkg/core/blockchain.go)
|
|
||||||
submitblock (needs to be implemented in pkg/core/blockchain.go)
|
|
||||||
|
|
||||||
*/
|
|
||||||
package server
|
|
Loading…
Reference in a new issue