core: adjust System.Blockchain.GetContract interop
Part of #1055. It should put on stack an array instead of interop interface.
This commit is contained in:
parent
1a5fb01e61
commit
d2ec0fed3d
4 changed files with 59 additions and 9 deletions
|
@ -14,7 +14,7 @@ var syscalls = map[string]map[string]Syscall{
|
|||
},
|
||||
"blockchain": {
|
||||
"GetBlock": {"System.Blockchain.GetBlock", true},
|
||||
"GetContract": {"System.Blockchain.GetContract", false},
|
||||
"GetContract": {"System.Blockchain.GetContract", true},
|
||||
"GetHeight": {"System.Blockchain.GetHeight", false},
|
||||
"GetTransaction": {"System.Blockchain.GetTransaction", true},
|
||||
"GetTransactionFromBlock": {"System.Blockchain.GetTransactionFromBlock", false},
|
||||
|
|
|
@ -83,6 +83,20 @@ func bcGetBlock(ic *interop.Context, v *vm.VM) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// contractToStackItem converts state.Contract to stackitem.Item
|
||||
func contractToStackItem(cs *state.Contract) (stackitem.Item, error) {
|
||||
manifest, err := cs.Manifest.MarshalJSON()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return stackitem.NewArray([]stackitem.Item{
|
||||
stackitem.NewByteArray(cs.Script),
|
||||
stackitem.NewByteArray(manifest),
|
||||
stackitem.NewBool(cs.HasStorage()),
|
||||
stackitem.NewBool(cs.IsPayable()),
|
||||
}), nil
|
||||
}
|
||||
|
||||
// bcGetContract returns contract.
|
||||
func bcGetContract(ic *interop.Context, v *vm.VM) error {
|
||||
hashbytes := v.Estack().Pop().Bytes()
|
||||
|
@ -92,9 +106,13 @@ func bcGetContract(ic *interop.Context, v *vm.VM) error {
|
|||
}
|
||||
cs, err := ic.DAO.GetContractState(hash)
|
||||
if err != nil {
|
||||
v.Estack().PushVal([]byte{})
|
||||
v.Estack().PushVal(stackitem.Null{})
|
||||
} else {
|
||||
v.Estack().PushVal(stackitem.NewInterop(cs))
|
||||
item, err := contractToStackItem(cs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.Estack().PushVal(item)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -292,3 +292,31 @@ func TestRuntimeGetInvocationCounter(t *testing.T) {
|
|||
require.EqualValues(t, 42, v.Estack().Pop().BigInt().Int64())
|
||||
})
|
||||
}
|
||||
|
||||
func TestBlockchainGetContractState(t *testing.T) {
|
||||
v, cs, ic, bc := createVMAndContractState(t)
|
||||
defer bc.Close()
|
||||
require.NoError(t, ic.DAO.PutContractState(cs))
|
||||
|
||||
t.Run("positive", func(t *testing.T) {
|
||||
v.Estack().PushVal(cs.ScriptHash().BytesBE())
|
||||
require.NoError(t, bcGetContract(ic, v))
|
||||
|
||||
expectedManifest, err := cs.Manifest.MarshalJSON()
|
||||
require.NoError(t, err)
|
||||
actual := v.Estack().Pop().Array()
|
||||
require.Equal(t, 4, len(actual))
|
||||
require.Equal(t, cs.Script, actual[0].Value().([]byte))
|
||||
require.Equal(t, expectedManifest, actual[1].Value().([]byte))
|
||||
require.Equal(t, cs.HasStorage(), actual[2].Bool())
|
||||
require.Equal(t, cs.IsPayable(), actual[3].Bool())
|
||||
})
|
||||
|
||||
t.Run("uncknown contract state", func(t *testing.T) {
|
||||
v.Estack().PushVal(util.Uint160{1, 2, 3}.BytesBE())
|
||||
require.NoError(t, bcGetContract(ic, v))
|
||||
|
||||
actual := v.Estack().Pop().Item()
|
||||
require.Equal(t, stackitem.Null{}, actual)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -3,10 +3,6 @@ Package blockchain provides functions to access various blockchain data.
|
|||
*/
|
||||
package blockchain
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
||||
)
|
||||
|
||||
// Transaction represents a NEO transaction. It's similar to Transaction class
|
||||
// in Neo .net framework.
|
||||
type Transaction struct {
|
||||
|
@ -57,6 +53,14 @@ type Block struct {
|
|||
TransactionsLength int
|
||||
}
|
||||
|
||||
// Contract represents a Neo contract and is used in interop functions.
|
||||
type Contract struct {
|
||||
Script []byte
|
||||
Manifest []byte
|
||||
HasStorage bool
|
||||
IsPayable bool
|
||||
}
|
||||
|
||||
// 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
|
||||
|
@ -99,6 +103,6 @@ func GetTransactionHeight(hash []byte) int {
|
|||
// 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
|
||||
// `System.Blockchain.GetContract` syscall.
|
||||
func GetContract(scriptHash []byte) contract.Contract {
|
||||
return contract.Contract{}
|
||||
func GetContract(scriptHash []byte) Contract {
|
||||
return Contract{}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue