Merge pull request #1231 from nspcc-dev/fix/printops

vm: pretty-print remaining opcodes
This commit is contained in:
Roman Khimov 2020-08-14 14:43:29 +03:00 committed by GitHub
commit 40bcd4c0bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 400 additions and 199 deletions

View file

@ -12,6 +12,7 @@ import (
"sort" "sort"
"strings" "strings"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm"
@ -1313,7 +1314,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, "System.Runtime.Log") emit.Syscall(c.prog.BinWriter, interopnames.SystemRuntimeLog)
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

@ -6,8 +6,8 @@ import (
"math/big" "math/big"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -56,7 +56,7 @@ func getPanicSource(need bool, message string) string {
} }
func getLogHandler(logs *[]string) vm.SyscallHandler { func getLogHandler(logs *[]string) vm.SyscallHandler {
logID := emit.InteropNameToID([]byte("System.Runtime.Log")) logID := interopnames.ToID([]byte(interopnames.SystemRuntimeLog))
return func(v *vm.VM, id uint32) error { return func(v *vm.VM, id uint32) error {
if id != logID { if id != logID {
return errors.New("syscall not found") return errors.New("syscall not found")

View file

@ -1,5 +1,7 @@
package compiler package compiler
import "github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
// Syscall represents NEO or System syscall API with flag for proper AVM generation // Syscall represents NEO or System syscall API with flag for proper AVM generation
type Syscall struct { type Syscall struct {
API string API string
@ -9,80 +11,80 @@ type Syscall struct {
// All lists are sorted, keep 'em this way, please. // All lists are sorted, keep 'em this way, please.
var syscalls = map[string]map[string]Syscall{ var syscalls = map[string]map[string]Syscall{
"binary": { "binary": {
"Base64Decode": {"System.Binary.Base64Decode", false}, "Base64Decode": {interopnames.SystemBinaryBase64Decode, false},
"Base64Encode": {"System.Binary.Base64Encode", false}, "Base64Encode": {interopnames.SystemBinaryBase64Encode, false},
"Deserialize": {"System.Binary.Deserialize", false}, "Deserialize": {interopnames.SystemBinaryDeserialize, false},
"Serialize": {"System.Binary.Serialize", false}, "Serialize": {interopnames.SystemBinarySerialize, false},
}, },
"blockchain": { "blockchain": {
"GetBlock": {"System.Blockchain.GetBlock", true}, "GetBlock": {interopnames.SystemBlockchainGetBlock, true},
"GetContract": {"System.Blockchain.GetContract", true}, "GetContract": {interopnames.SystemBlockchainGetContract, true},
"GetHeight": {"System.Blockchain.GetHeight", false}, "GetHeight": {interopnames.SystemBlockchainGetHeight, false},
"GetTransaction": {"System.Blockchain.GetTransaction", true}, "GetTransaction": {interopnames.SystemBlockchainGetTransaction, true},
"GetTransactionFromBlock": {"System.Blockchain.GetTransactionFromBlock", false}, "GetTransactionFromBlock": {interopnames.SystemBlockchainGetTransactionFromBlock, false},
"GetTransactionHeight": {"System.Blockchain.GetTransactionHeight", false}, "GetTransactionHeight": {interopnames.SystemBlockchainGetTransactionHeight, false},
}, },
"contract": { "contract": {
"Create": {"System.Contract.Create", true}, "Create": {interopnames.SystemContractCreate, true},
"CreateStandardAccount": {"System.Contract.CreateStandardAccount", false}, "CreateStandardAccount": {interopnames.SystemContractCreateStandardAccount, false},
"Destroy": {"System.Contract.Destroy", false}, "Destroy": {interopnames.SystemContractDestroy, false},
"IsStandard": {"System.Contract.IsStandard", false}, "IsStandard": {interopnames.SystemContractIsStandard, false},
"GetCallFlags": {"System.Contract.GetCallFlags", false}, "GetCallFlags": {interopnames.SystemContractGetCallFlags, false},
"Update": {"System.Contract.Update", false}, "Update": {interopnames.SystemContractUpdate, false},
}, },
"crypto": { "crypto": {
"ECDsaSecp256k1Verify": {"Neo.Crypto.VerifyWithECDsaSecp256k1", false}, "ECDsaSecp256k1Verify": {interopnames.NeoCryptoVerifyWithECDsaSecp256k1, false},
"ECDSASecp256k1CheckMultisig": {"Neo.Crypto.CheckMultisigWithECDsaSecp256k1", false}, "ECDSASecp256k1CheckMultisig": {interopnames.NeoCryptoCheckMultisigWithECDsaSecp256k1, false},
"ECDsaSecp256r1Verify": {"Neo.Crypto.VerifyWithECDsaSecp256r1", false}, "ECDsaSecp256r1Verify": {interopnames.NeoCryptoVerifyWithECDsaSecp256r1, false},
"ECDSASecp256r1CheckMultisig": {"Neo.Crypto.CheckMultisigWithECDsaSecp256r1", false}, "ECDSASecp256r1CheckMultisig": {interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1, false},
"RIPEMD160": {"Neo.Crypto.RIPEMD160", false}, "RIPEMD160": {interopnames.NeoCryptoRIPEMD160, false},
"SHA256": {"Neo.Crypto.SHA256", false}, "SHA256": {interopnames.NeoCryptoSHA256, false},
}, },
"enumerator": { "enumerator": {
"Concat": {"System.Enumerator.Concat", false}, "Concat": {interopnames.SystemEnumeratorConcat, false},
"Create": {"System.Enumerator.Create", false}, "Create": {interopnames.SystemEnumeratorCreate, false},
"Next": {"System.Enumerator.Next", false}, "Next": {interopnames.SystemEnumeratorNext, false},
"Value": {"System.Enumerator.Value", false}, "Value": {interopnames.SystemEnumeratorValue, false},
}, },
"engine": { "engine": {
"AppCall": {"System.Contract.Call", false}, "AppCall": {interopnames.SystemContractCall, false},
}, },
"iterator": { "iterator": {
"Concat": {"System.Iterator.Concat", false}, "Concat": {interopnames.SystemIteratorConcat, false},
"Create": {"System.Iterator.Create", false}, "Create": {interopnames.SystemIteratorCreate, false},
"Key": {"System.Iterator.Key", false}, "Key": {interopnames.SystemIteratorKey, false},
"Keys": {"System.Iterator.Keys", false}, "Keys": {interopnames.SystemIteratorKeys, false},
"Next": {"System.Enumerator.Next", false}, "Next": {interopnames.SystemEnumeratorNext, false},
"Value": {"System.Enumerator.Value", false}, "Value": {interopnames.SystemEnumeratorValue, false},
"Values": {"System.Iterator.Values", false}, "Values": {interopnames.SystemIteratorValues, false},
}, },
"json": { "json": {
"Deserialize": {"System.Json.Deserialize", false}, "Deserialize": {interopnames.SystemJSONDeserialize, false},
"Serialize": {"System.Json.Serialize", false}, "Serialize": {interopnames.SystemJSONSerialize, false},
}, },
"runtime": { "runtime": {
"GasLeft": {"System.Runtime.GasLeft", false}, "GasLeft": {interopnames.SystemRuntimeGasLeft, false},
"GetInvocationCounter": {"System.Runtime.GetInvocationCounter", false}, "GetInvocationCounter": {interopnames.SystemRuntimeGetInvocationCounter, false},
"GetCallingScriptHash": {"System.Runtime.GetCallingScriptHash", false}, "GetCallingScriptHash": {interopnames.SystemRuntimeGetCallingScriptHash, false},
"GetEntryScriptHash": {"System.Runtime.GetEntryScriptHash", false}, "GetEntryScriptHash": {interopnames.SystemRuntimeGetEntryScriptHash, false},
"GetExecutingScriptHash": {"System.Runtime.GetExecutingScriptHash", false}, "GetExecutingScriptHash": {interopnames.SystemRuntimeGetExecutingScriptHash, false},
"GetNotifications": {"System.Runtime.GetNotifications", false}, "GetNotifications": {interopnames.SystemRuntimeGetNotifications, false},
"GetScriptContainer": {"System.Runtime.GetScriptContainer", true}, "GetScriptContainer": {interopnames.SystemRuntimeGetScriptContainer, true},
"GetTime": {"System.Runtime.GetTime", false}, "GetTime": {interopnames.SystemRuntimeGetTime, false},
"GetTrigger": {"System.Runtime.GetTrigger", false}, "GetTrigger": {interopnames.SystemRuntimeGetTrigger, false},
"CheckWitness": {"System.Runtime.CheckWitness", false}, "CheckWitness": {interopnames.SystemRuntimeCheckWitness, false},
"Log": {"System.Runtime.Log", false}, "Log": {interopnames.SystemRuntimeLog, false},
"Notify": {"System.Runtime.Notify", false}, "Notify": {interopnames.SystemRuntimeNotify, false},
"Platform": {"System.Runtime.Platform", false}, "Platform": {interopnames.SystemRuntimePlatform, false},
}, },
"storage": { "storage": {
"ConvertContextToReadOnly": {"System.Storage.AsReadOnly", false}, "ConvertContextToReadOnly": {interopnames.SystemStorageAsReadOnly, false},
"Delete": {"System.Storage.Delete", false}, "Delete": {interopnames.SystemStorageDelete, false},
"Find": {"System.Storage.Find", false}, "Find": {interopnames.SystemStorageFind, false},
"Get": {"System.Storage.Get", false}, "Get": {interopnames.SystemStorageGet, false},
"GetContext": {"System.Storage.GetContext", false}, "GetContext": {interopnames.SystemStorageGetContext, false},
"GetReadOnlyContext": {"System.Storage.GetReadOnlyContext", false}, "GetReadOnlyContext": {interopnames.SystemStorageGetReadOnlyContext, false},
"Put": {"System.Storage.Put", false}, "Put": {interopnames.SystemStoragePut, false},
"PutEx": {"System.Storage.PutEx", false}, "PutEx": {interopnames.SystemStoragePutEx, false},
}, },
} }

View file

@ -4,9 +4,9 @@ import (
"fmt" "fmt"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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/vm" "github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -19,7 +19,7 @@ func TestVerifyGood(t *testing.T) {
src := getVerifyProg(pub, sig, msg) src := getVerifyProg(pub, sig, msg)
v, p := vmAndCompileInterop(t, src) v, p := vmAndCompileInterop(t, src)
p.interops[emit.InteropNameToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256r1"))] = func(v *vm.VM) error { p.interops[interopnames.ToID([]byte(interopnames.NeoCryptoVerifyWithECDsaSecp256r1))] = func(v *vm.VM) error {
assert.Equal(t, msg, v.Estack().Pop().Bytes()) assert.Equal(t, msg, v.Estack().Pop().Bytes())
assert.Equal(t, pub, v.Estack().Pop().Bytes()) assert.Equal(t, pub, v.Estack().Pop().Bytes())
assert.Equal(t, sig, v.Estack().Pop().Bytes()) assert.Equal(t, sig, v.Estack().Pop().Bytes())

View file

@ -7,11 +7,11 @@ import (
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/compiler" "github.com/nspcc-dev/neo-go/pkg/compiler"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
"github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -109,10 +109,10 @@ func newStoragePlugin() *storagePlugin {
mem: make(map[string][]byte), mem: make(map[string][]byte),
interops: make(map[uint32]func(v *vm.VM) error), interops: make(map[uint32]func(v *vm.VM) error),
} }
s.interops[emit.InteropNameToID([]byte("System.Storage.Get"))] = s.Get s.interops[interopnames.ToID([]byte(interopnames.SystemStorageGet))] = s.Get
s.interops[emit.InteropNameToID([]byte("System.Storage.Put"))] = s.Put s.interops[interopnames.ToID([]byte(interopnames.SystemStoragePut))] = s.Put
s.interops[emit.InteropNameToID([]byte("System.Storage.GetContext"))] = s.GetContext s.interops[interopnames.ToID([]byte(interopnames.SystemStorageGetContext))] = s.GetContext
s.interops[emit.InteropNameToID([]byte("System.Runtime.Notify"))] = s.Notify s.interops[interopnames.ToID([]byte(interopnames.SystemRuntimeNotify))] = s.Notify
return s return s
} }

View file

@ -7,6 +7,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/config/netmode"
"github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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/storage" "github.com/nspcc-dev/neo-go/pkg/core/storage"
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/core/transaction"
@ -273,7 +274,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, "System.Runtime.Notify") emit.Syscall(script.BinWriter, interopnames.SystemRuntimeNotify)
require.NoError(t, script.Err) require.NoError(t, script.Err)
txGood1 := transaction.New(netmode.UnitTestNet, script.Bytes(), 0) txGood1 := transaction.New(netmode.UnitTestNet, script.Bytes(), 0)
txGood1.Signers = []transaction.Signer{{Account: neoOwner}} txGood1.Signers = []transaction.Signer{{Account: neoOwner}}
@ -284,7 +285,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, "System.Runtime.Notify") emit.Syscall(script.BinWriter, interopnames.SystemRuntimeNotify)
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(netmode.UnitTestNet, script.Bytes(), 0) txBad := transaction.New(netmode.UnitTestNet, script.Bytes(), 0)
@ -295,7 +296,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, "System.Runtime.Notify") emit.Syscall(script.BinWriter, interopnames.SystemRuntimeNotify)
require.NoError(t, script.Err) require.NoError(t, script.Err)
txGood2 := transaction.New(netmode.UnitTestNet, script.Bytes(), 0) txGood2 := transaction.New(netmode.UnitTestNet, script.Bytes(), 0)
txGood2.Signers = []transaction.Signer{{Account: neoOwner}} txGood2.Signers = []transaction.Signer{{Account: neoOwner}}

View file

@ -14,6 +14,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/compiler" "github.com/nspcc-dev/neo-go/pkg/compiler"
"github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/core/native" "github.com/nspcc-dev/neo-go/pkg/core/native"
"github.com/nspcc-dev/neo-go/pkg/core/storage" "github.com/nspcc-dev/neo-go/pkg/core/storage"
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/core/transaction"
@ -239,7 +240,7 @@ func TestCreateBasicChain(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
emit.Bytes(script.BinWriter, bs) emit.Bytes(script.BinWriter, bs)
emit.Bytes(script.BinWriter, avm) emit.Bytes(script.BinWriter, avm)
emit.Syscall(script.BinWriter, "System.Contract.Create") emit.Syscall(script.BinWriter, interopnames.SystemContractCreate)
txScript := script.Bytes() txScript := script.Bytes()
txDeploy := transaction.New(testchain.Network(), txScript, 100*native.GASFactor) txDeploy := transaction.New(testchain.Network(), txScript, 100*native.GASFactor)

View file

@ -4,8 +4,8 @@ import (
"errors" "errors"
"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/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
) )
@ -27,7 +27,7 @@ func Invoke(ic *interop.Context) error {
cb.LoadContext(ic.VM, args) cb.LoadContext(ic.VM, args)
switch t := cb.(type) { switch t := cb.(type) {
case *MethodCallback: case *MethodCallback:
id := emit.InteropNameToID([]byte("System.Contract.Call")) id := interopnames.ToID([]byte(interopnames.SystemContractCall))
return ic.SyscallHandler(ic.VM, id) return ic.SyscallHandler(ic.VM, id)
case *SyscallCallback: case *SyscallCallback:
return ic.SyscallHandler(ic.VM, t.desc.ID) return ic.SyscallHandler(ic.VM, t.desc.ID)

View file

@ -8,6 +8,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer" "github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
"github.com/nspcc-dev/neo-go/pkg/core/dao" "github.com/nspcc-dev/neo-go/pkg/core/dao"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/crypto" "github.com/nspcc-dev/neo-go/pkg/crypto"
@ -110,7 +111,7 @@ func NewContractMD(name string) *ContractMD {
w := io.NewBufBinWriter() w := io.NewBufBinWriter()
emit.String(w.BinWriter, c.Name) emit.String(w.BinWriter, c.Name)
emit.Syscall(w.BinWriter, "Neo.Native.Call") emit.Syscall(w.BinWriter, interopnames.NeoNativeCall)
c.Script = w.Bytes() c.Script = w.Bytes()
c.Hash = hash.Hash160(c.Script) c.Hash = hash.Hash160(c.Script)

View file

@ -5,6 +5,7 @@ import (
"testing" "testing"
"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/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"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/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/emit"
@ -17,7 +18,7 @@ func TestSHA256(t *testing.T) {
res := "47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254" res := "47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254"
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
emit.Bytes(buf.BinWriter, []byte{1, 0}) emit.Bytes(buf.BinWriter, []byte{1, 0})
emit.Syscall(buf.BinWriter, "Neo.Crypto.SHA256") emit.Syscall(buf.BinWriter, interopnames.NeoCryptoSHA256)
prog := buf.Bytes() prog := buf.Bytes()
ic := &interop.Context{Trigger: trigger.Verification} ic := &interop.Context{Trigger: trigger.Verification}
Register(ic) Register(ic)
@ -33,7 +34,7 @@ func TestRIPEMD160(t *testing.T) {
res := "213492c0c6fc5d61497cf17249dd31cd9964b8a3" res := "213492c0c6fc5d61497cf17249dd31cd9964b8a3"
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
emit.Bytes(buf.BinWriter, []byte{1, 0}) emit.Bytes(buf.BinWriter, []byte{1, 0})
emit.Syscall(buf.BinWriter, "Neo.Crypto.RIPEMD160") emit.Syscall(buf.BinWriter, interopnames.NeoCryptoRIPEMD160)
prog := buf.Bytes() prog := buf.Bytes()
ic := &interop.Context{Trigger: trigger.Verification} ic := &interop.Context{Trigger: trigger.Verification}
Register(ic) Register(ic)

View file

@ -2,16 +2,16 @@ package crypto
import ( 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/vm/emit" "github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
) )
var ( var (
ecdsaSecp256r1VerifyID = emit.InteropNameToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256r1")) ecdsaSecp256r1VerifyID = interopnames.ToID([]byte(interopnames.NeoCryptoVerifyWithECDsaSecp256r1))
ecdsaSecp256k1VerifyID = emit.InteropNameToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256k1")) ecdsaSecp256k1VerifyID = interopnames.ToID([]byte(interopnames.NeoCryptoVerifyWithECDsaSecp256k1))
ecdsaSecp256r1CheckMultisigID = emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1")) ecdsaSecp256r1CheckMultisigID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1))
ecdsaSecp256k1CheckMultisigID = emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256k1")) ecdsaSecp256k1CheckMultisigID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckMultisigWithECDsaSecp256k1))
sha256ID = emit.InteropNameToID([]byte("Neo.Crypto.SHA256")) sha256ID = interopnames.ToID([]byte(interopnames.NeoCryptoSHA256))
ripemd160ID = emit.InteropNameToID([]byte("Neo.Crypto.RIPEMD160")) ripemd160ID = interopnames.ToID([]byte(interopnames.NeoCryptoRIPEMD160))
) )
var cryptoInterops = []interop.Function{ var cryptoInterops = []interop.Function{

View file

@ -0,0 +1,25 @@
package interopnames
import (
"crypto/sha256"
"encoding/binary"
"errors"
)
var errNotFound = errors.New("interop not found")
// ToID returns an identificator of the method based on its name.
func ToID(name []byte) uint32 {
h := sha256.Sum256(name)
return binary.LittleEndian.Uint32(h[:4])
}
// FromID returns interop name from its id.
func FromID(id uint32) (string, error) {
for i := range names {
if id == ToID([]byte(names[i])) {
return names[i], nil
}
}
return "", errNotFound
}

View file

@ -0,0 +1,21 @@
package interopnames
import (
"errors"
"testing"
"github.com/stretchr/testify/require"
)
func TestFromID(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
id := ToID([]byte(names[0]))
name, err := FromID(id)
require.NoError(t, err)
require.Equal(t, names[0], name)
})
t.Run("Invalid", func(t *testing.T) {
_, err := FromID(0x42424242)
require.True(t, errors.Is(err, errNotFound))
})
}

View file

@ -0,0 +1,132 @@
package interopnames
// Names of all used interops.
const (
SystemBinaryBase64Decode = "System.Binary.Base64Decode"
SystemBinaryBase64Encode = "System.Binary.Base64Encode"
SystemBinaryDeserialize = "System.Binary.Deserialize"
SystemBinarySerialize = "System.Binary.Serialize"
SystemBlockchainGetBlock = "System.Blockchain.GetBlock"
SystemBlockchainGetContract = "System.Blockchain.GetContract"
SystemBlockchainGetHeight = "System.Blockchain.GetHeight"
SystemBlockchainGetTransaction = "System.Blockchain.GetTransaction"
SystemBlockchainGetTransactionFromBlock = "System.Blockchain.GetTransactionFromBlock"
SystemBlockchainGetTransactionHeight = "System.Blockchain.GetTransactionHeight"
SystemCallbackCreate = "System.Callback.Create"
SystemCallbackCreateFromMethod = "System.Callback.CreateFromMethod"
SystemCallbackCreateFromSyscall = "System.Callback.CreateFromSyscall"
SystemCallbackInvoke = "System.Callback.Invoke"
SystemContractCall = "System.Contract.Call"
SystemContractCallEx = "System.Contract.CallEx"
SystemContractCreate = "System.Contract.Create"
SystemContractCreateStandardAccount = "System.Contract.CreateStandardAccount"
SystemContractDestroy = "System.Contract.Destroy"
SystemContractIsStandard = "System.Contract.IsStandard"
SystemContractGetCallFlags = "System.Contract.GetCallFlags"
SystemContractUpdate = "System.Contract.Update"
SystemEnumeratorConcat = "System.Enumerator.Concat"
SystemEnumeratorCreate = "System.Enumerator.Create"
SystemEnumeratorNext = "System.Enumerator.Next"
SystemEnumeratorValue = "System.Enumerator.Value"
SystemIteratorConcat = "System.Iterator.Concat"
SystemIteratorCreate = "System.Iterator.Create"
SystemIteratorKey = "System.Iterator.Key"
SystemIteratorKeys = "System.Iterator.Keys"
SystemIteratorValues = "System.Iterator.Values"
SystemJSONDeserialize = "System.Json.Deserialize"
SystemJSONSerialize = "System.Json.Serialize"
SystemRuntimeCheckWitness = "System.Runtime.CheckWitness"
SystemRuntimeGasLeft = "System.Runtime.GasLeft"
SystemRuntimeGetCallingScriptHash = "System.Runtime.GetCallingScriptHash"
SystemRuntimeGetEntryScriptHash = "System.Runtime.GetEntryScriptHash"
SystemRuntimeGetExecutingScriptHash = "System.Runtime.GetExecutingScriptHash"
SystemRuntimeGetInvocationCounter = "System.Runtime.GetInvocationCounter"
SystemRuntimeGetNotifications = "System.Runtime.GetNotifications"
SystemRuntimeGetScriptContainer = "System.Runtime.GetScriptContainer"
SystemRuntimeGetTime = "System.Runtime.GetTime"
SystemRuntimeGetTrigger = "System.Runtime.GetTrigger"
SystemRuntimeLog = "System.Runtime.Log"
SystemRuntimeNotify = "System.Runtime.Notify"
SystemRuntimePlatform = "System.Runtime.Platform"
SystemStorageDelete = "System.Storage.Delete"
SystemStorageFind = "System.Storage.Find"
SystemStorageGet = "System.Storage.Get"
SystemStorageGetContext = "System.Storage.GetContext"
SystemStorageGetReadOnlyContext = "System.Storage.GetReadOnlyContext"
SystemStoragePut = "System.Storage.Put"
SystemStoragePutEx = "System.Storage.PutEx"
SystemStorageAsReadOnly = "System.Storage.AsReadOnly"
NeoCryptoVerifyWithECDsaSecp256r1 = "Neo.Crypto.VerifyWithECDsaSecp256r1"
NeoCryptoVerifyWithECDsaSecp256k1 = "Neo.Crypto.VerifyWithECDsaSecp256k1"
NeoCryptoCheckMultisigWithECDsaSecp256r1 = "Neo.Crypto.CheckMultisigWithECDsaSecp256r1"
NeoCryptoCheckMultisigWithECDsaSecp256k1 = "Neo.Crypto.CheckMultisigWithECDsaSecp256k1"
NeoCryptoSHA256 = "Neo.Crypto.SHA256"
NeoCryptoRIPEMD160 = "Neo.Crypto.RIPEMD160"
NeoNativeCall = "Neo.Native.Call"
NeoNativeDeploy = "Neo.Native.Deploy"
)
var names = []string{
SystemBinaryBase64Decode,
SystemBinaryBase64Encode,
SystemBinaryDeserialize,
SystemBinarySerialize,
SystemBlockchainGetBlock,
SystemBlockchainGetContract,
SystemBlockchainGetHeight,
SystemBlockchainGetTransaction,
SystemBlockchainGetTransactionFromBlock,
SystemBlockchainGetTransactionHeight,
SystemCallbackCreate,
SystemCallbackCreateFromMethod,
SystemCallbackCreateFromSyscall,
SystemCallbackInvoke,
SystemContractCall,
SystemContractCallEx,
SystemContractCreate,
SystemContractCreateStandardAccount,
SystemContractDestroy,
SystemContractIsStandard,
SystemContractGetCallFlags,
SystemContractUpdate,
SystemEnumeratorConcat,
SystemEnumeratorCreate,
SystemEnumeratorNext,
SystemEnumeratorValue,
SystemIteratorConcat,
SystemIteratorCreate,
SystemIteratorKey,
SystemIteratorKeys,
SystemIteratorValues,
SystemJSONDeserialize,
SystemJSONSerialize,
SystemRuntimeCheckWitness,
SystemRuntimeGasLeft,
SystemRuntimeGetCallingScriptHash,
SystemRuntimeGetEntryScriptHash,
SystemRuntimeGetExecutingScriptHash,
SystemRuntimeGetInvocationCounter,
SystemRuntimeGetNotifications,
SystemRuntimeGetScriptContainer,
SystemRuntimeGetTime,
SystemRuntimeGetTrigger,
SystemRuntimeLog,
SystemRuntimeNotify,
SystemRuntimePlatform,
SystemStorageDelete,
SystemStorageFind,
SystemStorageGet,
SystemStorageGetContext,
SystemStorageGetReadOnlyContext,
SystemStoragePut,
SystemStoragePutEx,
SystemStorageAsReadOnly,
NeoCryptoVerifyWithECDsaSecp256r1,
NeoCryptoVerifyWithECDsaSecp256k1,
NeoCryptoCheckMultisigWithECDsaSecp256r1,
NeoCryptoCheckMultisigWithECDsaSecp256k1,
NeoCryptoSHA256,
NeoCryptoRIPEMD160,
NeoNativeCall,
NeoNativeDeploy,
}

View file

@ -5,15 +5,15 @@ import (
"testing" "testing"
"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/vm/emit" "github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/vm/opcode"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
var ( var (
serializeID = emit.InteropNameToID([]byte("System.Json.Serialize")) serializeID = interopnames.ToID([]byte(interopnames.SystemJSONSerialize))
deserializeID = emit.InteropNameToID([]byte("System.Json.Deserialize")) deserializeID = interopnames.ToID([]byte(interopnames.SystemJSONDeserialize))
) )
var jsonInterops = []interop.Function{ var jsonInterops = []interop.Function{

View file

@ -12,13 +12,13 @@ import (
"github.com/nspcc-dev/neo-go/pkg/core/interop/callback" "github.com/nspcc-dev/neo-go/pkg/core/interop/callback"
"github.com/nspcc-dev/neo-go/pkg/core/interop/crypto" "github.com/nspcc-dev/neo-go/pkg/core/interop/crypto"
"github.com/nspcc-dev/neo-go/pkg/core/interop/enumerator" "github.com/nspcc-dev/neo-go/pkg/core/interop/enumerator"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/core/interop/iterator" "github.com/nspcc-dev/neo-go/pkg/core/interop/iterator"
"github.com/nspcc-dev/neo-go/pkg/core/interop/json" "github.com/nspcc-dev/neo-go/pkg/core/interop/json"
"github.com/nspcc-dev/neo-go/pkg/core/interop/runtime" "github.com/nspcc-dev/neo-go/pkg/core/interop/runtime"
"github.com/nspcc-dev/neo-go/pkg/core/native" "github.com/nspcc-dev/neo-go/pkg/core/native"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
) )
// SpawnVM returns a VM with script getter and interop functions set // SpawnVM returns a VM with script getter and interop functions set
@ -31,101 +31,101 @@ func SpawnVM(ic *interop.Context) *vm.VM {
// All lists are sorted, keep 'em this way, please. // All lists are sorted, keep 'em this way, please.
var systemInterops = []interop.Function{ var systemInterops = []interop.Function{
{Name: "System.Binary.Base64Decode", Func: runtimeDecode, Price: 100000, ParamCount: 1}, {Name: interopnames.SystemBinaryBase64Decode, Func: runtimeDecode, Price: 100000, ParamCount: 1},
{Name: "System.Binary.Base64Encode", Func: runtimeEncode, Price: 100000, ParamCount: 1}, {Name: interopnames.SystemBinaryBase64Encode, Func: runtimeEncode, Price: 100000, ParamCount: 1},
{Name: "System.Binary.Deserialize", Func: runtimeDeserialize, Price: 500000, ParamCount: 1}, {Name: interopnames.SystemBinaryDeserialize, Func: runtimeDeserialize, Price: 500000, ParamCount: 1},
{Name: "System.Binary.Serialize", Func: runtimeSerialize, Price: 100000, ParamCount: 1}, {Name: interopnames.SystemBinarySerialize, Func: runtimeSerialize, Price: 100000, ParamCount: 1},
{Name: "System.Blockchain.GetBlock", Func: bcGetBlock, Price: 2500000, {Name: interopnames.SystemBlockchainGetBlock, Func: bcGetBlock, Price: 2500000,
RequiredFlags: smartcontract.AllowStates, ParamCount: 1}, RequiredFlags: smartcontract.AllowStates, ParamCount: 1},
{Name: "System.Blockchain.GetContract", Func: bcGetContract, Price: 1000000, {Name: interopnames.SystemBlockchainGetContract, Func: bcGetContract, Price: 1000000,
RequiredFlags: smartcontract.AllowStates, ParamCount: 1}, RequiredFlags: smartcontract.AllowStates, ParamCount: 1},
{Name: "System.Blockchain.GetHeight", Func: bcGetHeight, Price: 400, {Name: interopnames.SystemBlockchainGetHeight, Func: bcGetHeight, Price: 400,
RequiredFlags: smartcontract.AllowStates}, RequiredFlags: smartcontract.AllowStates},
{Name: "System.Blockchain.GetTransaction", Func: bcGetTransaction, Price: 1000000, {Name: interopnames.SystemBlockchainGetTransaction, Func: bcGetTransaction, Price: 1000000,
RequiredFlags: smartcontract.AllowStates, ParamCount: 1}, RequiredFlags: smartcontract.AllowStates, ParamCount: 1},
{Name: "System.Blockchain.GetTransactionFromBlock", Func: bcGetTransactionFromBlock, Price: 1000000, {Name: interopnames.SystemBlockchainGetTransactionFromBlock, Func: bcGetTransactionFromBlock, Price: 1000000,
RequiredFlags: smartcontract.AllowStates, ParamCount: 2}, RequiredFlags: smartcontract.AllowStates, ParamCount: 2},
{Name: "System.Blockchain.GetTransactionHeight", Func: bcGetTransactionHeight, Price: 1000000, {Name: interopnames.SystemBlockchainGetTransactionHeight, Func: bcGetTransactionHeight, Price: 1000000,
RequiredFlags: smartcontract.AllowStates, ParamCount: 1}, RequiredFlags: smartcontract.AllowStates, ParamCount: 1},
{Name: "System.Callback.Create", Func: callback.Create, Price: 400, ParamCount: 3, DisallowCallback: true}, {Name: interopnames.SystemCallbackCreate, Func: callback.Create, Price: 400, ParamCount: 3, DisallowCallback: true},
{Name: "System.Callback.CreateFromMethod", Func: callback.CreateFromMethod, Price: 1000000, ParamCount: 2, DisallowCallback: true}, {Name: interopnames.SystemCallbackCreateFromMethod, Func: callback.CreateFromMethod, Price: 1000000, ParamCount: 2, DisallowCallback: true},
{Name: "System.Callback.CreateFromSyscall", Func: callback.CreateFromSyscall, Price: 400, ParamCount: 1, DisallowCallback: true}, {Name: interopnames.SystemCallbackCreateFromSyscall, Func: callback.CreateFromSyscall, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: "System.Callback.Invoke", Func: callback.Invoke, Price: 1000000, ParamCount: 2, DisallowCallback: true}, {Name: interopnames.SystemCallbackInvoke, Func: callback.Invoke, Price: 1000000, ParamCount: 2, DisallowCallback: true},
{Name: "System.Contract.Call", Func: contractCall, Price: 1000000, {Name: interopnames.SystemContractCall, Func: contractCall, Price: 1000000,
RequiredFlags: smartcontract.AllowCall, ParamCount: 3, DisallowCallback: true}, RequiredFlags: smartcontract.AllowCall, ParamCount: 3, DisallowCallback: true},
{Name: "System.Contract.CallEx", Func: contractCallEx, Price: 1000000, {Name: interopnames.SystemContractCallEx, Func: contractCallEx, Price: 1000000,
RequiredFlags: smartcontract.AllowCall, ParamCount: 4, DisallowCallback: true}, RequiredFlags: smartcontract.AllowCall, ParamCount: 4, DisallowCallback: true},
{Name: "System.Contract.Create", Func: contractCreate, Price: 0, {Name: interopnames.SystemContractCreate, Func: contractCreate, Price: 0,
RequiredFlags: smartcontract.AllowModifyStates, ParamCount: 2, DisallowCallback: true}, RequiredFlags: smartcontract.AllowModifyStates, ParamCount: 2, DisallowCallback: true},
{Name: "System.Contract.CreateStandardAccount", Func: contractCreateStandardAccount, Price: 10000, ParamCount: 1, DisallowCallback: true}, {Name: interopnames.SystemContractCreateStandardAccount, Func: contractCreateStandardAccount, Price: 10000, ParamCount: 1, DisallowCallback: true},
{Name: "System.Contract.Destroy", Func: contractDestroy, Price: 1000000, RequiredFlags: smartcontract.AllowModifyStates, DisallowCallback: true}, {Name: interopnames.SystemContractDestroy, Func: contractDestroy, Price: 1000000, RequiredFlags: smartcontract.AllowModifyStates, DisallowCallback: true},
{Name: "System.Contract.IsStandard", Func: contractIsStandard, Price: 30000, ParamCount: 1}, {Name: interopnames.SystemContractIsStandard, Func: contractIsStandard, Price: 30000, ParamCount: 1},
{Name: "System.Contract.GetCallFlags", Func: contractGetCallFlags, Price: 30000, DisallowCallback: true}, {Name: interopnames.SystemContractGetCallFlags, Func: contractGetCallFlags, Price: 30000, DisallowCallback: true},
{Name: "System.Contract.Update", Func: contractUpdate, Price: 0, {Name: interopnames.SystemContractUpdate, Func: contractUpdate, Price: 0,
RequiredFlags: smartcontract.AllowModifyStates, ParamCount: 2, DisallowCallback: true}, RequiredFlags: smartcontract.AllowModifyStates, ParamCount: 2, DisallowCallback: true},
{Name: "System.Enumerator.Concat", Func: enumerator.Concat, Price: 400, ParamCount: 2, DisallowCallback: true}, {Name: interopnames.SystemEnumeratorConcat, Func: enumerator.Concat, Price: 400, ParamCount: 2, DisallowCallback: true},
{Name: "System.Enumerator.Create", Func: enumerator.Create, Price: 400, ParamCount: 1, DisallowCallback: true}, {Name: interopnames.SystemEnumeratorCreate, Func: enumerator.Create, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: "System.Enumerator.Next", Func: enumerator.Next, Price: 1000000, ParamCount: 1, DisallowCallback: true}, {Name: interopnames.SystemEnumeratorNext, Func: enumerator.Next, Price: 1000000, ParamCount: 1, DisallowCallback: true},
{Name: "System.Enumerator.Value", Func: enumerator.Value, Price: 400, ParamCount: 1, DisallowCallback: true}, {Name: interopnames.SystemEnumeratorValue, Func: enumerator.Value, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: "System.Iterator.Concat", Func: iterator.Concat, Price: 400, ParamCount: 2, DisallowCallback: true}, {Name: interopnames.SystemIteratorConcat, Func: iterator.Concat, Price: 400, ParamCount: 2, DisallowCallback: true},
{Name: "System.Iterator.Create", Func: iterator.Create, Price: 400, ParamCount: 1, DisallowCallback: true}, {Name: interopnames.SystemIteratorCreate, Func: iterator.Create, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: "System.Iterator.Key", Func: iterator.Key, Price: 400, ParamCount: 1, DisallowCallback: true}, {Name: interopnames.SystemIteratorKey, Func: iterator.Key, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: "System.Iterator.Keys", Func: iterator.Keys, Price: 400, ParamCount: 1, DisallowCallback: true}, {Name: interopnames.SystemIteratorKeys, Func: iterator.Keys, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: "System.Iterator.Values", Func: iterator.Values, Price: 400, ParamCount: 1, DisallowCallback: true}, {Name: interopnames.SystemIteratorValues, Func: iterator.Values, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: "System.Json.Deserialize", Func: json.Deserialize, Price: 500000, ParamCount: 1}, {Name: interopnames.SystemJSONDeserialize, Func: json.Deserialize, Price: 500000, ParamCount: 1},
{Name: "System.Json.Serialize", Func: json.Serialize, Price: 100000, ParamCount: 1}, {Name: interopnames.SystemJSONSerialize, Func: json.Serialize, Price: 100000, ParamCount: 1},
{Name: "System.Runtime.CheckWitness", Func: runtime.CheckWitness, Price: 30000, {Name: interopnames.SystemRuntimeCheckWitness, Func: runtime.CheckWitness, Price: 30000,
RequiredFlags: smartcontract.AllowStates, ParamCount: 1}, RequiredFlags: smartcontract.AllowStates, ParamCount: 1},
{Name: "System.Runtime.GasLeft", Func: runtime.GasLeft, Price: 400}, {Name: interopnames.SystemRuntimeGasLeft, Func: runtime.GasLeft, Price: 400},
{Name: "System.Runtime.GetCallingScriptHash", Func: engineGetCallingScriptHash, Price: 400}, {Name: interopnames.SystemRuntimeGetCallingScriptHash, Func: engineGetCallingScriptHash, Price: 400},
{Name: "System.Runtime.GetEntryScriptHash", Func: engineGetEntryScriptHash, Price: 400}, {Name: interopnames.SystemRuntimeGetEntryScriptHash, Func: engineGetEntryScriptHash, Price: 400},
{Name: "System.Runtime.GetExecutingScriptHash", Func: engineGetExecutingScriptHash, Price: 400}, {Name: interopnames.SystemRuntimeGetExecutingScriptHash, Func: engineGetExecutingScriptHash, Price: 400},
{Name: "System.Runtime.GetInvocationCounter", Func: runtime.GetInvocationCounter, Price: 400}, {Name: interopnames.SystemRuntimeGetInvocationCounter, Func: runtime.GetInvocationCounter, Price: 400},
{Name: "System.Runtime.GetNotifications", Func: runtime.GetNotifications, Price: 10000, ParamCount: 1}, {Name: interopnames.SystemRuntimeGetNotifications, Func: runtime.GetNotifications, Price: 10000, ParamCount: 1},
{Name: "System.Runtime.GetScriptContainer", Func: engineGetScriptContainer, Price: 250}, {Name: interopnames.SystemRuntimeGetScriptContainer, Func: engineGetScriptContainer, Price: 250},
{Name: "System.Runtime.GetTime", Func: runtimeGetTime, Price: 250, RequiredFlags: smartcontract.AllowStates}, {Name: interopnames.SystemRuntimeGetTime, Func: runtimeGetTime, Price: 250, RequiredFlags: smartcontract.AllowStates},
{Name: "System.Runtime.GetTrigger", Func: runtimeGetTrigger, Price: 250}, {Name: interopnames.SystemRuntimeGetTrigger, Func: runtimeGetTrigger, Price: 250},
{Name: "System.Runtime.Log", Func: runtimeLog, Price: 1000000, RequiredFlags: smartcontract.AllowNotify, {Name: interopnames.SystemRuntimeLog, Func: runtimeLog, Price: 1000000, RequiredFlags: smartcontract.AllowNotify,
ParamCount: 1, DisallowCallback: true}, ParamCount: 1, DisallowCallback: true},
{Name: "System.Runtime.Notify", Func: runtimeNotify, Price: 1000000, RequiredFlags: smartcontract.AllowNotify, {Name: interopnames.SystemRuntimeNotify, Func: runtimeNotify, Price: 1000000, RequiredFlags: smartcontract.AllowNotify,
ParamCount: 2, DisallowCallback: true}, ParamCount: 2, DisallowCallback: true},
{Name: "System.Runtime.Platform", Func: runtimePlatform, Price: 250}, {Name: interopnames.SystemRuntimePlatform, Func: runtimePlatform, Price: 250},
{Name: "System.Storage.Delete", Func: storageDelete, Price: StoragePrice, {Name: interopnames.SystemStorageDelete, Func: storageDelete, Price: StoragePrice,
RequiredFlags: smartcontract.AllowModifyStates, ParamCount: 2, DisallowCallback: true}, RequiredFlags: smartcontract.AllowModifyStates, ParamCount: 2, DisallowCallback: true},
{Name: "System.Storage.Find", Func: storageFind, Price: 1000000, RequiredFlags: smartcontract.AllowStates, {Name: interopnames.SystemStorageFind, Func: storageFind, Price: 1000000, RequiredFlags: smartcontract.AllowStates,
ParamCount: 2, DisallowCallback: true}, ParamCount: 2, DisallowCallback: true},
{Name: "System.Storage.Get", Func: storageGet, Price: 1000000, RequiredFlags: smartcontract.AllowStates, {Name: interopnames.SystemStorageGet, Func: storageGet, Price: 1000000, RequiredFlags: smartcontract.AllowStates,
ParamCount: 2, DisallowCallback: true}, ParamCount: 2, DisallowCallback: true},
{Name: "System.Storage.GetContext", Func: storageGetContext, Price: 400, {Name: interopnames.SystemStorageGetContext, Func: storageGetContext, Price: 400,
RequiredFlags: smartcontract.AllowStates, DisallowCallback: true}, RequiredFlags: smartcontract.AllowStates, DisallowCallback: true},
{Name: "System.Storage.GetReadOnlyContext", Func: storageGetReadOnlyContext, Price: 400, {Name: interopnames.SystemStorageGetReadOnlyContext, Func: storageGetReadOnlyContext, Price: 400,
RequiredFlags: smartcontract.AllowStates, DisallowCallback: true}, RequiredFlags: smartcontract.AllowStates, DisallowCallback: true},
{Name: "System.Storage.Put", Func: storagePut, Price: 0, RequiredFlags: smartcontract.AllowModifyStates, {Name: interopnames.SystemStoragePut, Func: storagePut, Price: 0, RequiredFlags: smartcontract.AllowModifyStates,
ParamCount: 3, DisallowCallback: true}, // These don't have static price in C# code. ParamCount: 3, DisallowCallback: true}, // These don't have static price in C# code.
{Name: "System.Storage.PutEx", Func: storagePutEx, Price: 0, RequiredFlags: smartcontract.AllowModifyStates, {Name: interopnames.SystemStoragePutEx, Func: storagePutEx, Price: 0, RequiredFlags: smartcontract.AllowModifyStates,
ParamCount: 4, DisallowCallback: true}, ParamCount: 4, DisallowCallback: true},
{Name: "System.Storage.AsReadOnly", Func: storageContextAsReadOnly, Price: 400, {Name: interopnames.SystemStorageAsReadOnly, Func: storageContextAsReadOnly, Price: 400,
RequiredFlags: smartcontract.AllowStates, ParamCount: 1, DisallowCallback: true}, RequiredFlags: smartcontract.AllowStates, ParamCount: 1, DisallowCallback: true},
} }
var neoInterops = []interop.Function{ var neoInterops = []interop.Function{
{Name: "Neo.Crypto.VerifyWithECDsaSecp256r1", Func: crypto.ECDSASecp256r1Verify, {Name: interopnames.NeoCryptoVerifyWithECDsaSecp256r1, Func: crypto.ECDSASecp256r1Verify,
Price: crypto.ECDSAVerifyPrice, ParamCount: 3}, Price: crypto.ECDSAVerifyPrice, ParamCount: 3},
{Name: "Neo.Crypto.VerifyWithECDsaSecp256k1", Func: crypto.ECDSASecp256k1Verify, {Name: interopnames.NeoCryptoVerifyWithECDsaSecp256k1, Func: crypto.ECDSASecp256k1Verify,
Price: crypto.ECDSAVerifyPrice, ParamCount: 3}, Price: crypto.ECDSAVerifyPrice, ParamCount: 3},
{Name: "Neo.Crypto.CheckMultisigWithECDsaSecp256r1", Func: crypto.ECDSASecp256r1CheckMultisig, Price: 0, ParamCount: 3}, {Name: interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1, Func: crypto.ECDSASecp256r1CheckMultisig, Price: 0, ParamCount: 3},
{Name: "Neo.Crypto.CheckMultisigWithECDsaSecp256k1", Func: crypto.ECDSASecp256k1CheckMultisig, Price: 0, ParamCount: 3}, {Name: interopnames.NeoCryptoCheckMultisigWithECDsaSecp256k1, Func: crypto.ECDSASecp256k1CheckMultisig, Price: 0, ParamCount: 3},
{Name: "Neo.Crypto.SHA256", Func: crypto.Sha256, Price: 1000000, ParamCount: 1}, {Name: interopnames.NeoCryptoSHA256, Func: crypto.Sha256, Price: 1000000, ParamCount: 1},
{Name: "Neo.Crypto.RIPEMD160", Func: crypto.RipeMD160, Price: 1000000, ParamCount: 1}, {Name: interopnames.NeoCryptoRIPEMD160, Func: crypto.RipeMD160, Price: 1000000, ParamCount: 1},
{Name: "Neo.Native.Call", Func: native.Call, Price: 0, ParamCount: 1, DisallowCallback: true}, {Name: interopnames.NeoNativeCall, Func: native.Call, Price: 0, ParamCount: 1, DisallowCallback: true},
{Name: "Neo.Native.Deploy", Func: native.Deploy, Price: 0, RequiredFlags: smartcontract.AllowModifyStates, DisallowCallback: true}, {Name: interopnames.NeoNativeDeploy, Func: native.Deploy, Price: 0, RequiredFlags: smartcontract.AllowModifyStates, DisallowCallback: true},
} }
// initIDinInteropsSlice initializes IDs from names in one given // initIDinInteropsSlice initializes IDs from names in one given
// Function slice and then sorts it. // Function slice and then sorts it.
func initIDinInteropsSlice(iops []interop.Function) { func initIDinInteropsSlice(iops []interop.Function) {
for i := range iops { for i := range iops {
iops[i].ID = emit.InteropNameToID([]byte(iops[i].Name)) iops[i].ID = interopnames.ToID([]byte(iops[i].Name))
} }
interop.Sort(iops) interop.Sort(iops)
} }

View file

@ -8,6 +8,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/config/netmode"
"github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/nspcc-dev/neo-go/pkg/core/interop/crypto" "github.com/nspcc-dev/neo-go/pkg/core/interop/crypto"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
@ -75,7 +76,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error)
func deployNativeContracts(magic netmode.Magic) *transaction.Transaction { func deployNativeContracts(magic netmode.Magic) *transaction.Transaction {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
emit.Syscall(buf.BinWriter, "Neo.Native.Deploy") emit.Syscall(buf.BinWriter, interopnames.NeoNativeDeploy)
script := buf.Bytes() script := buf.Bytes()
tx := transaction.New(magic, script, 0) tx := transaction.New(magic, script, 0)
tx.Nonce = 0 tx.Nonce = 0

View file

@ -11,6 +11,7 @@ import (
"math/big" "math/big"
"github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/btcec"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
@ -295,7 +296,7 @@ func (p *PublicKey) GetVerificationScript() []byte {
} }
emit.Bytes(buf.BinWriter, b) emit.Bytes(buf.BinWriter, b)
emit.Opcode(buf.BinWriter, opcode.PUSHNULL) emit.Opcode(buf.BinWriter, opcode.PUSHNULL)
emit.Syscall(buf.BinWriter, "Neo.Crypto.VerifyWithECDsaSecp256r1") emit.Syscall(buf.BinWriter, interopnames.NeoCryptoVerifyWithECDsaSecp256r1)
return buf.Bytes() return buf.Bytes()
} }

View file

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"strconv" "strconv"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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/io"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
@ -24,7 +25,7 @@ func CreateDeploymentScript(avm []byte, manif *manifest.Manifest) ([]byte, error
} }
emit.Bytes(script.BinWriter, rawManifest) emit.Bytes(script.BinWriter, rawManifest)
emit.Bytes(script.BinWriter, avm) emit.Bytes(script.BinWriter, avm)
emit.Syscall(script.BinWriter, "System.Contract.Create") emit.Syscall(script.BinWriter, interopnames.SystemContractCreate)
return script.Bytes(), nil return script.Bytes(), nil
} }

View file

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"sort" "sort"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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/io"
"github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/emit"
@ -31,7 +32,7 @@ func CreateMultiSigRedeemScript(m int, publicKeys keys.PublicKeys) ([]byte, erro
} }
emit.Int(buf.BinWriter, int64(len(publicKeys))) emit.Int(buf.BinWriter, int64(len(publicKeys)))
emit.Opcode(buf.BinWriter, opcode.PUSHNULL) emit.Opcode(buf.BinWriter, opcode.PUSHNULL)
emit.Syscall(buf.BinWriter, "Neo.Crypto.CheckMultisigWithECDsaSecp256r1") emit.Syscall(buf.BinWriter, interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1)
return buf.Bytes(), nil return buf.Bytes(), nil
} }

View file

@ -3,9 +3,9 @@ package smartcontract
import ( import (
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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/io"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/vm/opcode"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -34,7 +34,7 @@ func TestCreateMultiSigRedeemScript(t *testing.T) {
assert.Equal(t, opcode.PUSH3, opcode.Opcode(br.ReadB())) assert.Equal(t, opcode.PUSH3, opcode.Opcode(br.ReadB()))
assert.Equal(t, opcode.PUSHNULL, opcode.Opcode(br.ReadB())) assert.Equal(t, opcode.PUSHNULL, opcode.Opcode(br.ReadB()))
assert.Equal(t, opcode.SYSCALL, opcode.Opcode(br.ReadB())) assert.Equal(t, opcode.SYSCALL, opcode.Opcode(br.ReadB()))
assert.Equal(t, emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1")), br.ReadU32LE()) assert.Equal(t, interopnames.ToID([]byte(interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1)), br.ReadU32LE())
} }
func TestCreateDefaultMultiSigRedeemScript(t *testing.T) { func TestCreateDefaultMultiSigRedeemScript(t *testing.T) {

View file

@ -3,15 +3,15 @@ package vm
import ( import (
"encoding/binary" "encoding/binary"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint" "github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/vm/opcode"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
) )
var ( var (
verifyInteropID = emit.InteropNameToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256r1")) verifyInteropID = interopnames.ToID([]byte(interopnames.NeoCryptoVerifyWithECDsaSecp256r1))
multisigInteropID = emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1")) multisigInteropID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1))
) )
func getNumOfThingsFromInstr(instr opcode.Opcode, param []byte) (int, bool) { func getNumOfThingsFromInstr(instr opcode.Opcode, param []byte) (int, bool) {

View file

@ -1,13 +1,13 @@
package emit package emit
import ( import (
"crypto/sha256"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
"math/bits" "math/bits"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint" "github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
@ -124,7 +124,7 @@ func Syscall(w *io.BinWriter, api string) {
return return
} }
buf := make([]byte, 4) buf := make([]byte, 4)
binary.LittleEndian.PutUint32(buf, InteropNameToID([]byte(api))) binary.LittleEndian.PutUint32(buf, interopnames.ToID([]byte(api)))
Instruction(w, opcode.SYSCALL, buf) Instruction(w, opcode.SYSCALL, buf)
} }
@ -149,7 +149,7 @@ func Jmp(w *io.BinWriter, op opcode.Opcode, label uint16) {
// AppCall emits call to provided contract. // AppCall emits call to provided contract.
func AppCall(w *io.BinWriter, scriptHash util.Uint160) { func AppCall(w *io.BinWriter, scriptHash util.Uint160) {
Bytes(w, scriptHash.BytesBE()) Bytes(w, scriptHash.BytesBE())
Syscall(w, "System.Contract.Call") Syscall(w, interopnames.SystemContractCall)
} }
// AppCallWithOperationAndArgs emits an APPCALL with the given operation and arguments. // AppCallWithOperationAndArgs emits an APPCALL with the given operation and arguments.
@ -162,9 +162,3 @@ func AppCallWithOperationAndArgs(w *io.BinWriter, scriptHash util.Uint160, opera
func isInstructionJmp(op opcode.Opcode) bool { func isInstructionJmp(op opcode.Opcode) bool {
return opcode.JMP <= op && op <= opcode.CALLL return opcode.JMP <= op && op <= opcode.CALLL
} }
// InteropNameToID returns an identificator of the method based on its name.
func InteropNameToID(name []byte) uint32 {
h := sha256.Sum256(name)
return binary.LittleEndian.Uint32(h[:4])
}

View file

@ -5,6 +5,7 @@ import (
"errors" "errors"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint" "github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/vm/opcode"
@ -190,8 +191,8 @@ func TestEmitString(t *testing.T) {
func TestEmitSyscall(t *testing.T) { func TestEmitSyscall(t *testing.T) {
syscalls := []string{ syscalls := []string{
"System.Runtime.Log", interopnames.SystemRuntimeLog,
"System.Runtime.Notify", interopnames.SystemRuntimeNotify,
"System.Runtime.Whatever", "System.Runtime.Whatever",
} }
@ -201,7 +202,7 @@ func TestEmitSyscall(t *testing.T) {
result := buf.Bytes() result := buf.Bytes()
assert.Equal(t, 5, len(result)) assert.Equal(t, 5, len(result))
assert.Equal(t, opcode.Opcode(result[0]), opcode.SYSCALL) assert.Equal(t, opcode.Opcode(result[0]), opcode.SYSCALL)
assert.Equal(t, binary.LittleEndian.Uint32(result[1:]), InteropNameToID([]byte(syscall))) assert.Equal(t, binary.LittleEndian.Uint32(result[1:]), interopnames.ToID([]byte(syscall)))
buf.Reset() buf.Reset()
} }

View file

@ -5,8 +5,8 @@ import (
"fmt" "fmt"
"sort" "sort"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
) )
@ -19,31 +19,31 @@ type interopIDFuncPrice struct {
} }
var defaultVMInterops = []interopIDFuncPrice{ var defaultVMInterops = []interopIDFuncPrice{
{ID: emit.InteropNameToID([]byte("System.Binary.Deserialize")), {ID: interopnames.ToID([]byte(interopnames.SystemBinaryDeserialize)),
Func: RuntimeDeserialize, Price: 500000}, Func: RuntimeDeserialize, Price: 500000},
{ID: emit.InteropNameToID([]byte("System.Binary.Serialize")), {ID: interopnames.ToID([]byte(interopnames.SystemBinarySerialize)),
Func: RuntimeSerialize, Price: 100000}, Func: RuntimeSerialize, Price: 100000},
{ID: emit.InteropNameToID([]byte("System.Runtime.Log")), {ID: interopnames.ToID([]byte(interopnames.SystemRuntimeLog)),
Func: runtimeLog, Price: 1000000, RequiredFlags: smartcontract.AllowNotify}, Func: runtimeLog, Price: 1000000, RequiredFlags: smartcontract.AllowNotify},
{ID: emit.InteropNameToID([]byte("System.Runtime.Notify")), {ID: interopnames.ToID([]byte(interopnames.SystemRuntimeNotify)),
Func: runtimeNotify, Price: 1000000, RequiredFlags: smartcontract.AllowNotify}, Func: runtimeNotify, Price: 1000000, RequiredFlags: smartcontract.AllowNotify},
{ID: emit.InteropNameToID([]byte("System.Enumerator.Create")), {ID: interopnames.ToID([]byte(interopnames.SystemEnumeratorCreate)),
Func: EnumeratorCreate, Price: 400}, Func: EnumeratorCreate, Price: 400},
{ID: emit.InteropNameToID([]byte("System.Enumerator.Next")), {ID: interopnames.ToID([]byte(interopnames.SystemEnumeratorNext)),
Func: EnumeratorNext, Price: 1000000}, Func: EnumeratorNext, Price: 1000000},
{ID: emit.InteropNameToID([]byte("System.Enumerator.Concat")), {ID: interopnames.ToID([]byte(interopnames.SystemEnumeratorConcat)),
Func: EnumeratorConcat, Price: 400}, Func: EnumeratorConcat, Price: 400},
{ID: emit.InteropNameToID([]byte("System.Enumerator.Value")), {ID: interopnames.ToID([]byte(interopnames.SystemEnumeratorValue)),
Func: EnumeratorValue, Price: 400}, Func: EnumeratorValue, Price: 400},
{ID: emit.InteropNameToID([]byte("System.Iterator.Create")), {ID: interopnames.ToID([]byte(interopnames.SystemIteratorCreate)),
Func: IteratorCreate, Price: 400}, Func: IteratorCreate, Price: 400},
{ID: emit.InteropNameToID([]byte("System.Iterator.Concat")), {ID: interopnames.ToID([]byte(interopnames.SystemIteratorConcat)),
Func: IteratorConcat, Price: 400}, Func: IteratorConcat, Price: 400},
{ID: emit.InteropNameToID([]byte("System.Iterator.Key")), {ID: interopnames.ToID([]byte(interopnames.SystemIteratorKey)),
Func: IteratorKey, Price: 400}, Func: IteratorKey, Price: 400},
{ID: emit.InteropNameToID([]byte("System.Iterator.Keys")), {ID: interopnames.ToID([]byte(interopnames.SystemIteratorKeys)),
Func: IteratorKeys, Price: 400}, Func: IteratorKeys, Price: 400},
{ID: emit.InteropNameToID([]byte("System.Iterator.Values")), {ID: interopnames.ToID([]byte(interopnames.SystemIteratorValues)),
Func: IteratorValues, Price: 400}, Func: IteratorValues, Price: 400},
} }

View file

@ -13,6 +13,7 @@ import (
"text/tabwriter" "text/tabwriter"
"unicode/utf8" "unicode/utf8"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"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/encoding/bigint" "github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
@ -191,10 +192,23 @@ func (v *VM) PrintOps() {
v.getOffsetDesc(ctx, catchP), v.getOffsetDesc(ctx, finallyP)) v.getOffsetDesc(ctx, catchP), v.getOffsetDesc(ctx, finallyP))
case opcode.INITSSLOT: case opcode.INITSSLOT:
desc = fmt.Sprint(parameter[0]) desc = fmt.Sprint(parameter[0])
case opcode.CONVERT, opcode.ISTYPE:
typ := stackitem.Type(parameter[0])
desc = fmt.Sprintf("%s (%x)", typ, parameter[0])
case opcode.INITSLOT: case opcode.INITSLOT:
desc = fmt.Sprintf("%d local, %d arg", parameter[0], parameter[1]) desc = fmt.Sprintf("%d local, %d arg", parameter[0], parameter[1])
case opcode.SYSCALL: case opcode.SYSCALL:
desc = fmt.Sprintf("%q", parameter) name, err := interopnames.FromID(GetInteropID(parameter))
if err != nil {
name = "not found"
}
desc = fmt.Sprintf("%s (%x)", name, parameter)
case opcode.PUSHINT8, opcode.PUSHINT16, opcode.PUSHINT32,
opcode.PUSHINT64, opcode.PUSHINT128, opcode.PUSHINT256:
val := bigint.FromBytes(parameter)
desc = fmt.Sprintf("%d (%x)", val, parameter)
case opcode.LDLOC, opcode.STLOC, opcode.LDARG, opcode.STARG, opcode.LDSFLD, opcode.STSFLD:
desc = fmt.Sprintf("%d (%x)", parameter[0], parameter)
default: default:
if utf8.Valid(parameter) { if utf8.Valid(parameter) {
desc = fmt.Sprintf("%x (%q)", parameter, parameter) desc = fmt.Sprintf("%x (%q)", parameter, parameter)

View file

@ -11,6 +11,7 @@ import (
"math/rand" "math/rand"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint" "github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
"github.com/nspcc-dev/neo-go/pkg/internal/random" "github.com/nspcc-dev/neo-go/pkg/internal/random"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
@ -23,7 +24,7 @@ import (
) )
func fooInteropHandler(v *VM, id uint32) error { func fooInteropHandler(v *VM, id uint32) error {
if id == emit.InteropNameToID([]byte("foo")) { if id == interopnames.ToID([]byte("foo")) {
if !v.AddGas(1) { if !v.AddGas(1) {
return errors.New("invalid gas amount") return errors.New("invalid gas amount")
} }
@ -244,6 +245,8 @@ func TestISTYPE(t *testing.T) {
func testCONVERT(to stackitem.Type, item, res stackitem.Item) func(t *testing.T) { func testCONVERT(to stackitem.Type, item, res stackitem.Item) func(t *testing.T) {
return func(t *testing.T) { return func(t *testing.T) {
prog := []byte{byte(opcode.CONVERT), byte(to)} prog := []byte{byte(opcode.CONVERT), byte(to)}
v := load(prog)
v.PrintOps()
runWithArgs(t, prog, res, item) runWithArgs(t, prog, res, item)
} }
} }
@ -491,16 +494,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("System.Enumerator.Next")...) prog = append(prog, getSyscallProg(interopnames.SystemEnumeratorNext)...)
prog = append(prog, byte(opcode.LDSFLD0)) prog = append(prog, byte(opcode.LDSFLD0))
prog = append(prog, getSyscallProg("System.Enumerator.Value")...) prog = append(prog, getSyscallProg(interopnames.SystemEnumeratorValue)...)
if isIter { if isIter {
prog = append(prog, byte(opcode.LDSFLD0)) prog = append(prog, byte(opcode.LDSFLD0))
prog = append(prog, getSyscallProg("System.Iterator.Key")...) prog = append(prog, getSyscallProg(interopnames.SystemIteratorKey)...)
} }
} }
prog = append(prog, byte(opcode.LDSFLD0)) prog = append(prog, byte(opcode.LDSFLD0))
prog = append(prog, getSyscallProg("System.Enumerator.Next")...) prog = append(prog, getSyscallProg(interopnames.SystemEnumeratorNext)...)
return return
} }
@ -592,8 +595,8 @@ func TestIteratorConcat(t *testing.T) {
} }
func TestIteratorKeys(t *testing.T) { func TestIteratorKeys(t *testing.T) {
prog := getSyscallProg("System.Iterator.Create") prog := getSyscallProg(interopnames.SystemIteratorCreate)
prog = append(prog, getSyscallProg("System.Iterator.Keys")...) prog = append(prog, getSyscallProg(interopnames.SystemIteratorKeys)...)
prog = append(prog, getEnumeratorProg(2, false)...) prog = append(prog, getEnumeratorProg(2, false)...)
v := load(prog) v := load(prog)
@ -612,8 +615,8 @@ func TestIteratorKeys(t *testing.T) {
} }
func TestIteratorValues(t *testing.T) { func TestIteratorValues(t *testing.T) {
prog := getSyscallProg("System.Iterator.Create") prog := getSyscallProg(interopnames.SystemIteratorCreate)
prog = append(prog, getSyscallProg("System.Iterator.Values")...) prog = append(prog, getSyscallProg(interopnames.SystemIteratorValues)...)
prog = append(prog, getEnumeratorProg(2, false)...) prog = append(prog, getEnumeratorProg(2, false)...)
v := load(prog) v := load(prog)
@ -646,8 +649,8 @@ func getSyscallProg(name string) (prog []byte) {
} }
func getSerializeProg() (prog []byte) { func getSerializeProg() (prog []byte) {
prog = append(prog, getSyscallProg("System.Binary.Serialize")...) prog = append(prog, getSyscallProg(interopnames.SystemBinarySerialize)...)
prog = append(prog, getSyscallProg("System.Binary.Deserialize")...) prog = append(prog, getSyscallProg(interopnames.SystemBinaryDeserialize)...)
prog = append(prog, byte(opcode.RET)) prog = append(prog, byte(opcode.RET))
return return
@ -752,7 +755,7 @@ func TestSerializeStruct(t *testing.T) {
} }
func TestDeserializeUnknown(t *testing.T) { func TestDeserializeUnknown(t *testing.T) {
prog := append(getSyscallProg("System.Binary.Deserialize"), byte(opcode.RET)) prog := append(getSyscallProg(interopnames.SystemBinaryDeserialize), 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)
@ -788,7 +791,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, "System.Binary.Serialize") emit.Syscall(buf.BinWriter, interopnames.SystemBinarySerialize)
require.NoError(t, buf.Err) require.NoError(t, buf.Err)
vm := load(buf.Bytes()) vm := load(buf.Bytes())