parent
7121686571
commit
15a939b1da
7 changed files with 112 additions and 5 deletions
|
@ -77,6 +77,11 @@ Both methods also don't currently support arrays in function parameters.
|
||||||
It's possible to call this method for any address with neo-go, unlike with C#
|
It's possible to call this method for any address with neo-go, unlike with C#
|
||||||
node where it only works for addresses from opened wallet.
|
node where it only works for addresses from opened wallet.
|
||||||
|
|
||||||
|
##### `getcontractstate`
|
||||||
|
|
||||||
|
It's possible to get non-native contract state by its ID, unlike with C# node where
|
||||||
|
it only works for native contracts.
|
||||||
|
|
||||||
### Unsupported methods
|
### Unsupported methods
|
||||||
|
|
||||||
Methods listed down below are not going to be supported for various reasons
|
Methods listed down below are not going to be supported for various reasons
|
||||||
|
|
|
@ -1073,6 +1073,15 @@ func (bc *Blockchain) GetContractScriptHash(id int32) (util.Uint160, error) {
|
||||||
return bc.dao.GetContractScriptHash(id)
|
return bc.dao.GetContractScriptHash(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetNativeContractScriptHash returns native contract script hash by its name.
|
||||||
|
func (bc *Blockchain) GetNativeContractScriptHash(name string) (util.Uint160, error) {
|
||||||
|
c := bc.contracts.ByName(name)
|
||||||
|
if c != nil {
|
||||||
|
return c.Metadata().Hash, nil
|
||||||
|
}
|
||||||
|
return util.Uint160{}, errors.New("Unknown native contract")
|
||||||
|
}
|
||||||
|
|
||||||
// GetConfig returns the config stored in the blockchain.
|
// GetConfig returns the config stored in the blockchain.
|
||||||
func (bc *Blockchain) GetConfig() config.ProtocolConfiguration {
|
func (bc *Blockchain) GetConfig() config.ProtocolConfiguration {
|
||||||
return bc.config
|
return bc.config
|
||||||
|
|
|
@ -39,6 +39,7 @@ type Blockchainer interface {
|
||||||
HasBlock(util.Uint256) bool
|
HasBlock(util.Uint256) bool
|
||||||
HasTransaction(util.Uint256) bool
|
HasTransaction(util.Uint256) bool
|
||||||
GetAppExecResult(util.Uint256) (*state.AppExecResult, error)
|
GetAppExecResult(util.Uint256) (*state.AppExecResult, error)
|
||||||
|
GetNativeContractScriptHash(string) (util.Uint160, error)
|
||||||
GetNextBlockValidators() ([]*keys.PublicKey, error)
|
GetNextBlockValidators() ([]*keys.PublicKey, error)
|
||||||
GetNEP5Balances(util.Uint160) *state.NEP5Balances
|
GetNEP5Balances(util.Uint160) *state.NEP5Balances
|
||||||
GetValidators() ([]*keys.PublicKey, error)
|
GetValidators() ([]*keys.PublicKey, error)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
|
@ -35,6 +36,17 @@ func (cs *Contracts) ByHash(h util.Uint160) interop.Contract {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ByName returns native contract with the specified name.
|
||||||
|
func (cs *Contracts) ByName(name string) interop.Contract {
|
||||||
|
name = strings.ToLower(name)
|
||||||
|
for _, ctr := range cs.Contracts {
|
||||||
|
if strings.ToLower(ctr.Metadata().Name) == name {
|
||||||
|
return ctr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewContracts returns new set of native contracts with new GAS, NEO and Policy
|
// NewContracts returns new set of native contracts with new GAS, NEO and Policy
|
||||||
// contracts.
|
// contracts.
|
||||||
func NewContracts() *Contracts {
|
func NewContracts() *Contracts {
|
||||||
|
|
|
@ -89,6 +89,9 @@ func (chain testChain) GetContractState(hash util.Uint160) *state.Contract {
|
||||||
func (chain testChain) GetContractScriptHash(id int32) (util.Uint160, error) {
|
func (chain testChain) GetContractScriptHash(id int32) (util.Uint160, error) {
|
||||||
panic("TODO")
|
panic("TODO")
|
||||||
}
|
}
|
||||||
|
func (chain testChain) GetNativeContractScriptHash(name string) (util.Uint160, error) {
|
||||||
|
panic("TODO")
|
||||||
|
}
|
||||||
func (chain testChain) GetHeaderHash(int) util.Uint256 {
|
func (chain testChain) GetHeaderHash(int) util.Uint256 {
|
||||||
return util.Uint256{}
|
return util.Uint256{}
|
||||||
}
|
}
|
||||||
|
|
|
@ -765,6 +765,42 @@ func (s *Server) contractIDFromParam(param *request.Param) (int32, *response.Err
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getContractScriptHashFromParam returns the contract script hash by hex contract hash, address, id or native contract name.
|
||||||
|
func (s *Server) contractScriptHashFromParam(param *request.Param) (util.Uint160, *response.Error) {
|
||||||
|
var result util.Uint160
|
||||||
|
if param == nil {
|
||||||
|
return result, response.ErrInvalidParams
|
||||||
|
}
|
||||||
|
switch param.Type {
|
||||||
|
case request.StringT:
|
||||||
|
var err error
|
||||||
|
result, err = param.GetUint160FromAddressOrHex()
|
||||||
|
if err == nil {
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
name, err := param.GetString()
|
||||||
|
if err != nil {
|
||||||
|
return result, response.ErrInvalidParams
|
||||||
|
}
|
||||||
|
result, err = s.chain.GetNativeContractScriptHash(name)
|
||||||
|
if err != nil {
|
||||||
|
return result, response.NewRPCError("Unknown contract: querying by name is supported for native contracts only", "", nil)
|
||||||
|
}
|
||||||
|
case request.NumberT:
|
||||||
|
id, err := param.GetInt()
|
||||||
|
if err != nil {
|
||||||
|
return result, response.ErrInvalidParams
|
||||||
|
}
|
||||||
|
result, err = s.chain.GetContractScriptHash(int32(id))
|
||||||
|
if err != nil {
|
||||||
|
return result, response.NewRPCError("Unknown contract", "", err)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return result, response.ErrInvalidParams
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) getStorage(ps request.Params) (interface{}, *response.Error) {
|
func (s *Server) getStorage(ps request.Params) (interface{}, *response.Error) {
|
||||||
id, rErr := s.contractIDFromParam(ps.Value(0))
|
id, rErr := s.contractIDFromParam(ps.Value(0))
|
||||||
if rErr == response.ErrUnknown {
|
if rErr == response.ErrUnknown {
|
||||||
|
@ -828,11 +864,12 @@ func (s *Server) getTransactionHeight(ps request.Params) (interface{}, *response
|
||||||
return height, nil
|
return height, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getContractState returns contract state (contract information, according to the contract script hash).
|
// getContractState returns contract state (contract information, according to the contract script hash,
|
||||||
|
// contract id or native contract name).
|
||||||
func (s *Server) getContractState(reqParams request.Params) (interface{}, *response.Error) {
|
func (s *Server) getContractState(reqParams request.Params) (interface{}, *response.Error) {
|
||||||
scriptHash, err := reqParams.ValueWithType(0, request.StringT).GetUint160FromHex()
|
scriptHash, err := s.contractScriptHashFromParam(reqParams.Value(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, response.ErrInvalidParams
|
return nil, err
|
||||||
}
|
}
|
||||||
cs := s.chain.GetContractState(scriptHash)
|
cs := s.chain.GetContractState(scriptHash)
|
||||||
if cs == nil {
|
if cs == nil {
|
||||||
|
|
|
@ -96,7 +96,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
||||||
},
|
},
|
||||||
"getcontractstate": {
|
"getcontractstate": {
|
||||||
{
|
{
|
||||||
name: "positive",
|
name: "positive, by hash",
|
||||||
params: fmt.Sprintf(`["%s"]`, testContractHash),
|
params: fmt.Sprintf(`["%s"]`, testContractHash),
|
||||||
result: func(e *executor) interface{} { return &state.Contract{} },
|
result: func(e *executor) interface{} { return &state.Contract{} },
|
||||||
check: func(t *testing.T, e *executor, cs interface{}) {
|
check: func(t *testing.T, e *executor, cs interface{}) {
|
||||||
|
@ -106,10 +106,50 @@ var rpcTestCases = map[string][]rpcTestCase{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "negative",
|
name: "positive, by id",
|
||||||
|
params: `[0]`,
|
||||||
|
result: func(e *executor) interface{} { return &state.Contract{} },
|
||||||
|
check: func(t *testing.T, e *executor, cs interface{}) {
|
||||||
|
res, ok := cs.(*state.Contract)
|
||||||
|
require.True(t, ok)
|
||||||
|
assert.Equal(t, int32(0), res.ID)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "positive, native by id",
|
||||||
|
params: `[-3]`,
|
||||||
|
result: func(e *executor) interface{} { return &state.Contract{} },
|
||||||
|
check: func(t *testing.T, e *executor, cs interface{}) {
|
||||||
|
res, ok := cs.(*state.Contract)
|
||||||
|
require.True(t, ok)
|
||||||
|
assert.Equal(t, int32(-3), res.ID)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "positive, native by name",
|
||||||
|
params: `["Policy"]`,
|
||||||
|
result: func(e *executor) interface{} { return &state.Contract{} },
|
||||||
|
check: func(t *testing.T, e *executor, cs interface{}) {
|
||||||
|
res, ok := cs.(*state.Contract)
|
||||||
|
require.True(t, ok)
|
||||||
|
assert.Equal(t, int32(-3), res.ID)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "negative, bad hash",
|
||||||
params: `["6d1eeca891ee93de2b7a77eb91c26f3b3c04d6c3"]`,
|
params: `["6d1eeca891ee93de2b7a77eb91c26f3b3c04d6c3"]`,
|
||||||
fail: true,
|
fail: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "negative, bad ID",
|
||||||
|
params: `[-8]`,
|
||||||
|
fail: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "negative, bad native name",
|
||||||
|
params: `["unknown_native"]`,
|
||||||
|
fail: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "no params",
|
name: "no params",
|
||||||
params: `[]`,
|
params: `[]`,
|
||||||
|
|
Loading…
Reference in a new issue