Merge pull request #1040 from nspcc-dev/feature/neo_to_system

Move interops from Neo.* to System.*
This commit is contained in:
Roman Khimov 2020-06-10 12:26:16 +03:00 committed by GitHub
commit c044bdc731
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 125 additions and 531 deletions

View file

@ -898,23 +898,23 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
c.currentSwitch = label c.currentSwitch = label
ast.Walk(c, n.X) ast.Walk(c, n.X)
emit.Syscall(c.prog.BinWriter, "Neo.Iterator.Create") emit.Syscall(c.prog.BinWriter, "System.Iterator.Create")
c.pushStackLabel(label, 1) c.pushStackLabel(label, 1)
c.setLabel(start) c.setLabel(start)
emit.Opcode(c.prog.BinWriter, opcode.DUP) emit.Opcode(c.prog.BinWriter, opcode.DUP)
emit.Syscall(c.prog.BinWriter, "Neo.Enumerator.Next") emit.Syscall(c.prog.BinWriter, "System.Enumerator.Next")
emit.Jmp(c.prog.BinWriter, opcode.JMPIFNOTL, end) emit.Jmp(c.prog.BinWriter, opcode.JMPIFNOTL, end)
if n.Key != nil { if n.Key != nil {
emit.Opcode(c.prog.BinWriter, opcode.DUP) emit.Opcode(c.prog.BinWriter, opcode.DUP)
emit.Syscall(c.prog.BinWriter, "Neo.Iterator.Key") emit.Syscall(c.prog.BinWriter, "System.Iterator.Key")
c.emitStoreVar(n.Key.(*ast.Ident).Name) c.emitStoreVar(n.Key.(*ast.Ident).Name)
} }
if n.Value != nil { if n.Value != nil {
emit.Opcode(c.prog.BinWriter, opcode.DUP) emit.Opcode(c.prog.BinWriter, opcode.DUP)
emit.Syscall(c.prog.BinWriter, "Neo.Enumerator.Value") emit.Syscall(c.prog.BinWriter, "System.Enumerator.Value")
c.emitStoreVar(n.Value.(*ast.Ident).Name) c.emitStoreVar(n.Value.(*ast.Ident).Name)
} }
@ -1092,7 +1092,7 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
emit.Opcode(c.prog.BinWriter, opcode.THROW) emit.Opcode(c.prog.BinWriter, opcode.THROW)
} else if isString(c.typeInfo.Types[arg].Type) { } else if isString(c.typeInfo.Types[arg].Type) {
ast.Walk(c, arg) ast.Walk(c, arg)
emit.Syscall(c.prog.BinWriter, "Neo.Runtime.Log") emit.Syscall(c.prog.BinWriter, "System.Runtime.Log")
emit.Opcode(c.prog.BinWriter, opcode.THROW) emit.Opcode(c.prog.BinWriter, opcode.THROW)
} else { } else {
c.prog.Err = errors.New("panic should have string or nil argument") c.prog.Err = errors.New("panic should have string or nil argument")

View file

@ -55,7 +55,7 @@ func getPanicSource(need bool, message string) string {
} }
func logGetter(logs *[]string) vm.InteropGetterFunc { func logGetter(logs *[]string) vm.InteropGetterFunc {
logID := emit.InteropNameToID([]byte("Neo.Runtime.Log")) logID := emit.InteropNameToID([]byte("System.Runtime.Log"))
return func(id uint32) *vm.InteropFuncPrice { return func(id uint32) *vm.InteropFuncPrice {
if id != logID { if id != logID {
return nil return nil

View file

@ -1,59 +1,40 @@
package compiler package compiler
var syscalls = map[string]map[string]string{ var syscalls = map[string]map[string]string{
"account": {
"GetBalance": "Neo.Account.GetBalance",
"GetScriptHash": "Neo.Account.GetScriptHash",
"GetVotes": "Neo.Account.GetVotes",
"IsStandard": "Neo.Account.IsStandard",
},
"crypto": { "crypto": {
"ECDsaVerify": "Neo.Crypto.ECDsaVerify", "ECDsaVerify": "Neo.Crypto.ECDsaVerify",
}, },
"enumerator": { "enumerator": {
"Concat": "Neo.Enumerator.Concat", "Concat": "System.Enumerator.Concat",
"Create": "Neo.Enumerator.Create", "Create": "System.Enumerator.Create",
"Next": "Neo.Enumerator.Next", "Next": "System.Enumerator.Next",
"Value": "Neo.Enumerator.Value", "Value": "System.Enumerator.Value",
}, },
"storage": { "storage": {
"ConvertContextToReadOnly": "Neo.StorageContext.AsReadOnly", "ConvertContextToReadOnly": "System.Storage.AsReadOnly",
"Delete": "Neo.Storage.Delete", "Delete": "System.Storage.Delete",
"Find": "Neo.Storage.Find", "Find": "System.Storage.Find",
"Get": "Neo.Storage.Get", "Get": "System.Storage.Get",
"GetContext": "Neo.Storage.GetContext", "GetContext": "System.Storage.GetContext",
"GetReadOnlyContext": "Neo.Storage.GetReadOnlyContext", "GetReadOnlyContext": "System.Storage.GetReadOnlyContext",
"Put": "Neo.Storage.Put", "Put": "System.Storage.Put",
}, },
"runtime": { "runtime": {
"GetTrigger": "Neo.Runtime.GetTrigger", "GetTrigger": "System.Runtime.GetTrigger",
"CheckWitness": "Neo.Runtime.CheckWitness", "CheckWitness": "System.Runtime.CheckWitness",
"Notify": "Neo.Runtime.Notify", "Notify": "System.Runtime.Notify",
"Log": "Neo.Runtime.Log", "Log": "System.Runtime.Log",
"GetTime": "Neo.Runtime.GetTime", "GetTime": "System.Runtime.GetTime",
"Serialize": "Neo.Runtime.Serialize", "Serialize": "System.Runtime.Serialize",
"Deserialize": "Neo.Runtime.Deserialize", "Deserialize": "System.Runtime.Deserialize",
}, },
"blockchain": { "blockchain": {
"GetAccount": "Neo.Blockchain.GetAccount",
"GetBlock": "System.Blockchain.GetBlock", "GetBlock": "System.Blockchain.GetBlock",
"GetContract": "Neo.Blockchain.GetContract", "GetContract": "System.Blockchain.GetContract",
"GetHeader": "Neo.Blockchain.GetHeader", "GetHeight": "System.Blockchain.GetHeight",
"GetHeight": "Neo.Blockchain.GetHeight",
"GetTransaction": "System.Blockchain.GetTransaction", "GetTransaction": "System.Blockchain.GetTransaction",
"GetTransactionFromBlock": "System.Blockchain.GetTransactionFromBlock", "GetTransactionFromBlock": "System.Blockchain.GetTransactionFromBlock",
"GetTransactionHeight": "System.Blockchain.GetTransactionHeight", "GetTransactionHeight": "System.Blockchain.GetTransactionHeight",
"GetValidators": "Neo.Blockchain.GetValidators",
},
"header": {
"GetIndex": "Neo.Header.GetIndex",
"GetHash": "Neo.Header.GetHash",
"GetPrevHash": "Neo.Header.GetPrevHash",
"GetTimestamp": "Neo.Header.GetTimestamp",
"GetVersion": "Neo.Header.GetVersion",
"GetMerkleRoot": "Neo.Header.GetMerkleRoot",
"GetConsensusData": "Neo.Header.GetConsensusData",
"GetNextConsensus": "Neo.Header.GetNextConsensus",
}, },
"contract": { "contract": {
"GetScript": "Neo.Contract.GetScript", "GetScript": "Neo.Contract.GetScript",
@ -70,15 +51,12 @@ var syscalls = map[string]map[string]string{
"GetExecutingScriptHash": "System.ExecutionEngine.GetExecutingScriptHash", "GetExecutingScriptHash": "System.ExecutionEngine.GetExecutingScriptHash",
}, },
"iterator": { "iterator": {
"Concat": "Neo.Iterator.Concat", "Concat": "System.Iterator.Concat",
"Create": "Neo.Iterator.Create", "Create": "System.Iterator.Create",
"Key": "Neo.Iterator.Key", "Key": "System.Iterator.Key",
"Keys": "Neo.Iterator.Keys", "Keys": "System.Iterator.Keys",
"Next": "Neo.Iterator.Next", "Next": "System.Enumerator.Next",
"Value": "Neo.Iterator.Value", "Value": "System.Enumerator.Value",
"Values": "Neo.Iterator.Values", "Values": "System.Iterator.Values",
},
"witness": {
"GetVerificationScript": "Neo.Witness.GetVerificationScript",
}, },
} }

View file

@ -82,10 +82,10 @@ func newStoragePlugin() *storagePlugin {
mem: make(map[string][]byte), mem: make(map[string][]byte),
interops: make(map[uint32]vm.InteropFunc), interops: make(map[uint32]vm.InteropFunc),
} }
s.interops[emit.InteropNameToID([]byte("Neo.Storage.Get"))] = s.Get s.interops[emit.InteropNameToID([]byte("System.Storage.Get"))] = s.Get
s.interops[emit.InteropNameToID([]byte("Neo.Storage.Put"))] = s.Put s.interops[emit.InteropNameToID([]byte("System.Storage.Put"))] = s.Put
s.interops[emit.InteropNameToID([]byte("Neo.Storage.GetContext"))] = s.GetContext s.interops[emit.InteropNameToID([]byte("System.Storage.GetContext"))] = s.GetContext
s.interops[emit.InteropNameToID([]byte("Neo.Runtime.Notify"))] = s.Notify s.interops[emit.InteropNameToID([]byte("System.Runtime.Notify"))] = s.Notify
return s return s
} }

View file

@ -265,7 +265,7 @@ func TestSubscriptions(t *testing.T) {
script := io.NewBufBinWriter() script := io.NewBufBinWriter()
emit.Bytes(script.BinWriter, []byte("yay!")) emit.Bytes(script.BinWriter, []byte("yay!"))
emit.Syscall(script.BinWriter, "Neo.Runtime.Notify") emit.Syscall(script.BinWriter, "System.Runtime.Notify")
require.NoError(t, script.Err) require.NoError(t, script.Err)
txGood1 := transaction.New(script.Bytes(), 0) txGood1 := transaction.New(script.Bytes(), 0)
txGood1.Sender = neoOwner txGood1.Sender = neoOwner
@ -276,7 +276,7 @@ func TestSubscriptions(t *testing.T) {
// Reset() reuses the script buffer and we need to keep scripts. // Reset() reuses the script buffer and we need to keep scripts.
script = io.NewBufBinWriter() script = io.NewBufBinWriter()
emit.Bytes(script.BinWriter, []byte("nay!")) emit.Bytes(script.BinWriter, []byte("nay!"))
emit.Syscall(script.BinWriter, "Neo.Runtime.Notify") emit.Syscall(script.BinWriter, "System.Runtime.Notify")
emit.Opcode(script.BinWriter, opcode.THROW) emit.Opcode(script.BinWriter, opcode.THROW)
require.NoError(t, script.Err) require.NoError(t, script.Err)
txBad := transaction.New(script.Bytes(), 0) txBad := transaction.New(script.Bytes(), 0)
@ -287,7 +287,7 @@ func TestSubscriptions(t *testing.T) {
script = io.NewBufBinWriter() script = io.NewBufBinWriter()
emit.Bytes(script.BinWriter, []byte("yay! yay! yay!")) emit.Bytes(script.BinWriter, []byte("yay! yay! yay!"))
emit.Syscall(script.BinWriter, "Neo.Runtime.Notify") emit.Syscall(script.BinWriter, "System.Runtime.Notify")
require.NoError(t, script.Err) require.NoError(t, script.Err)
txGood2 := transaction.New(script.Bytes(), 0) txGood2 := transaction.New(script.Bytes(), 0)
txGood2.Sender = neoOwner txGood2.Sender = neoOwner

View file

@ -8,10 +8,8 @@ import (
"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/core/state" "github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger" "github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
) )
@ -27,109 +25,6 @@ const (
MaxContractStringLen = 252 MaxContractStringLen = 252
) )
// headerGetVersion returns version from the header.
func headerGetVersion(ic *interop.Context, v *vm.VM) error {
header, err := popHeaderFromVM(v)
if err != nil {
return err
}
v.Estack().PushVal(header.Version)
return nil
}
// headerGetMerkleRoot returns version from the header.
func headerGetMerkleRoot(ic *interop.Context, v *vm.VM) error {
header, err := popHeaderFromVM(v)
if err != nil {
return err
}
v.Estack().PushVal(header.MerkleRoot.BytesBE())
return nil
}
// headerGetNextConsensus returns version from the header.
func headerGetNextConsensus(ic *interop.Context, v *vm.VM) error {
header, err := popHeaderFromVM(v)
if err != nil {
return err
}
v.Estack().PushVal(header.NextConsensus.BytesBE())
return nil
}
// witnessGetVerificationScript returns current witness' script.
func witnessGetVerificationScript(ic *interop.Context, v *vm.VM) error {
witInterface := v.Estack().Pop().Value()
wit, ok := witInterface.(*transaction.Witness)
if !ok {
return errors.New("value is not a witness")
}
// It's important not to share wit.VerificationScript slice with the code running in VM.
script := make([]byte, len(wit.VerificationScript))
copy(script, wit.VerificationScript)
v.Estack().PushVal(script)
return nil
}
// bcGetAccount returns or creates an account.
func bcGetAccount(ic *interop.Context, v *vm.VM) error {
accbytes := v.Estack().Pop().Bytes()
acchash, err := util.Uint160DecodeBytesBE(accbytes)
if err != nil {
return err
}
acc, err := ic.DAO.GetAccountStateOrNew(acchash)
if err != nil {
return err
}
v.Estack().PushVal(stackitem.NewInterop(acc))
return nil
}
// accountGetBalance returns balance for a given account.
func accountGetBalance(ic *interop.Context, v *vm.VM) error {
accInterface := v.Estack().Pop().Value()
acc, ok := accInterface.(*state.Account)
if !ok {
return fmt.Errorf("%T is not an account state", acc)
}
asbytes := v.Estack().Pop().Bytes()
ashash, err := util.Uint256DecodeBytesBE(asbytes)
if err != nil {
return err
}
balance, ok := acc.GetBalanceValues()[ashash]
if !ok {
balance = util.Fixed8(0)
}
v.Estack().PushVal(int64(balance))
return nil
}
// accountGetScriptHash returns script hash of a given account.
func accountGetScriptHash(ic *interop.Context, v *vm.VM) error {
accInterface := v.Estack().Pop().Value()
acc, ok := accInterface.(*state.Account)
if !ok {
return fmt.Errorf("%T is not an account state", acc)
}
v.Estack().PushVal(acc.ScriptHash.BytesBE())
return nil
}
// accountIsStandard checks whether given account is standard.
func accountIsStandard(ic *interop.Context, v *vm.VM) error {
accbytes := v.Estack().Pop().Bytes()
acchash, err := util.Uint160DecodeBytesBE(accbytes)
if err != nil {
return err
}
contract, err := ic.DAO.GetContractState(acchash)
res := err != nil || vm.IsStandardContract(contract.Script)
v.Estack().PushVal(res)
return nil
}
// storageFind finds stored key-value pair. // storageFind finds stored key-value pair.
func storageFind(ic *interop.Context, v *vm.VM) error { func storageFind(ic *interop.Context, v *vm.VM) error {
stcInterface := v.Estack().Pop().Value() stcInterface := v.Estack().Pop().Value()

View file

@ -2,7 +2,6 @@ package core
import ( import (
"fmt" "fmt"
"math/big"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/block"
@ -136,64 +135,6 @@ func TestStorageFind(t *testing.T) {
}) })
} }
func TestHeaderGetVersion(t *testing.T) {
v, block, context, chain := createVMAndPushBlock(t)
defer chain.Close()
err := headerGetVersion(context, v)
require.NoError(t, err)
value := v.Estack().Pop().Value().(*big.Int)
require.Equal(t, uint64(block.Version), value.Uint64())
}
func TestHeaderGetVersion_Negative(t *testing.T) {
v := vm.New()
block := newDumbBlock()
chain := newTestChain(t)
defer chain.Close()
context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore()), block, nil)
v.Estack().PushVal(stackitem.NewBool(false))
err := headerGetVersion(context, v)
require.Errorf(t, err, "value is not a header or block")
}
func TestHeaderGetMerkleRoot(t *testing.T) {
v, block, context, chain := createVMAndPushBlock(t)
defer chain.Close()
err := headerGetMerkleRoot(context, v)
require.NoError(t, err)
value := v.Estack().Pop().Value()
require.Equal(t, block.MerkleRoot.BytesBE(), value)
}
func TestHeaderGetNextConsensus(t *testing.T) {
v, block, context, chain := createVMAndPushBlock(t)
defer chain.Close()
err := headerGetNextConsensus(context, v)
require.NoError(t, err)
value := v.Estack().Pop().Value()
require.Equal(t, block.NextConsensus.BytesBE(), value)
}
func TestWitnessGetVerificationScript(t *testing.T) {
v := vm.New()
script := []byte{byte(opcode.PUSHM1), byte(opcode.RET)}
witness := transaction.Witness{InvocationScript: nil, VerificationScript: script}
chain := newTestChain(t)
defer chain.Close()
context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore()), nil, nil)
v.Estack().PushVal(stackitem.NewInterop(&witness))
err := witnessGetVerificationScript(context, v)
require.NoError(t, err)
value := v.Estack().Pop().Value().([]byte)
require.Equal(t, witness.VerificationScript, value)
}
func TestECDSAVerify(t *testing.T) { func TestECDSAVerify(t *testing.T) {
priv, err := keys.NewPrivateKey() priv, err := keys.NewPrivateKey()
require.NoError(t, err) require.NoError(t, err)
@ -270,17 +211,6 @@ func TestECDSAVerify(t *testing.T) {
}) })
} }
func TestAccountGetScriptHash(t *testing.T) {
v, accState, context, chain := createVMAndAccState(t)
defer chain.Close()
v.Estack().PushVal(stackitem.NewInterop(accState))
err := accountGetScriptHash(context, v)
require.NoError(t, err)
hash := v.Estack().Pop().Value()
require.Equal(t, accState.ScriptHash.BytesBE(), hash)
}
func TestContractGetScript(t *testing.T) { func TestContractGetScript(t *testing.T) {
v, contractState, context, chain := createVMAndContractState(t) v, contractState, context, chain := createVMAndContractState(t)
defer chain.Close() defer chain.Close()

View file

@ -98,21 +98,6 @@ func bcGetContract(ic *interop.Context, v *vm.VM) error {
return nil return nil
} }
// bcGetHeader returns block header.
func bcGetHeader(ic *interop.Context, v *vm.VM) error {
hash, err := getBlockHashFromElement(ic.Chain, v.Estack().Pop())
if err != nil {
return err
}
header, err := ic.Chain.GetHeader(hash)
if err != nil {
v.Estack().PushVal([]byte{})
} else {
v.Estack().PushVal(stackitem.NewInterop(header))
}
return nil
}
// bcGetHeight returns blockchain height. // bcGetHeight returns blockchain height.
func bcGetHeight(ic *interop.Context, v *vm.VM) error { func bcGetHeight(ic *interop.Context, v *vm.VM) error {
v.Estack().PushVal(ic.Chain.BlockHeight()) v.Estack().PushVal(ic.Chain.BlockHeight())

View file

@ -64,7 +64,6 @@ func getInteropFromSlice(ic *interop.Context, slice []interop.Function) func(uin
var systemInterops = []interop.Function{ var systemInterops = []interop.Function{
{Name: "System.Blockchain.GetBlock", Func: bcGetBlock, Price: 250}, {Name: "System.Blockchain.GetBlock", Func: bcGetBlock, Price: 250},
{Name: "System.Blockchain.GetContract", Func: bcGetContract, Price: 100}, {Name: "System.Blockchain.GetContract", Func: bcGetContract, Price: 100},
{Name: "System.Blockchain.GetHeader", Func: bcGetHeader, Price: 100},
{Name: "System.Blockchain.GetHeight", Func: bcGetHeight, Price: 1}, {Name: "System.Blockchain.GetHeight", Func: bcGetHeight, Price: 1},
{Name: "System.Blockchain.GetTransaction", Func: bcGetTransaction, Price: 100}, {Name: "System.Blockchain.GetTransaction", Func: bcGetTransaction, Price: 100},
{Name: "System.Blockchain.GetTransactionFromBlock", Func: bcGetTransactionFromBlock, Price: 100}, {Name: "System.Blockchain.GetTransactionFromBlock", Func: bcGetTransactionFromBlock, Price: 100},
@ -73,14 +72,19 @@ var systemInterops = []interop.Function{
{Name: "System.Contract.CallEx", Func: contractCallEx, Price: 1}, {Name: "System.Contract.CallEx", Func: contractCallEx, Price: 1},
{Name: "System.Contract.Destroy", Func: contractDestroy, Price: 1}, {Name: "System.Contract.Destroy", Func: contractDestroy, Price: 1},
{Name: "System.Contract.GetStorageContext", Func: contractGetStorageContext, Price: 1}, {Name: "System.Contract.GetStorageContext", Func: contractGetStorageContext, Price: 1},
{Name: "System.Enumerator.Concat", Func: enumerator.Concat, Price: 1},
{Name: "System.Enumerator.Create", Func: enumerator.Create, Price: 1},
{Name: "System.Enumerator.Next", Func: enumerator.Next, Price: 1},
{Name: "System.Enumerator.Value", Func: enumerator.Value, Price: 1},
{Name: "System.ExecutionEngine.GetCallingScriptHash", Func: engineGetCallingScriptHash, Price: 1}, {Name: "System.ExecutionEngine.GetCallingScriptHash", Func: engineGetCallingScriptHash, Price: 1},
{Name: "System.ExecutionEngine.GetEntryScriptHash", Func: engineGetEntryScriptHash, Price: 1}, {Name: "System.ExecutionEngine.GetEntryScriptHash", Func: engineGetEntryScriptHash, Price: 1},
{Name: "System.ExecutionEngine.GetExecutingScriptHash", Func: engineGetExecutingScriptHash, Price: 1}, {Name: "System.ExecutionEngine.GetExecutingScriptHash", Func: engineGetExecutingScriptHash, Price: 1},
{Name: "System.ExecutionEngine.GetScriptContainer", Func: engineGetScriptContainer, Price: 1}, {Name: "System.ExecutionEngine.GetScriptContainer", Func: engineGetScriptContainer, Price: 1},
{Name: "System.Header.GetHash", Func: headerGetHash, Price: 1}, {Name: "System.Iterator.Concat", Func: iterator.Concat, Price: 1},
{Name: "System.Header.GetIndex", Func: headerGetIndex, Price: 1}, {Name: "System.Iterator.Create", Func: iterator.Create, Price: 1},
{Name: "System.Header.GetPrevHash", Func: headerGetPrevHash, Price: 1}, {Name: "System.Iterator.Key", Func: iterator.Key, Price: 1},
{Name: "System.Header.GetTimestamp", Func: headerGetTimestamp, Price: 1}, {Name: "System.Iterator.Keys", Func: iterator.Keys, Price: 1},
{Name: "System.Iterator.Values", Func: iterator.Values, Price: 1},
{Name: "System.Runtime.CheckWitness", Func: runtime.CheckWitness, Price: 200}, {Name: "System.Runtime.CheckWitness", Func: runtime.CheckWitness, Price: 200},
{Name: "System.Runtime.Deserialize", Func: runtimeDeserialize, Price: 1}, {Name: "System.Runtime.Deserialize", Func: runtimeDeserialize, Price: 1},
{Name: "System.Runtime.GetTime", Func: runtimeGetTime, Price: 1}, {Name: "System.Runtime.GetTime", Func: runtimeGetTime, Price: 1},
@ -90,22 +94,16 @@ var systemInterops = []interop.Function{
{Name: "System.Runtime.Platform", Func: runtimePlatform, Price: 1}, {Name: "System.Runtime.Platform", Func: runtimePlatform, Price: 1},
{Name: "System.Runtime.Serialize", Func: runtimeSerialize, Price: 1}, {Name: "System.Runtime.Serialize", Func: runtimeSerialize, Price: 1},
{Name: "System.Storage.Delete", Func: storageDelete, Price: 100}, {Name: "System.Storage.Delete", Func: storageDelete, Price: 100},
{Name: "System.Storage.Find", Func: storageFind, Price: 1},
{Name: "System.Storage.Get", Func: storageGet, Price: 100}, {Name: "System.Storage.Get", Func: storageGet, Price: 100},
{Name: "System.Storage.GetContext", Func: storageGetContext, Price: 1}, {Name: "System.Storage.GetContext", Func: storageGetContext, Price: 1},
{Name: "System.Storage.GetReadOnlyContext", Func: storageGetReadOnlyContext, Price: 1}, {Name: "System.Storage.GetReadOnlyContext", Func: storageGetReadOnlyContext, Price: 1},
{Name: "System.Storage.Put", Func: storagePut, Price: 0}, // These don't have static price in C# code. {Name: "System.Storage.Put", Func: storagePut, Price: 0}, // These don't have static price in C# code.
{Name: "System.Storage.PutEx", Func: storagePutEx, Price: 0}, {Name: "System.Storage.PutEx", Func: storagePutEx, Price: 0},
{Name: "System.StorageContext.AsReadOnly", Func: storageContextAsReadOnly, Price: 1}, {Name: "System.Storage.AsReadOnly", Func: storageContextAsReadOnly, Price: 1},
} }
var neoInterops = []interop.Function{ var neoInterops = []interop.Function{
{Name: "Neo.Account.GetBalance", Func: accountGetBalance, Price: 1},
{Name: "Neo.Account.GetScriptHash", Func: accountGetScriptHash, Price: 1},
{Name: "Neo.Account.IsStandard", Func: accountIsStandard, Price: 100},
{Name: "Neo.Blockchain.GetAccount", Func: bcGetAccount, Price: 100},
{Name: "Neo.Blockchain.GetContract", Func: bcGetContract, Price: 100},
{Name: "Neo.Blockchain.GetHeader", Func: bcGetHeader, Price: 100},
{Name: "Neo.Blockchain.GetHeight", Func: bcGetHeight, Price: 1},
{Name: "Neo.Contract.Create", Func: contractCreate, Price: 0}, {Name: "Neo.Contract.Create", Func: contractCreate, Price: 0},
{Name: "Neo.Contract.Destroy", Func: contractDestroy, Price: 1}, {Name: "Neo.Contract.Destroy", Func: contractDestroy, Price: 1},
{Name: "Neo.Contract.GetScript", Func: contractGetScript, Price: 1}, {Name: "Neo.Contract.GetScript", Func: contractGetScript, Price: 1},
@ -115,42 +113,7 @@ var neoInterops = []interop.Function{
{Name: "Neo.Crypto.ECDsaVerify", Func: crypto.ECDSAVerify, Price: 1}, {Name: "Neo.Crypto.ECDsaVerify", Func: crypto.ECDSAVerify, Price: 1},
{Name: "Neo.Crypto.ECDsaCheckMultiSig", Func: crypto.ECDSACheckMultisig, Price: 1}, {Name: "Neo.Crypto.ECDsaCheckMultiSig", Func: crypto.ECDSACheckMultisig, Price: 1},
{Name: "Neo.Crypto.SHA256", Func: crypto.Sha256, Price: 1}, {Name: "Neo.Crypto.SHA256", Func: crypto.Sha256, Price: 1},
{Name: "Neo.Enumerator.Concat", Func: enumerator.Concat, Price: 1},
{Name: "Neo.Enumerator.Create", Func: enumerator.Create, Price: 1},
{Name: "Neo.Enumerator.Next", Func: enumerator.Next, Price: 1},
{Name: "Neo.Enumerator.Value", Func: enumerator.Value, Price: 1},
{Name: "Neo.Header.GetHash", Func: headerGetHash, Price: 1},
{Name: "Neo.Header.GetIndex", Func: headerGetIndex, Price: 1},
{Name: "Neo.Header.GetMerkleRoot", Func: headerGetMerkleRoot, Price: 1},
{Name: "Neo.Header.GetNextConsensus", Func: headerGetNextConsensus, Price: 1},
{Name: "Neo.Header.GetPrevHash", Func: headerGetPrevHash, Price: 1},
{Name: "Neo.Header.GetTimestamp", Func: headerGetTimestamp, Price: 1},
{Name: "Neo.Header.GetVersion", Func: headerGetVersion, Price: 1},
{Name: "Neo.Iterator.Concat", Func: iterator.Concat, Price: 1},
{Name: "Neo.Iterator.Create", Func: iterator.Create, Price: 1},
{Name: "Neo.Iterator.Key", Func: iterator.Key, Price: 1},
{Name: "Neo.Iterator.Keys", Func: iterator.Keys, Price: 1},
{Name: "Neo.Iterator.Values", Func: iterator.Values, Price: 1},
{Name: "Neo.Native.Deploy", Func: native.Deploy, Price: 1}, {Name: "Neo.Native.Deploy", Func: native.Deploy, Price: 1},
{Name: "Neo.Runtime.CheckWitness", Func: runtime.CheckWitness, Price: 200},
{Name: "Neo.Runtime.Deserialize", Func: runtimeDeserialize, Price: 1},
{Name: "Neo.Runtime.GetTime", Func: runtimeGetTime, Price: 1},
{Name: "Neo.Runtime.GetTrigger", Func: runtimeGetTrigger, Price: 1},
{Name: "Neo.Runtime.Log", Func: runtimeLog, Price: 1},
{Name: "Neo.Runtime.Notify", Func: runtimeNotify, Price: 1},
{Name: "Neo.Runtime.Serialize", Func: runtimeSerialize, Price: 1},
{Name: "Neo.Storage.Delete", Func: storageDelete, Price: 100},
{Name: "Neo.Storage.Find", Func: storageFind, Price: 1},
{Name: "Neo.Storage.Get", Func: storageGet, Price: 100},
{Name: "Neo.Storage.GetContext", Func: storageGetContext, Price: 1},
{Name: "Neo.Storage.GetReadOnlyContext", Func: storageGetReadOnlyContext, Price: 1},
{Name: "Neo.Storage.Put", Func: storagePut, Price: 0},
{Name: "Neo.StorageContext.AsReadOnly", Func: storageContextAsReadOnly, Price: 1},
{Name: "Neo.Witness.GetVerificationScript", Func: witnessGetVerificationScript, Price: 100},
// Aliases.
{Name: "Neo.Iterator.Next", Func: enumerator.Next, Price: 1},
{Name: "Neo.Iterator.Value", Func: enumerator.Value, Price: 1},
} }
// initIDinInteropsSlice initializes IDs from names in one given // initIDinInteropsSlice initializes IDs from names in one given

View file

@ -32,25 +32,15 @@ func TestUnexpectedNonInterops(t *testing.T) {
// All of these functions expect an interop item on the stack. // All of these functions expect an interop item on the stack.
funcs := []func(*interop.Context, *vm.VM) error{ funcs := []func(*interop.Context, *vm.VM) error{
accountGetBalance,
accountGetScriptHash,
contractGetScript, contractGetScript,
contractGetStorageContext, contractGetStorageContext,
contractIsPayable, contractIsPayable,
headerGetHash,
headerGetIndex,
headerGetMerkleRoot,
headerGetNextConsensus,
headerGetPrevHash,
headerGetTimestamp,
headerGetVersion,
storageContextAsReadOnly, storageContextAsReadOnly,
storageDelete, storageDelete,
storageFind, storageFind,
storageGet, storageGet,
storagePut, storagePut,
storagePutEx, storagePutEx,
witnessGetVerificationScript,
} }
for _, f := range funcs { for _, f := range funcs {
for k, v := range vals { for k, v := range vals {

View file

@ -1,43 +0,0 @@
/*
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
// 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 (20 bytes in BE
// representation). It uses `Neo.Account.GetBalance` syscall internally.
func GetScriptHash(a Account) []byte {
return nil
}
// 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 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
}

View file

@ -4,9 +4,7 @@ Package blockchain provides functions to access various blockchain data.
package blockchain package blockchain
import ( import (
"github.com/nspcc-dev/neo-go/pkg/interop/account"
"github.com/nspcc-dev/neo-go/pkg/interop/contract" "github.com/nspcc-dev/neo-go/pkg/interop/contract"
"github.com/nspcc-dev/neo-go/pkg/interop/header"
) )
// Transaction represents a NEO transaction. It's similar to Transaction class // Transaction represents a NEO transaction. It's similar to Transaction class
@ -63,19 +61,11 @@ type Block struct {
// Note that when transaction is being run as a part of new block this block is // 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 // considered as not yet accepted (persisted) and thus you'll get an index of
// the previous (already accepted) block. This function uses // the previous (already accepted) block. This function uses
// `Neo.Blockchain.GetHeight` syscall. // `System.Blockchain.GetHeight` syscall.
func GetHeight() int { func GetHeight() int {
return 0 return 0
} }
// 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 block found by the given hash or index (with the same // GetBlock returns block found by the given hash or index (with the same
// encoding as for GetHeader). This function uses `System.Blockchain.GetBlock` // encoding as for GetHeader). This function uses `System.Blockchain.GetBlock`
// syscall. // syscall.
@ -108,22 +98,7 @@ func GetTransactionHeight(hash []byte) int {
// GetContract returns contract found by the given script hash (160 bit in BE // 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 // 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 // for details on how to use the returned structure. This function uses
// `Neo.Blockchain.GetContract` syscall. // `System.Blockchain.GetContract` syscall.
func GetContract(scriptHash []byte) contract.Contract { func GetContract(scriptHash []byte) contract.Contract {
return contract.Contract{} return contract.Contract{}
} }
// 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 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
}

View file

@ -11,7 +11,7 @@ type Enumerator struct{}
// Create creates a new enumerator from the given items (slice or structure). // 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 // 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` // advance it first with Next. This function uses `System.Enumerator.Create`
// syscall. // syscall.
func Create(items []interface{}) Enumerator { func Create(items []interface{}) Enumerator {
return Enumerator{} return Enumerator{}
@ -20,13 +20,13 @@ func Create(items []interface{}) Enumerator {
// Next moves position of the given enumerator by one and returns a bool that // 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, // 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 // 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. // enumerator. This function uses `System.Enumerator.Next` syscall.
func Next(e Enumerator) bool { func Next(e Enumerator) bool {
return true return true
} }
// Value returns current enumerator's item value, it's only valid to call it // 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. // after Next returning true. This function uses `System.Enumerator.Value` syscall.
func Value(e Enumerator) interface{} { func Value(e Enumerator) interface{} {
return nil return nil
} }
@ -35,7 +35,7 @@ func Value(e Enumerator) interface{} {
// a first and then continue with b. Enumerator positions are not reset for a // 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 // 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 // Enumerator will point at this new position and never go back to previous
// values. This function uses `Neo.Enumerator.Concat` syscall. // values. This function uses `System.Enumerator.Concat` syscall.
func Concat(a, b Enumerator) Enumerator { func Concat(a, b Enumerator) Enumerator {
return Enumerator{} return Enumerator{}
} }

View file

@ -1,61 +0,0 @@
/*
Package header contains functions working with block headers.
*/
package header
// 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 (height) of the given header. It uses
// `Neo.Header.GetIndex` syscall.
func GetIndex(h Header) int {
return 0
}
// 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 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. It uses
// `Neo.Header.GetTimestamp` syscall.
func GetTimestamp(h Header) int {
return 0
}
// 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 (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 (nonce) of the given header.
// It uses `Neo.Header.GetConsensusData` syscall.
func GetConsensusData(h Header) int {
return 0
}
// 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
}

View file

@ -13,7 +13,7 @@ type Iterator struct{}
// Create creates an iterator from the given items (array, struct or map). A new // 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 // 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. // need to call Next first. This function uses `System.Iterator.Create` syscall.
func Create(items []interface{}) Iterator { func Create(items []interface{}) Iterator {
return Iterator{} return Iterator{}
} }
@ -24,13 +24,13 @@ func Create(items []interface{}) Iterator {
// Iterator will point at this new position and never go back to previous // Iterator will point at this new position and never go back to previous
// key-value pairs. Concatenated iterators also remain completely independent // key-value pairs. Concatenated iterators also remain completely independent
// in results they return, so if both contain the same key you'll receive this // in results they return, so if both contain the same key you'll receive this
// key twice when iterating. This function uses `Neo.Iterator.Concat` syscall. // key twice when iterating. This function uses `System.Iterator.Concat` syscall.
func Concat(a, b Iterator) Iterator { func Concat(a, b Iterator) Iterator {
return Iterator{} return Iterator{}
} }
// Key returns iterator's key at current position. It's only valid to call after // 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. // successful Next call. This function uses `System.Iterator.Key` syscall.
func Key(it Iterator) interface{} { func Key(it Iterator) interface{} {
return nil return nil
} }
@ -38,20 +38,20 @@ func Key(it Iterator) interface{} {
// Keys returns Enumerator ranging over keys or the given Iterator. Note that // Keys returns Enumerator ranging over keys or the given Iterator. Note that
// this Enumerator is actually directly tied to the underlying Iterator, so 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 // advancing it with Next will actually advance the Iterator too. This function
// uses `Neo.Iterator.Keys` syscall. // uses `System.Iterator.Keys` syscall.
func Keys(it Iterator) enumerator.Enumerator { func Keys(it Iterator) enumerator.Enumerator {
return enumerator.Enumerator{} return enumerator.Enumerator{}
} }
// Next advances the iterator returning true if it is was successful (and you // 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 // can use Key or Value) and false otherwise (and there are no more elements in
// this Iterator). This function uses `Neo.Iterator.Next` syscall. // this Iterator). This function uses `System.Enumerator.Next` syscall.
func Next(it Iterator) bool { func Next(it Iterator) bool {
return true return true
} }
// Value returns iterator's current value. It's only valid to call after // Value returns iterator's current value. It's only valid to call after
// successful Next call. This function uses `Neo.Iterator.Value` syscall. // successful Next call. This function uses `System.Enumerator.Value` syscall.
func Value(it Iterator) interface{} { func Value(it Iterator) interface{} {
return nil return nil
} }
@ -59,7 +59,7 @@ func Value(it Iterator) interface{} {
// Values returns Enumerator ranging over values or the given Iterator. Note that // Values returns Enumerator ranging over values or the given Iterator. Note that
// this Enumerator is actually directly tied to the underlying Iterator, so 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 // advancing it with Next will actually advance the Iterator too. This function
// uses `Neo.Iterator.Values` syscall. // uses `System.Iterator.Values` syscall.
func Values(it Iterator) enumerator.Enumerator { func Values(it Iterator) enumerator.Enumerator {
return enumerator.Enumerator{} return enumerator.Enumerator{}
} }

View file

@ -6,14 +6,14 @@ package runtime
// CheckWitness verifies if the given script hash (160-bit BE value in a 20 byte // 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 // slice) or key (compressed serialized 33-byte form) is one of the signers of
// this invocation. It uses `Neo.Runtime.CheckWitness` syscall. // this invocation. It uses `System.Runtime.CheckWitness` syscall.
func CheckWitness(hashOrKey []byte) bool { func CheckWitness(hashOrKey []byte) bool {
return true return true
} }
// Log instructs VM to log the given message. It's mostly used for debugging // 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 // 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. // only visible in the VM logs. This function uses `System.Runtime.Log` syscall.
func Log(message string) {} func Log(message string) {}
// Notify sends a notification (collecting all arguments in an array) to the // Notify sends a notification (collecting all arguments in an array) to the
@ -21,14 +21,14 @@ func Log(message string) {}
// notification is saved in application log. It's intended to be used as a // 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 // part of contract's API to external systems, these events can be monitored
// from outside and act upon accordingly. This function uses // from outside and act upon accordingly. This function uses
// `Neo.Runtime.Notify` syscall. // `System.Runtime.Notify` syscall.
func Notify(arg ...interface{}) {} func Notify(arg ...interface{}) {}
// GetTime returns the timestamp of the most recent block. Note that when running // 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 // 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 // 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 // time of this (currently being processed) block. This function uses
// `Neo.Runtime.GetTime` syscall. // `System.Runtime.GetTime` syscall.
func GetTime() int { func GetTime() int {
return 0 return 0
} }
@ -38,7 +38,7 @@ func GetTime() int {
// as a part of verification process from running it as a regular application. // 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 // Some interop functions (especially ones that change the state in any way) are
// not available when running with verification trigger. This function uses // not available when running with verification trigger. This function uses
// `Neo.Runtime.GetTrigger` syscall. // `System.Runtime.GetTrigger` syscall.
func GetTrigger() byte { func GetTrigger() byte {
return 0x00 return 0x00
} }
@ -58,13 +58,13 @@ func Verification() byte {
// Serialize serializes any given item into a byte slice. It works for all // 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 // 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 // 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. // the external event receiver. It uses `System.Runtime.Serialize` syscall.
func Serialize(item interface{}) []byte { func Serialize(item interface{}) []byte {
return nil return nil
} }
// Deserialize unpacks previously serialized value from a byte slice, it's the // Deserialize unpacks previously serialized value from a byte slice, it's the
// opposite of Serialize. It uses `Neo.Runtime.Deserialize` syscall. // opposite of Serialize. It uses `System.Runtime.Deserialize` syscall.
func Deserialize(b []byte) interface{} { func Deserialize(b []byte) interface{} {
return nil return nil
} }

View file

@ -17,38 +17,38 @@ type Context struct{}
// ConvertContextToReadOnly returns new context from the given one, but with // ConvertContextToReadOnly returns new context from the given one, but with
// writing capability turned off, so that you could only invoke Get and Find // 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 // using this new Context. If Context is already read-only this function is a
// no-op. It uses `Neo.StorageContext.AsReadOnly` syscall. // no-op. It uses `System.Storage.AsReadOnly` syscall.
func ConvertContextToReadOnly(ctx Context) Context { return Context{} } func ConvertContextToReadOnly(ctx Context) Context { return Context{} }
// GetContext returns current contract's (that invokes this function) storage // GetContext returns current contract's (that invokes this function) storage
// context. It uses `Neo.Storage.GetContext` syscall. // context. It uses `System.Storage.GetContext` syscall.
func GetContext() Context { return Context{} } func GetContext() Context { return Context{} }
// GetReadOnlyContext returns current contract's (that invokes this function) // GetReadOnlyContext returns current contract's (that invokes this function)
// storage context in read-only mode, you can use this context for Get and Find // 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 // functions, but using it for Put and Delete will fail. It uses
// `Neo.Storage.GetReadOnlyContext` syscall. // `System.Storage.GetReadOnlyContext` syscall.
func GetReadOnlyContext() Context { return Context{} } func GetReadOnlyContext() Context { return Context{} }
// Put saves given value with given key in the storage using given 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 // 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 // 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 // complex types). To put more complex types there serialize them first using
// runtime.Serialize. This function uses `Neo.Storage.Put` syscall. // runtime.Serialize. This function uses `System.Storage.Put` syscall.
func Put(ctx Context, key interface{}, value interface{}) {} func Put(ctx Context, key interface{}, value interface{}) {}
// Get retrieves value stored for the given key using given Context. See Put // Get retrieves value stored for the given key using given Context. See Put
// documentation on possible key and value types. This function uses // documentation on possible key and value types. This function uses
// `Neo.Storage.Get` syscall. // `System.Storage.Get` syscall.
func Get(ctx Context, key interface{}) interface{} { return 0 } func Get(ctx Context, key interface{}) interface{} { return 0 }
// Delete removes key-value pair from storage by the given key using given // Delete removes key-value pair from storage by the given key using given
// Context. See Put documentation on possible key types. This function uses // Context. See Put documentation on possible key types. This function uses
// `Neo.Storage.Delete` syscall. // `System.Storage.Delete` syscall.
func Delete(ctx Context, key interface{}) {} func Delete(ctx Context, key interface{}) {}
// Find returns an iterator.Iterator over key-value pairs in the given Context // 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 // 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 // possible key types and iterator package documentation on how to use the
// returned value. This function uses `Neo.Storage.Find` syscall. // returned value. This function uses `System.Storage.Find` syscall.
func Find(ctx Context, key interface{}) iterator.Iterator { return iterator.Iterator{} } func Find(ctx Context, key interface{}) iterator.Iterator { return iterator.Iterator{} }

View file

@ -1,14 +0,0 @@
/*
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
}

View file

@ -49,18 +49,18 @@ type rpcTestCase struct {
check func(t *testing.T, e *executor, result interface{}) check func(t *testing.T, e *executor, result interface{})
} }
const testContractHash = "1b4357bff5a01bdf2a6581247cf9ed1e24629176" const testContractHash = "279c86355b30d452386c1717e2ffa01c9dac31f3"
var rpcTestCases = map[string][]rpcTestCase{ var rpcTestCases = map[string][]rpcTestCase{
"getapplicationlog": { "getapplicationlog": {
{ {
name: "positive", name: "positive",
params: `["5878052c7e9843786d64a9aeab16e74fabffd5abad9a0404aaf4f4bf2b6213e9"]`, params: `["328190e78f1b5b8dcf86e71ec1894d6144f4e4cdb25abc20ea02b618851941dd"]`,
result: func(e *executor) interface{} { return &result.ApplicationLog{} }, result: func(e *executor) interface{} { return &result.ApplicationLog{} },
check: func(t *testing.T, e *executor, acc interface{}) { check: func(t *testing.T, e *executor, acc interface{}) {
res, ok := acc.(*result.ApplicationLog) res, ok := acc.(*result.ApplicationLog)
require.True(t, ok) require.True(t, ok)
expectedTxHash, err := util.Uint256DecodeStringLE("5878052c7e9843786d64a9aeab16e74fabffd5abad9a0404aaf4f4bf2b6213e9") expectedTxHash, err := util.Uint256DecodeStringLE("328190e78f1b5b8dcf86e71ec1894d6144f4e4cdb25abc20ea02b618851941dd")
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, expectedTxHash, res.TxHash) assert.Equal(t, expectedTxHash, res.TxHash)
assert.Equal(t, 1, len(res.Executions)) assert.Equal(t, 1, len(res.Executions))
@ -484,7 +484,7 @@ var rpcTestCases = map[string][]rpcTestCase{
"gettransactionheight": { "gettransactionheight": {
{ {
name: "positive", name: "positive",
params: `["5878052c7e9843786d64a9aeab16e74fabffd5abad9a0404aaf4f4bf2b6213e9"]`, params: `["328190e78f1b5b8dcf86e71ec1894d6144f4e4cdb25abc20ea02b618851941dd"]`,
result: func(e *executor) interface{} { result: func(e *executor) interface{} {
h := 0 h := 0
return &h return &h

Binary file not shown.

Binary file not shown.

View file

@ -189,9 +189,9 @@ func TestEmitString(t *testing.T) {
func TestEmitSyscall(t *testing.T) { func TestEmitSyscall(t *testing.T) {
syscalls := []string{ syscalls := []string{
"Neo.Runtime.Log", "System.Runtime.Log",
"Neo.Runtime.Notify", "System.Runtime.Notify",
"Neo.Runtime.Whatever", "System.Runtime.Whatever",
} }
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()

View file

@ -29,35 +29,31 @@ type interopIDFuncPrice struct {
type InteropGetterFunc func(uint32) *InteropFuncPrice type InteropGetterFunc func(uint32) *InteropFuncPrice
var defaultVMInterops = []interopIDFuncPrice{ var defaultVMInterops = []interopIDFuncPrice{
{emit.InteropNameToID([]byte("Neo.Runtime.Log")), {emit.InteropNameToID([]byte("System.Runtime.Log")),
InteropFuncPrice{runtimeLog, 1}}, InteropFuncPrice{runtimeLog, 1}},
{emit.InteropNameToID([]byte("Neo.Runtime.Notify")), {emit.InteropNameToID([]byte("System.Runtime.Notify")),
InteropFuncPrice{runtimeNotify, 1}}, InteropFuncPrice{runtimeNotify, 1}},
{emit.InteropNameToID([]byte("Neo.Runtime.Serialize")),
InteropFuncPrice{RuntimeSerialize, 1}},
{emit.InteropNameToID([]byte("System.Runtime.Serialize")), {emit.InteropNameToID([]byte("System.Runtime.Serialize")),
InteropFuncPrice{RuntimeSerialize, 1}}, InteropFuncPrice{RuntimeSerialize, 1}},
{emit.InteropNameToID([]byte("Neo.Runtime.Deserialize")),
InteropFuncPrice{RuntimeDeserialize, 1}},
{emit.InteropNameToID([]byte("System.Runtime.Deserialize")), {emit.InteropNameToID([]byte("System.Runtime.Deserialize")),
InteropFuncPrice{RuntimeDeserialize, 1}}, InteropFuncPrice{RuntimeDeserialize, 1}},
{emit.InteropNameToID([]byte("Neo.Enumerator.Create")), {emit.InteropNameToID([]byte("System.Enumerator.Create")),
InteropFuncPrice{EnumeratorCreate, 1}}, InteropFuncPrice{EnumeratorCreate, 1}},
{emit.InteropNameToID([]byte("Neo.Enumerator.Next")), {emit.InteropNameToID([]byte("System.Enumerator.Next")),
InteropFuncPrice{EnumeratorNext, 1}}, InteropFuncPrice{EnumeratorNext, 1}},
{emit.InteropNameToID([]byte("Neo.Enumerator.Concat")), {emit.InteropNameToID([]byte("System.Enumerator.Concat")),
InteropFuncPrice{EnumeratorConcat, 1}}, InteropFuncPrice{EnumeratorConcat, 1}},
{emit.InteropNameToID([]byte("Neo.Enumerator.Value")), {emit.InteropNameToID([]byte("System.Enumerator.Value")),
InteropFuncPrice{EnumeratorValue, 1}}, InteropFuncPrice{EnumeratorValue, 1}},
{emit.InteropNameToID([]byte("Neo.Iterator.Create")), {emit.InteropNameToID([]byte("System.Iterator.Create")),
InteropFuncPrice{IteratorCreate, 1}}, InteropFuncPrice{IteratorCreate, 1}},
{emit.InteropNameToID([]byte("Neo.Iterator.Concat")), {emit.InteropNameToID([]byte("System.Iterator.Concat")),
InteropFuncPrice{IteratorConcat, 1}}, InteropFuncPrice{IteratorConcat, 1}},
{emit.InteropNameToID([]byte("Neo.Iterator.Key")), {emit.InteropNameToID([]byte("System.Iterator.Key")),
InteropFuncPrice{IteratorKey, 1}}, InteropFuncPrice{IteratorKey, 1}},
{emit.InteropNameToID([]byte("Neo.Iterator.Keys")), {emit.InteropNameToID([]byte("System.Iterator.Keys")),
InteropFuncPrice{IteratorKeys, 1}}, InteropFuncPrice{IteratorKeys, 1}},
{emit.InteropNameToID([]byte("Neo.Iterator.Values")), {emit.InteropNameToID([]byte("System.Iterator.Values")),
InteropFuncPrice{IteratorValues, 1}}, InteropFuncPrice{IteratorValues, 1}},
} }
@ -71,21 +67,21 @@ func getDefaultVMInterop(id uint32) *InteropFuncPrice {
return nil return nil
} }
// runtimeLog handles the syscall "Neo.Runtime.Log" for printing and logging stuff. // runtimeLog handles the syscall "System.Runtime.Log" for printing and logging stuff.
func runtimeLog(vm *VM) error { func runtimeLog(vm *VM) error {
item := vm.Estack().Pop() item := vm.Estack().Pop()
fmt.Printf("NEO-GO-VM (log) > %s\n", item.Value()) fmt.Printf("NEO-GO-VM (log) > %s\n", item.Value())
return nil return nil
} }
// runtimeNotify handles the syscall "Neo.Runtime.Notify" for printing and logging stuff. // runtimeNotify handles the syscall "System.Runtime.Notify" for printing and logging stuff.
func runtimeNotify(vm *VM) error { func runtimeNotify(vm *VM) error {
item := vm.Estack().Pop() item := vm.Estack().Pop()
fmt.Printf("NEO-GO-VM (notify) > %s\n", item.Value()) fmt.Printf("NEO-GO-VM (notify) > %s\n", item.Value())
return nil return nil
} }
// RuntimeSerialize handles syscalls System.Runtime.Serialize and Neo.Runtime.Serialize. // RuntimeSerialize handles syscalls System.Runtime.Serialize and System.Runtime.Serialize.
func RuntimeSerialize(vm *VM) error { func RuntimeSerialize(vm *VM) error {
item := vm.Estack().Pop() item := vm.Estack().Pop()
data, err := stackitem.SerializeItem(item.value) data, err := stackitem.SerializeItem(item.value)
@ -100,7 +96,7 @@ func RuntimeSerialize(vm *VM) error {
return nil return nil
} }
// RuntimeDeserialize handles syscalls System.Runtime.Deserialize and Neo.Runtime.Deserialize. // RuntimeDeserialize handles syscalls System.Runtime.Deserialize and System.Runtime.Deserialize.
func RuntimeDeserialize(vm *VM) error { func RuntimeDeserialize(vm *VM) error {
data := vm.Estack().Pop().Bytes() data := vm.Estack().Pop().Bytes()
@ -121,7 +117,7 @@ func init() {
}) })
} }
// EnumeratorCreate handles syscall Neo.Enumerator.Create. // EnumeratorCreate handles syscall System.Enumerator.Create.
func EnumeratorCreate(v *VM) error { func EnumeratorCreate(v *VM) error {
data := v.Estack().Pop().Array() data := v.Estack().Pop().Array()
v.Estack().Push(&Element{ v.Estack().Push(&Element{
@ -134,7 +130,7 @@ func EnumeratorCreate(v *VM) error {
return nil return nil
} }
// EnumeratorNext handles syscall Neo.Enumerator.Next. // EnumeratorNext handles syscall System.Enumerator.Next.
func EnumeratorNext(v *VM) error { func EnumeratorNext(v *VM) error {
iop := v.Estack().Pop().Interop() iop := v.Estack().Pop().Interop()
arr := iop.Value().(enumerator) arr := iop.Value().(enumerator)
@ -143,7 +139,7 @@ func EnumeratorNext(v *VM) error {
return nil return nil
} }
// EnumeratorValue handles syscall Neo.Enumerator.Value. // EnumeratorValue handles syscall System.Enumerator.Value.
func EnumeratorValue(v *VM) error { func EnumeratorValue(v *VM) error {
iop := v.Estack().Pop().Interop() iop := v.Estack().Pop().Interop()
arr := iop.Value().(enumerator) arr := iop.Value().(enumerator)
@ -152,7 +148,7 @@ func EnumeratorValue(v *VM) error {
return nil return nil
} }
// EnumeratorConcat handles syscall Neo.Enumerator.Concat. // EnumeratorConcat handles syscall System.Enumerator.Concat.
func EnumeratorConcat(v *VM) error { func EnumeratorConcat(v *VM) error {
iop1 := v.Estack().Pop().Interop() iop1 := v.Estack().Pop().Interop()
arr1 := iop1.Value().(enumerator) arr1 := iop1.Value().(enumerator)
@ -169,7 +165,7 @@ func EnumeratorConcat(v *VM) error {
return nil return nil
} }
// IteratorCreate handles syscall Neo.Iterator.Create. // IteratorCreate handles syscall System.Iterator.Create.
func IteratorCreate(v *VM) error { func IteratorCreate(v *VM) error {
data := v.Estack().Pop() data := v.Estack().Pop()
var item stackitem.Item var item stackitem.Item
@ -197,7 +193,7 @@ func NewMapIterator(m *stackitem.Map) *stackitem.Interop {
}) })
} }
// IteratorConcat handles syscall Neo.Iterator.Concat. // IteratorConcat handles syscall System.Iterator.Concat.
func IteratorConcat(v *VM) error { func IteratorConcat(v *VM) error {
iop1 := v.Estack().Pop().Interop() iop1 := v.Estack().Pop().Interop()
iter1 := iop1.Value().(iterator) iter1 := iop1.Value().(iterator)
@ -214,7 +210,7 @@ func IteratorConcat(v *VM) error {
return nil return nil
} }
// IteratorKey handles syscall Neo.Iterator.Key. // IteratorKey handles syscall System.Iterator.Key.
func IteratorKey(v *VM) error { func IteratorKey(v *VM) error {
iop := v.estack.Pop().Interop() iop := v.estack.Pop().Interop()
iter := iop.Value().(iterator) iter := iop.Value().(iterator)
@ -223,7 +219,7 @@ func IteratorKey(v *VM) error {
return nil return nil
} }
// IteratorKeys handles syscall Neo.Iterator.Keys. // IteratorKeys handles syscall System.Iterator.Keys.
func IteratorKeys(v *VM) error { func IteratorKeys(v *VM) error {
iop := v.estack.Pop().Interop() iop := v.estack.Pop().Interop()
iter := iop.Value().(iterator) iter := iop.Value().(iterator)
@ -234,7 +230,7 @@ func IteratorKeys(v *VM) error {
return nil return nil
} }
// IteratorValues handles syscall Neo.Iterator.Values. // IteratorValues handles syscall System.Iterator.Values.
func IteratorValues(v *VM) error { func IteratorValues(v *VM) error {
iop := v.estack.Pop().Interop() iop := v.estack.Pop().Interop()
iter := iop.Value().(iterator) iter := iop.Value().(iterator)

View file

@ -488,16 +488,16 @@ func getEnumeratorProg(n int, isIter bool) (prog []byte) {
prog = []byte{byte(opcode.INITSSLOT), 1, byte(opcode.STSFLD0)} prog = []byte{byte(opcode.INITSSLOT), 1, byte(opcode.STSFLD0)}
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
prog = append(prog, byte(opcode.LDSFLD0)) prog = append(prog, byte(opcode.LDSFLD0))
prog = append(prog, getSyscallProg("Neo.Enumerator.Next")...) prog = append(prog, getSyscallProg("System.Enumerator.Next")...)
prog = append(prog, byte(opcode.LDSFLD0)) prog = append(prog, byte(opcode.LDSFLD0))
prog = append(prog, getSyscallProg("Neo.Enumerator.Value")...) prog = append(prog, getSyscallProg("System.Enumerator.Value")...)
if isIter { if isIter {
prog = append(prog, byte(opcode.LDSFLD0)) prog = append(prog, byte(opcode.LDSFLD0))
prog = append(prog, getSyscallProg("Neo.Iterator.Key")...) prog = append(prog, getSyscallProg("System.Iterator.Key")...)
} }
} }
prog = append(prog, byte(opcode.LDSFLD0)) prog = append(prog, byte(opcode.LDSFLD0))
prog = append(prog, getSyscallProg("Neo.Enumerator.Next")...) prog = append(prog, getSyscallProg("System.Enumerator.Next")...)
return return
} }
@ -512,7 +512,7 @@ func checkEnumeratorStack(t *testing.T, vm *VM, arr []stackitem.Item) {
func testIterableCreate(t *testing.T, typ string) { func testIterableCreate(t *testing.T, typ string) {
isIter := typ == "Iterator" isIter := typ == "Iterator"
prog := getSyscallProg("Neo." + typ + ".Create") prog := getSyscallProg("System." + typ + ".Create")
prog = append(prog, getEnumeratorProg(2, isIter)...) prog = append(prog, getEnumeratorProg(2, isIter)...)
vm := load(prog) vm := load(prog)
@ -546,10 +546,10 @@ func TestIteratorCreate(t *testing.T) {
func testIterableConcat(t *testing.T, typ string) { func testIterableConcat(t *testing.T, typ string) {
isIter := typ == "Iterator" isIter := typ == "Iterator"
prog := getSyscallProg("Neo." + typ + ".Create") prog := getSyscallProg("System." + typ + ".Create")
prog = append(prog, byte(opcode.SWAP)) prog = append(prog, byte(opcode.SWAP))
prog = append(prog, getSyscallProg("Neo."+typ+".Create")...) prog = append(prog, getSyscallProg("System."+typ+".Create")...)
prog = append(prog, getSyscallProg("Neo."+typ+".Concat")...) prog = append(prog, getSyscallProg("System."+typ+".Concat")...)
prog = append(prog, getEnumeratorProg(3, isIter)...) prog = append(prog, getEnumeratorProg(3, isIter)...)
vm := load(prog) vm := load(prog)
@ -589,8 +589,8 @@ func TestIteratorConcat(t *testing.T) {
} }
func TestIteratorKeys(t *testing.T) { func TestIteratorKeys(t *testing.T) {
prog := getSyscallProg("Neo.Iterator.Create") prog := getSyscallProg("System.Iterator.Create")
prog = append(prog, getSyscallProg("Neo.Iterator.Keys")...) prog = append(prog, getSyscallProg("System.Iterator.Keys")...)
prog = append(prog, getEnumeratorProg(2, false)...) prog = append(prog, getEnumeratorProg(2, false)...)
v := load(prog) v := load(prog)
@ -609,8 +609,8 @@ func TestIteratorKeys(t *testing.T) {
} }
func TestIteratorValues(t *testing.T) { func TestIteratorValues(t *testing.T) {
prog := getSyscallProg("Neo.Iterator.Create") prog := getSyscallProg("System.Iterator.Create")
prog = append(prog, getSyscallProg("Neo.Iterator.Values")...) prog = append(prog, getSyscallProg("System.Iterator.Values")...)
prog = append(prog, getEnumeratorProg(2, false)...) prog = append(prog, getEnumeratorProg(2, false)...)
v := load(prog) v := load(prog)
@ -643,8 +643,8 @@ func getSyscallProg(name string) (prog []byte) {
} }
func getSerializeProg() (prog []byte) { func getSerializeProg() (prog []byte) {
prog = append(prog, getSyscallProg("Neo.Runtime.Serialize")...) prog = append(prog, getSyscallProg("System.Runtime.Serialize")...)
prog = append(prog, getSyscallProg("Neo.Runtime.Deserialize")...) prog = append(prog, getSyscallProg("System.Runtime.Deserialize")...)
prog = append(prog, byte(opcode.RET)) prog = append(prog, byte(opcode.RET))
return return
@ -749,7 +749,7 @@ func TestSerializeStruct(t *testing.T) {
} }
func TestDeserializeUnknown(t *testing.T) { func TestDeserializeUnknown(t *testing.T) {
prog := append(getSyscallProg("Neo.Runtime.Deserialize"), byte(opcode.RET)) prog := append(getSyscallProg("System.Runtime.Deserialize"), byte(opcode.RET))
data, err := stackitem.SerializeItem(stackitem.NewBigInteger(big.NewInt(123))) data, err := stackitem.SerializeItem(stackitem.NewBigInteger(big.NewInt(123)))
require.NoError(t, err) require.NoError(t, err)
@ -785,7 +785,7 @@ func TestSerializeMapCompat(t *testing.T) {
emit.Bytes(buf.BinWriter, []byte("key")) emit.Bytes(buf.BinWriter, []byte("key"))
emit.Bytes(buf.BinWriter, []byte("value")) emit.Bytes(buf.BinWriter, []byte("value"))
emit.Opcode(buf.BinWriter, opcode.SETITEM) emit.Opcode(buf.BinWriter, opcode.SETITEM)
emit.Syscall(buf.BinWriter, "Neo.Runtime.Serialize") emit.Syscall(buf.BinWriter, "System.Runtime.Serialize")
require.NoError(t, buf.Err) require.NoError(t, buf.Err)
vm := load(buf.Bytes()) vm := load(buf.Bytes())