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"
"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/io"
"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)
} else if isString(c.typeInfo.Types[arg].Type) {
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)
} else {
c.prog.Err = errors.New("panic should have string or nil argument")

View file

@ -6,8 +6,8 @@ import (
"math/big"
"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/emit"
"github.com/stretchr/testify/require"
)
@ -56,7 +56,7 @@ func getPanicSource(need bool, message string) string {
}
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 {
if id != logID {
return errors.New("syscall not found")

View file

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

View file

@ -4,9 +4,9 @@ import (
"fmt"
"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/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -19,7 +19,7 @@ func TestVerifyGood(t *testing.T) {
src := getVerifyProg(pub, sig, msg)
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, pub, v.Estack().Pop().Bytes())
assert.Equal(t, sig, v.Estack().Pop().Bytes())

View file

@ -7,11 +7,11 @@ import (
"testing"
"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/smartcontract"
"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/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -109,10 +109,10 @@ func newStoragePlugin() *storagePlugin {
mem: make(map[string][]byte),
interops: make(map[uint32]func(v *vm.VM) error),
}
s.interops[emit.InteropNameToID([]byte("System.Storage.Get"))] = s.Get
s.interops[emit.InteropNameToID([]byte("System.Storage.Put"))] = s.Put
s.interops[emit.InteropNameToID([]byte("System.Storage.GetContext"))] = s.GetContext
s.interops[emit.InteropNameToID([]byte("System.Runtime.Notify"))] = s.Notify
s.interops[interopnames.ToID([]byte(interopnames.SystemStorageGet))] = s.Get
s.interops[interopnames.ToID([]byte(interopnames.SystemStoragePut))] = s.Put
s.interops[interopnames.ToID([]byte(interopnames.SystemStorageGetContext))] = s.GetContext
s.interops[interopnames.ToID([]byte(interopnames.SystemRuntimeNotify))] = s.Notify
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/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/storage"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
@ -273,7 +274,7 @@ func TestSubscriptions(t *testing.T) {
script := io.NewBufBinWriter()
emit.Bytes(script.BinWriter, []byte("yay!"))
emit.Syscall(script.BinWriter, "System.Runtime.Notify")
emit.Syscall(script.BinWriter, interopnames.SystemRuntimeNotify)
require.NoError(t, script.Err)
txGood1 := transaction.New(netmode.UnitTestNet, script.Bytes(), 0)
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.
script = io.NewBufBinWriter()
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)
require.NoError(t, script.Err)
txBad := transaction.New(netmode.UnitTestNet, script.Bytes(), 0)
@ -295,7 +296,7 @@ func TestSubscriptions(t *testing.T) {
script = io.NewBufBinWriter()
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)
txGood2 := transaction.New(netmode.UnitTestNet, script.Bytes(), 0)
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/config"
"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/storage"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
@ -239,7 +240,7 @@ func TestCreateBasicChain(t *testing.T) {
require.NoError(t, err)
emit.Bytes(script.BinWriter, bs)
emit.Bytes(script.BinWriter, avm)
emit.Syscall(script.BinWriter, "System.Contract.Create")
emit.Syscall(script.BinWriter, interopnames.SystemContractCreate)
txScript := script.Bytes()
txDeploy := transaction.New(testchain.Network(), txScript, 100*native.GASFactor)

View file

@ -4,8 +4,8 @@ import (
"errors"
"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/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)
@ -27,7 +27,7 @@ func Invoke(ic *interop.Context) error {
cb.LoadContext(ic.VM, args)
switch t := cb.(type) {
case *MethodCallback:
id := emit.InteropNameToID([]byte("System.Contract.Call"))
id := interopnames.ToID([]byte(interopnames.SystemContractCall))
return ic.SyscallHandler(ic.VM, id)
case *SyscallCallback:
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/blockchainer"
"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/transaction"
"github.com/nspcc-dev/neo-go/pkg/crypto"
@ -110,7 +111,7 @@ func NewContractMD(name string) *ContractMD {
w := io.NewBufBinWriter()
emit.String(w.BinWriter, c.Name)
emit.Syscall(w.BinWriter, "Neo.Native.Call")
emit.Syscall(w.BinWriter, interopnames.NeoNativeCall)
c.Script = w.Bytes()
c.Hash = hash.Hash160(c.Script)

View file

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

View file

@ -2,16 +2,16 @@ package crypto
import (
"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 (
ecdsaSecp256r1VerifyID = emit.InteropNameToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256r1"))
ecdsaSecp256k1VerifyID = emit.InteropNameToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256k1"))
ecdsaSecp256r1CheckMultisigID = emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1"))
ecdsaSecp256k1CheckMultisigID = emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256k1"))
sha256ID = emit.InteropNameToID([]byte("Neo.Crypto.SHA256"))
ripemd160ID = emit.InteropNameToID([]byte("Neo.Crypto.RIPEMD160"))
ecdsaSecp256r1VerifyID = interopnames.ToID([]byte(interopnames.NeoCryptoVerifyWithECDsaSecp256r1))
ecdsaSecp256k1VerifyID = interopnames.ToID([]byte(interopnames.NeoCryptoVerifyWithECDsaSecp256k1))
ecdsaSecp256r1CheckMultisigID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1))
ecdsaSecp256k1CheckMultisigID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckMultisigWithECDsaSecp256k1))
sha256ID = interopnames.ToID([]byte(interopnames.NeoCryptoSHA256))
ripemd160ID = interopnames.ToID([]byte(interopnames.NeoCryptoRIPEMD160))
)
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"
"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/stackitem"
"github.com/stretchr/testify/require"
)
var (
serializeID = emit.InteropNameToID([]byte("System.Json.Serialize"))
deserializeID = emit.InteropNameToID([]byte("System.Json.Deserialize"))
serializeID = interopnames.ToID([]byte(interopnames.SystemJSONSerialize))
deserializeID = interopnames.ToID([]byte(interopnames.SystemJSONDeserialize))
)
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/crypto"
"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/json"
"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/smartcontract"
"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
@ -31,101 +31,101 @@ func SpawnVM(ic *interop.Context) *vm.VM {
// All lists are sorted, keep 'em this way, please.
var systemInterops = []interop.Function{
{Name: "System.Binary.Base64Decode", Func: runtimeDecode, Price: 100000, ParamCount: 1},
{Name: "System.Binary.Base64Encode", Func: runtimeEncode, Price: 100000, ParamCount: 1},
{Name: "System.Binary.Deserialize", Func: runtimeDeserialize, Price: 500000, ParamCount: 1},
{Name: "System.Binary.Serialize", Func: runtimeSerialize, Price: 100000, ParamCount: 1},
{Name: "System.Blockchain.GetBlock", Func: bcGetBlock, Price: 2500000,
{Name: interopnames.SystemBinaryBase64Decode, Func: runtimeDecode, Price: 100000, ParamCount: 1},
{Name: interopnames.SystemBinaryBase64Encode, Func: runtimeEncode, Price: 100000, ParamCount: 1},
{Name: interopnames.SystemBinaryDeserialize, Func: runtimeDeserialize, Price: 500000, ParamCount: 1},
{Name: interopnames.SystemBinarySerialize, Func: runtimeSerialize, Price: 100000, ParamCount: 1},
{Name: interopnames.SystemBlockchainGetBlock, Func: bcGetBlock, Price: 2500000,
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},
{Name: "System.Blockchain.GetHeight", Func: bcGetHeight, Price: 400,
{Name: interopnames.SystemBlockchainGetHeight, Func: bcGetHeight, Price: 400,
RequiredFlags: smartcontract.AllowStates},
{Name: "System.Blockchain.GetTransaction", Func: bcGetTransaction, Price: 1000000,
{Name: interopnames.SystemBlockchainGetTransaction, Func: bcGetTransaction, Price: 1000000,
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},
{Name: "System.Blockchain.GetTransactionHeight", Func: bcGetTransactionHeight, Price: 1000000,
{Name: interopnames.SystemBlockchainGetTransactionHeight, Func: bcGetTransactionHeight, Price: 1000000,
RequiredFlags: smartcontract.AllowStates, ParamCount: 1},
{Name: "System.Callback.Create", Func: callback.Create, Price: 400, ParamCount: 3, DisallowCallback: true},
{Name: "System.Callback.CreateFromMethod", Func: callback.CreateFromMethod, Price: 1000000, ParamCount: 2, DisallowCallback: true},
{Name: "System.Callback.CreateFromSyscall", Func: callback.CreateFromSyscall, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: "System.Callback.Invoke", Func: callback.Invoke, Price: 1000000, ParamCount: 2, DisallowCallback: true},
{Name: "System.Contract.Call", Func: contractCall, Price: 1000000,
{Name: interopnames.SystemCallbackCreate, Func: callback.Create, Price: 400, ParamCount: 3, DisallowCallback: true},
{Name: interopnames.SystemCallbackCreateFromMethod, Func: callback.CreateFromMethod, Price: 1000000, ParamCount: 2, DisallowCallback: true},
{Name: interopnames.SystemCallbackCreateFromSyscall, Func: callback.CreateFromSyscall, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: interopnames.SystemCallbackInvoke, Func: callback.Invoke, Price: 1000000, ParamCount: 2, DisallowCallback: true},
{Name: interopnames.SystemContractCall, Func: contractCall, Price: 1000000,
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},
{Name: "System.Contract.Create", Func: contractCreate, Price: 0,
{Name: interopnames.SystemContractCreate, Func: contractCreate, Price: 0,
RequiredFlags: smartcontract.AllowModifyStates, ParamCount: 2, DisallowCallback: true},
{Name: "System.Contract.CreateStandardAccount", Func: contractCreateStandardAccount, Price: 10000, ParamCount: 1, DisallowCallback: true},
{Name: "System.Contract.Destroy", Func: contractDestroy, Price: 1000000, RequiredFlags: smartcontract.AllowModifyStates, DisallowCallback: true},
{Name: "System.Contract.IsStandard", Func: contractIsStandard, Price: 30000, ParamCount: 1},
{Name: "System.Contract.GetCallFlags", Func: contractGetCallFlags, Price: 30000, DisallowCallback: true},
{Name: "System.Contract.Update", Func: contractUpdate, Price: 0,
{Name: interopnames.SystemContractCreateStandardAccount, Func: contractCreateStandardAccount, Price: 10000, ParamCount: 1, DisallowCallback: true},
{Name: interopnames.SystemContractDestroy, Func: contractDestroy, Price: 1000000, RequiredFlags: smartcontract.AllowModifyStates, DisallowCallback: true},
{Name: interopnames.SystemContractIsStandard, Func: contractIsStandard, Price: 30000, ParamCount: 1},
{Name: interopnames.SystemContractGetCallFlags, Func: contractGetCallFlags, Price: 30000, DisallowCallback: true},
{Name: interopnames.SystemContractUpdate, Func: contractUpdate, Price: 0,
RequiredFlags: smartcontract.AllowModifyStates, ParamCount: 2, DisallowCallback: true},
{Name: "System.Enumerator.Concat", Func: enumerator.Concat, Price: 400, ParamCount: 2, DisallowCallback: true},
{Name: "System.Enumerator.Create", Func: enumerator.Create, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: "System.Enumerator.Next", Func: enumerator.Next, Price: 1000000, ParamCount: 1, DisallowCallback: true},
{Name: "System.Enumerator.Value", Func: enumerator.Value, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: "System.Iterator.Concat", Func: iterator.Concat, Price: 400, ParamCount: 2, DisallowCallback: true},
{Name: "System.Iterator.Create", Func: iterator.Create, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: "System.Iterator.Key", Func: iterator.Key, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: "System.Iterator.Keys", Func: iterator.Keys, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: "System.Iterator.Values", Func: iterator.Values, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: "System.Json.Deserialize", Func: json.Deserialize, Price: 500000, ParamCount: 1},
{Name: "System.Json.Serialize", Func: json.Serialize, Price: 100000, ParamCount: 1},
{Name: "System.Runtime.CheckWitness", Func: runtime.CheckWitness, Price: 30000,
{Name: interopnames.SystemEnumeratorConcat, Func: enumerator.Concat, Price: 400, ParamCount: 2, DisallowCallback: true},
{Name: interopnames.SystemEnumeratorCreate, Func: enumerator.Create, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: interopnames.SystemEnumeratorNext, Func: enumerator.Next, Price: 1000000, ParamCount: 1, DisallowCallback: true},
{Name: interopnames.SystemEnumeratorValue, Func: enumerator.Value, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: interopnames.SystemIteratorConcat, Func: iterator.Concat, Price: 400, ParamCount: 2, DisallowCallback: true},
{Name: interopnames.SystemIteratorCreate, Func: iterator.Create, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: interopnames.SystemIteratorKey, Func: iterator.Key, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: interopnames.SystemIteratorKeys, Func: iterator.Keys, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: interopnames.SystemIteratorValues, Func: iterator.Values, Price: 400, ParamCount: 1, DisallowCallback: true},
{Name: interopnames.SystemJSONDeserialize, Func: json.Deserialize, Price: 500000, ParamCount: 1},
{Name: interopnames.SystemJSONSerialize, Func: json.Serialize, Price: 100000, ParamCount: 1},
{Name: interopnames.SystemRuntimeCheckWitness, Func: runtime.CheckWitness, Price: 30000,
RequiredFlags: smartcontract.AllowStates, ParamCount: 1},
{Name: "System.Runtime.GasLeft", Func: runtime.GasLeft, Price: 400},
{Name: "System.Runtime.GetCallingScriptHash", Func: engineGetCallingScriptHash, Price: 400},
{Name: "System.Runtime.GetEntryScriptHash", Func: engineGetEntryScriptHash, Price: 400},
{Name: "System.Runtime.GetExecutingScriptHash", Func: engineGetExecutingScriptHash, Price: 400},
{Name: "System.Runtime.GetInvocationCounter", Func: runtime.GetInvocationCounter, Price: 400},
{Name: "System.Runtime.GetNotifications", Func: runtime.GetNotifications, Price: 10000, ParamCount: 1},
{Name: "System.Runtime.GetScriptContainer", Func: engineGetScriptContainer, Price: 250},
{Name: "System.Runtime.GetTime", Func: runtimeGetTime, Price: 250, RequiredFlags: smartcontract.AllowStates},
{Name: "System.Runtime.GetTrigger", Func: runtimeGetTrigger, Price: 250},
{Name: "System.Runtime.Log", Func: runtimeLog, Price: 1000000, RequiredFlags: smartcontract.AllowNotify,
{Name: interopnames.SystemRuntimeGasLeft, Func: runtime.GasLeft, Price: 400},
{Name: interopnames.SystemRuntimeGetCallingScriptHash, Func: engineGetCallingScriptHash, Price: 400},
{Name: interopnames.SystemRuntimeGetEntryScriptHash, Func: engineGetEntryScriptHash, Price: 400},
{Name: interopnames.SystemRuntimeGetExecutingScriptHash, Func: engineGetExecutingScriptHash, Price: 400},
{Name: interopnames.SystemRuntimeGetInvocationCounter, Func: runtime.GetInvocationCounter, Price: 400},
{Name: interopnames.SystemRuntimeGetNotifications, Func: runtime.GetNotifications, Price: 10000, ParamCount: 1},
{Name: interopnames.SystemRuntimeGetScriptContainer, Func: engineGetScriptContainer, Price: 250},
{Name: interopnames.SystemRuntimeGetTime, Func: runtimeGetTime, Price: 250, RequiredFlags: smartcontract.AllowStates},
{Name: interopnames.SystemRuntimeGetTrigger, Func: runtimeGetTrigger, Price: 250},
{Name: interopnames.SystemRuntimeLog, Func: runtimeLog, Price: 1000000, RequiredFlags: smartcontract.AllowNotify,
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},
{Name: "System.Runtime.Platform", Func: runtimePlatform, Price: 250},
{Name: "System.Storage.Delete", Func: storageDelete, Price: StoragePrice,
{Name: interopnames.SystemRuntimePlatform, Func: runtimePlatform, Price: 250},
{Name: interopnames.SystemStorageDelete, Func: storageDelete, Price: StoragePrice,
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},
{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},
{Name: "System.Storage.GetContext", Func: storageGetContext, Price: 400,
{Name: interopnames.SystemStorageGetContext, Func: storageGetContext, Price: 400,
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},
{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.
{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},
{Name: "System.Storage.AsReadOnly", Func: storageContextAsReadOnly, Price: 400,
{Name: interopnames.SystemStorageAsReadOnly, Func: storageContextAsReadOnly, Price: 400,
RequiredFlags: smartcontract.AllowStates, ParamCount: 1, DisallowCallback: true},
}
var neoInterops = []interop.Function{
{Name: "Neo.Crypto.VerifyWithECDsaSecp256r1", Func: crypto.ECDSASecp256r1Verify,
{Name: interopnames.NeoCryptoVerifyWithECDsaSecp256r1, Func: crypto.ECDSASecp256r1Verify,
Price: crypto.ECDSAVerifyPrice, ParamCount: 3},
{Name: "Neo.Crypto.VerifyWithECDsaSecp256k1", Func: crypto.ECDSASecp256k1Verify,
{Name: interopnames.NeoCryptoVerifyWithECDsaSecp256k1, Func: crypto.ECDSASecp256k1Verify,
Price: crypto.ECDSAVerifyPrice, ParamCount: 3},
{Name: "Neo.Crypto.CheckMultisigWithECDsaSecp256r1", Func: crypto.ECDSASecp256r1CheckMultisig, Price: 0, ParamCount: 3},
{Name: "Neo.Crypto.CheckMultisigWithECDsaSecp256k1", Func: crypto.ECDSASecp256k1CheckMultisig, Price: 0, ParamCount: 3},
{Name: "Neo.Crypto.SHA256", Func: crypto.Sha256, Price: 1000000, ParamCount: 1},
{Name: "Neo.Crypto.RIPEMD160", Func: crypto.RipeMD160, Price: 1000000, ParamCount: 1},
{Name: "Neo.Native.Call", 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.NeoCryptoCheckMultisigWithECDsaSecp256r1, Func: crypto.ECDSASecp256r1CheckMultisig, Price: 0, ParamCount: 3},
{Name: interopnames.NeoCryptoCheckMultisigWithECDsaSecp256k1, Func: crypto.ECDSASecp256k1CheckMultisig, Price: 0, ParamCount: 3},
{Name: interopnames.NeoCryptoSHA256, Func: crypto.Sha256, Price: 1000000, ParamCount: 1},
{Name: interopnames.NeoCryptoRIPEMD160, Func: crypto.RipeMD160, Price: 1000000, ParamCount: 1},
{Name: interopnames.NeoNativeCall, Func: native.Call, Price: 0, ParamCount: 1, DisallowCallback: true},
{Name: interopnames.NeoNativeDeploy, Func: native.Deploy, Price: 0, RequiredFlags: smartcontract.AllowModifyStates, DisallowCallback: true},
}
// initIDinInteropsSlice initializes IDs from names in one given
// Function slice and then sorts it.
func initIDinInteropsSlice(iops []interop.Function) {
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)
}

View file

@ -8,6 +8,7 @@ import (
"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/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/crypto/hash"
"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 {
buf := io.NewBufBinWriter()
emit.Syscall(buf.BinWriter, "Neo.Native.Deploy")
emit.Syscall(buf.BinWriter, interopnames.NeoNativeDeploy)
script := buf.Bytes()
tx := transaction.New(magic, script, 0)
tx.Nonce = 0

View file

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

View file

@ -5,6 +5,7 @@ import (
"fmt"
"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/io"
"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, avm)
emit.Syscall(script.BinWriter, "System.Contract.Create")
emit.Syscall(script.BinWriter, interopnames.SystemContractCreate)
return script.Bytes(), nil
}

View file

@ -4,6 +4,7 @@ import (
"fmt"
"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/io"
"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.Opcode(buf.BinWriter, opcode.PUSHNULL)
emit.Syscall(buf.BinWriter, "Neo.Crypto.CheckMultisigWithECDsaSecp256r1")
emit.Syscall(buf.BinWriter, interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1)
return buf.Bytes(), nil
}

View file

@ -3,9 +3,9 @@ package smartcontract
import (
"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/io"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
"github.com/stretchr/testify/assert"
"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.PUSHNULL, 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) {

View file

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

View file

@ -1,13 +1,13 @@
package emit
import (
"crypto/sha256"
"encoding/binary"
"errors"
"fmt"
"math/big"
"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/io"
"github.com/nspcc-dev/neo-go/pkg/util"
@ -124,7 +124,7 @@ func Syscall(w *io.BinWriter, api string) {
return
}
buf := make([]byte, 4)
binary.LittleEndian.PutUint32(buf, InteropNameToID([]byte(api)))
binary.LittleEndian.PutUint32(buf, interopnames.ToID([]byte(api)))
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.
func AppCall(w *io.BinWriter, scriptHash util.Uint160) {
Bytes(w, scriptHash.BytesBE())
Syscall(w, "System.Contract.Call")
Syscall(w, interopnames.SystemContractCall)
}
// 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 {
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"
"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/io"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
@ -190,8 +191,8 @@ func TestEmitString(t *testing.T) {
func TestEmitSyscall(t *testing.T) {
syscalls := []string{
"System.Runtime.Log",
"System.Runtime.Notify",
interopnames.SystemRuntimeLog,
interopnames.SystemRuntimeNotify,
"System.Runtime.Whatever",
}
@ -201,7 +202,7 @@ func TestEmitSyscall(t *testing.T) {
result := buf.Bytes()
assert.Equal(t, 5, len(result))
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()
}

View file

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

View file

@ -13,6 +13,7 @@ import (
"text/tabwriter"
"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/encoding/bigint"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
@ -191,10 +192,23 @@ func (v *VM) PrintOps() {
v.getOffsetDesc(ctx, catchP), v.getOffsetDesc(ctx, finallyP))
case opcode.INITSSLOT:
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:
desc = fmt.Sprintf("%d local, %d arg", parameter[0], parameter[1])
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:
if utf8.Valid(parameter) {
desc = fmt.Sprintf("%x (%q)", parameter, parameter)

View file

@ -11,6 +11,7 @@ import (
"math/rand"
"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/internal/random"
"github.com/nspcc-dev/neo-go/pkg/io"
@ -23,7 +24,7 @@ import (
)
func fooInteropHandler(v *VM, id uint32) error {
if id == emit.InteropNameToID([]byte("foo")) {
if id == interopnames.ToID([]byte("foo")) {
if !v.AddGas(1) {
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) {
return func(t *testing.T) {
prog := []byte{byte(opcode.CONVERT), byte(to)}
v := load(prog)
v.PrintOps()
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)}
for i := 0; i < n; i++ {
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, getSyscallProg("System.Enumerator.Value")...)
prog = append(prog, getSyscallProg(interopnames.SystemEnumeratorValue)...)
if isIter {
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, getSyscallProg("System.Enumerator.Next")...)
prog = append(prog, getSyscallProg(interopnames.SystemEnumeratorNext)...)
return
}
@ -592,8 +595,8 @@ func TestIteratorConcat(t *testing.T) {
}
func TestIteratorKeys(t *testing.T) {
prog := getSyscallProg("System.Iterator.Create")
prog = append(prog, getSyscallProg("System.Iterator.Keys")...)
prog := getSyscallProg(interopnames.SystemIteratorCreate)
prog = append(prog, getSyscallProg(interopnames.SystemIteratorKeys)...)
prog = append(prog, getEnumeratorProg(2, false)...)
v := load(prog)
@ -612,8 +615,8 @@ func TestIteratorKeys(t *testing.T) {
}
func TestIteratorValues(t *testing.T) {
prog := getSyscallProg("System.Iterator.Create")
prog = append(prog, getSyscallProg("System.Iterator.Values")...)
prog := getSyscallProg(interopnames.SystemIteratorCreate)
prog = append(prog, getSyscallProg(interopnames.SystemIteratorValues)...)
prog = append(prog, getEnumeratorProg(2, false)...)
v := load(prog)
@ -646,8 +649,8 @@ func getSyscallProg(name string) (prog []byte) {
}
func getSerializeProg() (prog []byte) {
prog = append(prog, getSyscallProg("System.Binary.Serialize")...)
prog = append(prog, getSyscallProg("System.Binary.Deserialize")...)
prog = append(prog, getSyscallProg(interopnames.SystemBinarySerialize)...)
prog = append(prog, getSyscallProg(interopnames.SystemBinaryDeserialize)...)
prog = append(prog, byte(opcode.RET))
return
@ -752,7 +755,7 @@ func TestSerializeStruct(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)))
require.NoError(t, err)
@ -788,7 +791,7 @@ func TestSerializeMapCompat(t *testing.T) {
emit.Bytes(buf.BinWriter, []byte("key"))
emit.Bytes(buf.BinWriter, []byte("value"))
emit.Opcode(buf.BinWriter, opcode.SETITEM)
emit.Syscall(buf.BinWriter, "System.Binary.Serialize")
emit.Syscall(buf.BinWriter, interopnames.SystemBinarySerialize)
require.NoError(t, buf.Err)
vm := load(buf.Bytes())