From cee1836183581c7dc534065eed2aa3baf1fa607b Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 28 Aug 2020 10:47:15 +0300 Subject: [PATCH 1/4] interop: provide missing smartcontract parameter type defs Contract can have Hash160, Hash256, Signature etc. types which all map to a `[]byte` in Go. Having synonyms helps us to generate proper manifest file. --- examples/token/token.go | 5 +++-- pkg/interop/blockchain/blockchain.go | 25 ++++++++++++++----------- pkg/interop/contract/contract.go | 6 ++++-- pkg/interop/crypto/crypto.go | 14 ++++++++------ pkg/interop/doc.go | 14 +++++++++++++- pkg/interop/engine/engine.go | 4 +++- pkg/interop/runtime/engine.go | 11 +++++++---- pkg/interop/runtime/runtime.go | 4 +++- pkg/interop/types.go | 17 +++++++++++++++++ pkg/interop/util/util.go | 4 +++- 10 files changed, 75 insertions(+), 29 deletions(-) create mode 100644 pkg/interop/types.go diff --git a/examples/token/token.go b/examples/token/token.go index 0925b4fd1..09107d702 100644 --- a/examples/token/token.go +++ b/examples/token/token.go @@ -2,6 +2,7 @@ package tokencontract import ( "github.com/nspcc-dev/neo-go/examples/token/nep5" + "github.com/nspcc-dev/neo-go/pkg/interop" "github.com/nspcc-dev/neo-go/pkg/interop/storage" "github.com/nspcc-dev/neo-go/pkg/interop/util" ) @@ -52,12 +53,12 @@ func TotalSupply() int { } // BalanceOf returns the amount of token on the specified address -func BalanceOf(holder []byte) interface{} { +func BalanceOf(holder interop.Hash160) interface{} { return token.BalanceOf(ctx, holder) } // Transfer token from one user to another -func Transfer(from []byte, to []byte, amount int) bool { +func Transfer(from interop.Hash160, to interop.Hash160, amount int) bool { return token.Transfer(ctx, from, to, amount) } diff --git a/pkg/interop/blockchain/blockchain.go b/pkg/interop/blockchain/blockchain.go index e01aaf9ac..caae68845 100644 --- a/pkg/interop/blockchain/blockchain.go +++ b/pkg/interop/blockchain/blockchain.go @@ -3,21 +3,24 @@ Package blockchain provides functions to access various blockchain data. */ package blockchain -import "github.com/nspcc-dev/neo-go/pkg/interop/contract" +import ( + "github.com/nspcc-dev/neo-go/pkg/interop" + "github.com/nspcc-dev/neo-go/pkg/interop/contract" +) // Transaction represents a NEO transaction. It's similar to Transaction class // in Neo .net framework. type Transaction struct { // Hash represents the hash (256 bit BE value in a 32 byte slice) of the // given transaction (which also is its ID). - Hash []byte + Hash interop.Hash256 // Version represents the transaction version. Version int // Nonce is a random number to avoid hash collision. Nonce int // Sender represents the sender (160 bit BE value in a 20 byte slice) of the // given Transaction. - Sender []byte + Sender interop.Hash160 // SysFee represents fee to be burned. SysFee int // NetFee represents fee to be distributed to consensus nodes. @@ -35,22 +38,22 @@ type Transaction struct { type Block struct { // Hash represents the hash (256 bit BE value in a 32 byte slice) of the // given block. - Hash []byte + Hash interop.Hash256 // Version of the block. Version int // PrevHash represents the hash (256 bit BE value in a 32 byte slice) of the // previous block. - PrevHash []byte + PrevHash interop.Hash256 // MerkleRoot represents the root hash (256 bit BE value in a 32 byte slice) // of a transaction list. - MerkleRoot []byte + MerkleRoot interop.Hash256 // Timestamp represents millisecond-precision block timestamp. Timestamp int // Index represents the height of the block. Index int // NextConsensus represents contract address of the next miner (160 bit BE // value in a 20 byte slice). - NextConsensus []byte + NextConsensus interop.Hash160 // TransactionsLength represents the length of block's transactions array. TransactionsLength int } @@ -74,7 +77,7 @@ func GetBlock(heightOrHash interface{}) Block { // GetTransaction returns transaction found by the given hash (256 bit in BE // format represented as a slice of 32 bytes). This function uses // `System.Blockchain.GetTransaction` syscall. -func GetTransaction(hash []byte) Transaction { +func GetTransaction(hash interop.Hash256) Transaction { return Transaction{} } @@ -82,14 +85,14 @@ func GetTransaction(hash []byte) Transaction { // represented as a slice of 32 bytes) from the block found by the given hash or // index (with the same encoding as for GetHeader) by its index. This // function uses `System.Blockchain.GetTransactionFromBlock` syscall. -func GetTransactionFromBlock(heightOrHash interface{}, index int) []byte { +func GetTransactionFromBlock(heightOrHash interface{}, index int) interop.Hash256 { return nil } // GetTransactionHeight returns transaction's height (index of the block that // includes it) by the given ID (256 bit in BE format represented as a slice of // 32 bytes). This function uses `System.Blockchain.GetTransactionHeight` syscall. -func GetTransactionHeight(hash []byte) int { +func GetTransactionHeight(hash interop.Hash256) int { return 0 } @@ -97,6 +100,6 @@ func GetTransactionHeight(hash []byte) int { // format represented as a slice of 20 bytes). Refer to the `contract` package // for details on how to use the returned structure. This function uses // `System.Blockchain.GetContract` syscall. -func GetContract(scriptHash []byte) contract.Contract { +func GetContract(scriptHash interop.Hash160) contract.Contract { return contract.Contract{} } diff --git a/pkg/interop/contract/contract.go b/pkg/interop/contract/contract.go index 4e237f6d9..4b2aa9b08 100644 --- a/pkg/interop/contract/contract.go +++ b/pkg/interop/contract/contract.go @@ -3,6 +3,8 @@ Package contract provides functions to work with contracts. */ package contract +import "github.com/nspcc-dev/neo-go/pkg/interop" + // Contract represents a Neo contract and is used in interop functions. It's // a data structure that you can manipulate with using functions from // this package. It's similar in function to the Contract class in the Neo .net @@ -40,13 +42,13 @@ func Destroy() {} // IsStandard checks if contract with provided hash is a standard signature/multisig contract. // This function uses `System.Contract.IsStandard` syscall. -func IsStandard(h []byte) bool { +func IsStandard(h interop.Hash160) bool { return false } // CreateStandardAccount calculates script hash of a given public key. // This function uses `System.Contract.CreateStandardAccount` syscall. -func CreateStandardAccount(pub []byte) []byte { +func CreateStandardAccount(pub interop.PublicKey) []byte { return nil } diff --git a/pkg/interop/crypto/crypto.go b/pkg/interop/crypto/crypto.go index 4f986f128..84d1b2a99 100644 --- a/pkg/interop/crypto/crypto.go +++ b/pkg/interop/crypto/crypto.go @@ -3,36 +3,38 @@ Package crypto provides an interface to cryptographic syscalls. */ package crypto +import "github.com/nspcc-dev/neo-go/pkg/interop" + // SHA256 computes SHA256 hash of b. It uses `Neo.Crypto.SHA256` syscall. -func SHA256(b []byte) []byte { +func SHA256(b []byte) interop.Hash256 { return nil } // RIPEMD160 computes RIPEMD160 hash of b. It uses `Neo.Crypto.RIPEMD160` syscall. -func RIPEMD160(b []byte) []byte { +func RIPEMD160(b []byte) interop.Hash160 { return nil } // ECDsaSecp256r1Verify checks that sig is correct msg's signature for a given pub // (serialized public key). It uses `Neo.Crypto.VerifyWithECDsaSecp256r1` syscall. -func ECDsaSecp256r1Verify(msg []byte, pub []byte, sig []byte) bool { +func ECDsaSecp256r1Verify(msg []byte, pub interop.PublicKey, sig interop.Signature) bool { return false } // ECDsaSecp256k1Verify checks that sig is correct msg's signature for a given pub // (serialized public key). It uses `Neo.Crypto.VerifyWithECDsaSecp256k1` syscall. -func ECDsaSecp256k1Verify(msg []byte, pub []byte, sig []byte) bool { +func ECDsaSecp256k1Verify(msg []byte, pub interop.PublicKey, sig interop.Signature) bool { return false } // ECDSASecp256r1CheckMultisig checks multiple ECDSA signatures at once. It uses // `Neo.Crypto.CheckMultisigWithECDsaSecp256r1` syscall. -func ECDSASecp256r1CheckMultisig(msg []byte, pubs [][]byte, sigs [][]byte) bool { +func ECDSASecp256r1CheckMultisig(msg []byte, pubs []interop.PublicKey, sigs []interop.Signature) bool { return false } // ECDSASecp256k1CheckMultisig checks multiple ECDSA signatures at once. It uses // `Neo.Crypto.CheckMultisigWithECDsaSecp256k1` syscall. -func ECDSASecp256k1CheckMultisig(msg []byte, pubs [][]byte, sigs [][]byte) bool { +func ECDSASecp256k1CheckMultisig(msg []byte, pubs []interop.PublicKey, sigs []interop.Signature) bool { return false } diff --git a/pkg/interop/doc.go b/pkg/interop/doc.go index 56ddc3081..8031b775a 100644 --- a/pkg/interop/doc.go +++ b/pkg/interop/doc.go @@ -1,11 +1,23 @@ /* -Package interop contains smart contract API functions. +Package interop contains smart contract API functions and type synonyms. Its subpackages can be imported into smart contracts written in Go to provide various functionality. Upon compilation, functions from these packages will be substituted with appropriate NeoVM system calls implemented by Neo. Usually these system calls have additional price in NeoVM, so they're explicitly written in the documentation of respective functions. +Types defined here are used for proper manifest generation. Here is how Go types +correspond to smartcontract and VM types: + int-like - Integer + bool - Boolean + []byte - ByteArray (Buffer in VM) + string - String (ByteString in VM) + (interface{})(nil) - Any + non-byte slice - Array + map[K]V - map +Other types are defined explicitly in this pkg: + Hash160, Hash256, InteropInterface, PublicKey, Signature + Note that unless written otherwise structures defined in this packages can't be correctly created by new() or composite literals, they should be received from some interop functions (and then used as parameters for some other interop diff --git a/pkg/interop/engine/engine.go b/pkg/interop/engine/engine.go index 5cd16ac1e..353044c15 100644 --- a/pkg/interop/engine/engine.go +++ b/pkg/interop/engine/engine.go @@ -5,10 +5,12 @@ framework. */ package engine +import "github.com/nspcc-dev/neo-go/pkg/interop" + // AppCall executes previously deployed blockchain contract with specified hash // (160 bit in BE form represented as 20-byte slice) using provided arguments. // It returns whatever this contract returns. This function uses // `System.Contract.Call` syscall. -func AppCall(scriptHash []byte, method string, args ...interface{}) interface{} { +func AppCall(scriptHash interop.Hash160, method string, args ...interface{}) interface{} { return nil } diff --git a/pkg/interop/runtime/engine.go b/pkg/interop/runtime/engine.go index c71173c1b..011001807 100644 --- a/pkg/interop/runtime/engine.go +++ b/pkg/interop/runtime/engine.go @@ -1,6 +1,9 @@ package runtime -import "github.com/nspcc-dev/neo-go/pkg/interop/blockchain" +import ( + "github.com/nspcc-dev/neo-go/pkg/interop" + "github.com/nspcc-dev/neo-go/pkg/interop/blockchain" +) // GetScriptContainer returns the transaction that initially triggered current // execution context. It never changes in a single execution, no matter how deep @@ -15,7 +18,7 @@ func GetScriptContainer() blockchain.Transaction { // AppCall can change the value returned by this function if it calls a // different contract. This function uses // `System.Runtime.GetExecutingScriptHash` syscall. -func GetExecutingScriptHash() []byte { +func GetExecutingScriptHash() interop.Hash160 { return nil } @@ -24,7 +27,7 @@ func GetExecutingScriptHash() []byte { // running context (caller of current contract or function), so it's one level // above the GetExecutingScriptHash in the call stack. It uses // `System.Runtime.GetCallingScriptHash` syscall. -func GetCallingScriptHash() []byte { +func GetCallingScriptHash() interop.Hash160 { return nil } @@ -33,6 +36,6 @@ func GetCallingScriptHash() []byte { // (this is a script that is contained in a transaction returned by // GetScriptContainer) execution from the start. This function uses // `System.Runtime.GetEntryScriptHash` syscall. -func GetEntryScriptHash() []byte { +func GetEntryScriptHash() interop.Hash160 { return nil } diff --git a/pkg/interop/runtime/runtime.go b/pkg/interop/runtime/runtime.go index b91d2d2c3..98cc0561b 100644 --- a/pkg/interop/runtime/runtime.go +++ b/pkg/interop/runtime/runtime.go @@ -4,6 +4,8 @@ It has similar function to Runtime class in .net framwork for Neo. */ package runtime +import "github.com/nspcc-dev/neo-go/pkg/interop" + // Trigger values to compare with GetTrigger result. const ( System byte = 0x01 @@ -60,7 +62,7 @@ func GasLeft() int64 { // 'nil' literal means no filtering. It returns slice consisting of following elements: // [ scripthash of notification's contract , emitted item ]. // This function uses `System.Runtime.GetNotifications` syscall. -func GetNotifications(h []byte) [][]interface{} { +func GetNotifications(h interop.Hash160) [][]interface{} { return nil } diff --git a/pkg/interop/types.go b/pkg/interop/types.go new file mode 100644 index 000000000..f6ae0b11e --- /dev/null +++ b/pkg/interop/types.go @@ -0,0 +1,17 @@ +package interop + +// Signature represents 64-byte signature. +type Signature []byte + +// Hash160 represents 20-byte hash. +type Hash160 []byte + +// Hash256 represents 32-byte hash. +type Hash256 []byte + +// PublicKey represents marshalled ecdsa public key. +type PublicKey []byte + +// Interface represents interop interface type which is needed for +// transparent handling of VM-internal types (e.g. storage.Context) +type Interface interface{} diff --git a/pkg/interop/util/util.go b/pkg/interop/util/util.go index 3e80a77b0..a47473cb0 100644 --- a/pkg/interop/util/util.go +++ b/pkg/interop/util/util.go @@ -3,11 +3,13 @@ Package util contains some special useful functions that are provided by compile */ package util +import "github.com/nspcc-dev/neo-go/pkg/interop" + // FromAddress is an utility function that converts a Neo address to its hash // (160 bit BE value in a 20 byte slice). It can only be used for strings known // at compilation time, because the conversion is actually being done by the // compiler. -func FromAddress(address string) []byte { +func FromAddress(address string) interop.Hash160 { return nil } From 25f8545cdf692132bafe7591eebbc935fa856437 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 28 Aug 2020 11:08:04 +0300 Subject: [PATCH 2/4] compiler: extend manifest generation with custom types --- pkg/compiler/debug.go | 15 +++++++++++++++ pkg/compiler/debug_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/pkg/compiler/debug.go b/pkg/compiler/debug.go index e4ef96e3d..4fd9a2b59 100644 --- a/pkg/compiler/debug.go +++ b/pkg/compiler/debug.go @@ -201,6 +201,21 @@ func (c *codegen) scTypeFromExpr(typ ast.Expr) string { if c.typeOf(typ) == nil { return "Any" } + if named, ok := t.(*types.Named); ok { + if isInteropPath(named.String()) { + name := named.Obj().Name() + pkg := named.Obj().Pkg().Name() + switch pkg { + case "blockchain", "contract": + return "Array" // Block, Transaction, Contract + case "interop": + if name != "Interface" { + return name + } + } + return "InteropInterface" + } + } switch t := t.Underlying().(type) { case *types.Basic: info := t.Info() diff --git a/pkg/compiler/debug_test.go b/pkg/compiler/debug_test.go index 6223e59e4..d795a05e8 100644 --- a/pkg/compiler/debug_test.go +++ b/pkg/compiler/debug_test.go @@ -15,6 +15,10 @@ import ( func TestCodeGen_DebugInfo(t *testing.T) { src := `package foo + import "github.com/nspcc-dev/neo-go/pkg/interop" + import "github.com/nspcc-dev/neo-go/pkg/interop/storage" + import "github.com/nspcc-dev/neo-go/pkg/interop/blockchain" + import "github.com/nspcc-dev/neo-go/pkg/interop/contract" func Main(op string) bool { var s string _ = s @@ -42,6 +46,12 @@ func MethodByteArray() []byte { return nil } func MethodArray() []bool { return nil } func MethodStruct() struct{} { return struct{}{} } func unexportedMethod() int { return 1 } +func MethodParams(addr interop.Hash160, h interop.Hash256, + sig interop.Signature, pub interop.PublicKey, + inter interop.Interface, ctr contract.Contract, + ctx storage.Context, tx blockchain.Transaction) bool { + return true +} type MyStruct struct {} func (ms MyStruct) MethodOnStruct() { } func (ms *MyStruct) MethodOnPointerToStruct() { } @@ -72,6 +82,7 @@ func (ms *MyStruct) MethodOnPointerToStruct() { } "unexportedMethod": "Integer", "MethodOnStruct": "Void", "MethodOnPointerToStruct": "Void", + "MethodParams": "Boolean", } for i := range d.Methods { name := d.Methods[i].ID @@ -201,6 +212,21 @@ func (ms *MyStruct) MethodOnPointerToStruct() { } }, ReturnType: smartcontract.StringType, }, + { + Name: "methodParams", + Offset: 125, + Parameters: []manifest.Parameter{ + manifest.NewParameter("addr", smartcontract.Hash160Type), + manifest.NewParameter("h", smartcontract.Hash256Type), + manifest.NewParameter("sig", smartcontract.SignatureType), + manifest.NewParameter("pub", smartcontract.PublicKeyType), + manifest.NewParameter("inter", smartcontract.InteropInterfaceType), + manifest.NewParameter("ctr", smartcontract.ArrayType), + manifest.NewParameter("ctx", smartcontract.InteropInterfaceType), + manifest.NewParameter("tx", smartcontract.ArrayType), + }, + ReturnType: smartcontract.BoolType, + }, }, Events: []manifest.Event{}, }, From 37f7363386789ba59a846bb5fe650308423456c9 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Tue, 8 Sep 2020 13:41:47 +0300 Subject: [PATCH 3/4] interop: return struct pointers where needed `Transaction`, `Block` and `Contract` are represented as `Array`s in VM, so we must return pointers. Revert a1f98f92. --- pkg/compiler/codegen.go | 5 +- pkg/compiler/syscall.go | 126 +++++++++++++-------------- pkg/interop/blockchain/blockchain.go | 12 +-- pkg/interop/contract/contract.go | 4 +- pkg/interop/runtime/engine.go | 4 +- 5 files changed, 71 insertions(+), 80 deletions(-) diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index be9e8ec2c..2d8778524 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -1392,10 +1392,7 @@ func (c *codegen) convertSyscall(expr *ast.CallExpr, api, name string) { c.prog.Err = fmt.Errorf("unknown VM syscall api: %s.%s", api, name) return } - emit.Syscall(c.prog.BinWriter, syscall.API) - if syscall.ConvertResultToStruct { - c.emitConvert(stackitem.StructT) - } + emit.Syscall(c.prog.BinWriter, syscall) // This NOP instruction is basically not needed, but if we do, we have a // one to one matching avm file with neo-python which is very nice for debugging. diff --git a/pkg/compiler/syscall.go b/pkg/compiler/syscall.go index f1c6ed792..d69952f4d 100644 --- a/pkg/compiler/syscall.go +++ b/pkg/compiler/syscall.go @@ -2,91 +2,85 @@ 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 - ConvertResultToStruct bool -} - // All lists are sorted, keep 'em this way, please. -var syscalls = map[string]map[string]Syscall{ +var syscalls = map[string]map[string]string{ "binary": { - "Base58Decode": {interopnames.SystemBinaryBase58Decode, false}, - "Base58Encode": {interopnames.SystemBinaryBase58Encode, false}, - "Base64Decode": {interopnames.SystemBinaryBase64Decode, false}, - "Base64Encode": {interopnames.SystemBinaryBase64Encode, false}, - "Deserialize": {interopnames.SystemBinaryDeserialize, false}, - "Serialize": {interopnames.SystemBinarySerialize, false}, + "Base58Decode": interopnames.SystemBinaryBase58Decode, + "Base58Encode": interopnames.SystemBinaryBase58Encode, + "Base64Decode": interopnames.SystemBinaryBase64Decode, + "Base64Encode": interopnames.SystemBinaryBase64Encode, + "Deserialize": interopnames.SystemBinaryDeserialize, + "Serialize": interopnames.SystemBinarySerialize, }, "blockchain": { - "GetBlock": {interopnames.SystemBlockchainGetBlock, true}, - "GetContract": {interopnames.SystemBlockchainGetContract, true}, - "GetHeight": {interopnames.SystemBlockchainGetHeight, false}, - "GetTransaction": {interopnames.SystemBlockchainGetTransaction, true}, - "GetTransactionFromBlock": {interopnames.SystemBlockchainGetTransactionFromBlock, false}, - "GetTransactionHeight": {interopnames.SystemBlockchainGetTransactionHeight, false}, + "GetBlock": interopnames.SystemBlockchainGetBlock, + "GetContract": interopnames.SystemBlockchainGetContract, + "GetHeight": interopnames.SystemBlockchainGetHeight, + "GetTransaction": interopnames.SystemBlockchainGetTransaction, + "GetTransactionFromBlock": interopnames.SystemBlockchainGetTransactionFromBlock, + "GetTransactionHeight": interopnames.SystemBlockchainGetTransactionHeight, }, "contract": { - "Create": {interopnames.SystemContractCreate, true}, - "CreateStandardAccount": {interopnames.SystemContractCreateStandardAccount, false}, - "Destroy": {interopnames.SystemContractDestroy, false}, - "IsStandard": {interopnames.SystemContractIsStandard, false}, - "GetCallFlags": {interopnames.SystemContractGetCallFlags, false}, - "Update": {interopnames.SystemContractUpdate, false}, + "Create": interopnames.SystemContractCreate, + "CreateStandardAccount": interopnames.SystemContractCreateStandardAccount, + "Destroy": interopnames.SystemContractDestroy, + "IsStandard": interopnames.SystemContractIsStandard, + "GetCallFlags": interopnames.SystemContractGetCallFlags, + "Update": interopnames.SystemContractUpdate, }, "crypto": { - "ECDsaSecp256k1Verify": {interopnames.NeoCryptoVerifyWithECDsaSecp256k1, false}, - "ECDSASecp256k1CheckMultisig": {interopnames.NeoCryptoCheckMultisigWithECDsaSecp256k1, false}, - "ECDsaSecp256r1Verify": {interopnames.NeoCryptoVerifyWithECDsaSecp256r1, false}, - "ECDSASecp256r1CheckMultisig": {interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1, false}, - "RIPEMD160": {interopnames.NeoCryptoRIPEMD160, false}, - "SHA256": {interopnames.NeoCryptoSHA256, false}, + "ECDsaSecp256k1Verify": interopnames.NeoCryptoVerifyWithECDsaSecp256k1, + "ECDSASecp256k1CheckMultisig": interopnames.NeoCryptoCheckMultisigWithECDsaSecp256k1, + "ECDsaSecp256r1Verify": interopnames.NeoCryptoVerifyWithECDsaSecp256r1, + "ECDSASecp256r1CheckMultisig": interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1, + "RIPEMD160": interopnames.NeoCryptoRIPEMD160, + "SHA256": interopnames.NeoCryptoSHA256, }, "enumerator": { - "Concat": {interopnames.SystemEnumeratorConcat, false}, - "Create": {interopnames.SystemEnumeratorCreate, false}, - "Next": {interopnames.SystemEnumeratorNext, false}, - "Value": {interopnames.SystemEnumeratorValue, false}, + "Concat": interopnames.SystemEnumeratorConcat, + "Create": interopnames.SystemEnumeratorCreate, + "Next": interopnames.SystemEnumeratorNext, + "Value": interopnames.SystemEnumeratorValue, }, "engine": { - "AppCall": {interopnames.SystemContractCall, false}, + "AppCall": interopnames.SystemContractCall, }, "iterator": { - "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}, + "Concat": interopnames.SystemIteratorConcat, + "Create": interopnames.SystemIteratorCreate, + "Key": interopnames.SystemIteratorKey, + "Keys": interopnames.SystemIteratorKeys, + "Next": interopnames.SystemEnumeratorNext, + "Value": interopnames.SystemEnumeratorValue, + "Values": interopnames.SystemIteratorValues, }, "json": { - "Deserialize": {interopnames.SystemJSONDeserialize, false}, - "Serialize": {interopnames.SystemJSONSerialize, false}, + "Deserialize": interopnames.SystemJSONDeserialize, + "Serialize": interopnames.SystemJSONSerialize, }, "runtime": { - "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}, + "GasLeft": interopnames.SystemRuntimeGasLeft, + "GetInvocationCounter": interopnames.SystemRuntimeGetInvocationCounter, + "GetCallingScriptHash": interopnames.SystemRuntimeGetCallingScriptHash, + "GetEntryScriptHash": interopnames.SystemRuntimeGetEntryScriptHash, + "GetExecutingScriptHash": interopnames.SystemRuntimeGetExecutingScriptHash, + "GetNotifications": interopnames.SystemRuntimeGetNotifications, + "GetScriptContainer": interopnames.SystemRuntimeGetScriptContainer, + "GetTime": interopnames.SystemRuntimeGetTime, + "GetTrigger": interopnames.SystemRuntimeGetTrigger, + "CheckWitness": interopnames.SystemRuntimeCheckWitness, + "Log": interopnames.SystemRuntimeLog, + "Notify": interopnames.SystemRuntimeNotify, + "Platform": interopnames.SystemRuntimePlatform, }, "storage": { - "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}, + "ConvertContextToReadOnly": interopnames.SystemStorageAsReadOnly, + "Delete": interopnames.SystemStorageDelete, + "Find": interopnames.SystemStorageFind, + "Get": interopnames.SystemStorageGet, + "GetContext": interopnames.SystemStorageGetContext, + "GetReadOnlyContext": interopnames.SystemStorageGetReadOnlyContext, + "Put": interopnames.SystemStoragePut, + "PutEx": interopnames.SystemStoragePutEx, }, } diff --git a/pkg/interop/blockchain/blockchain.go b/pkg/interop/blockchain/blockchain.go index caae68845..a8d8e1659 100644 --- a/pkg/interop/blockchain/blockchain.go +++ b/pkg/interop/blockchain/blockchain.go @@ -70,15 +70,15 @@ func GetHeight() int { // GetBlock returns block found by the given hash or index (with the same // encoding as for GetHeader). This function uses `System.Blockchain.GetBlock` // syscall. -func GetBlock(heightOrHash interface{}) Block { - return Block{} +func GetBlock(heightOrHash interface{}) *Block { + return &Block{} } // GetTransaction returns transaction found by the given hash (256 bit in BE // format represented as a slice of 32 bytes). This function uses // `System.Blockchain.GetTransaction` syscall. -func GetTransaction(hash interop.Hash256) Transaction { - return Transaction{} +func GetTransaction(hash interop.Hash256) *Transaction { + return &Transaction{} } // GetTransactionFromBlock returns transaction hash (256 bit in BE format @@ -100,6 +100,6 @@ func GetTransactionHeight(hash interop.Hash256) int { // format represented as a slice of 20 bytes). Refer to the `contract` package // for details on how to use the returned structure. This function uses // `System.Blockchain.GetContract` syscall. -func GetContract(scriptHash interop.Hash160) contract.Contract { - return contract.Contract{} +func GetContract(scriptHash interop.Hash160) *contract.Contract { + return &contract.Contract{} } diff --git a/pkg/interop/contract/contract.go b/pkg/interop/contract/contract.go index 4b2aa9b08..30930a08a 100644 --- a/pkg/interop/contract/contract.go +++ b/pkg/interop/contract/contract.go @@ -21,8 +21,8 @@ type Contract struct { // manifest contract's manifest (limited in length by 2 KiB) // It returns this new created Contract when successful (and fails transaction // if not). It uses `System.Contract.Create` syscall. -func Create(script []byte, manifest []byte) Contract { - return Contract{} +func Create(script []byte, manifest []byte) *Contract { + return &Contract{} } // Update updates script and manifest of the calling contract (that is the one that calls Update) diff --git a/pkg/interop/runtime/engine.go b/pkg/interop/runtime/engine.go index 011001807..64e0b7b66 100644 --- a/pkg/interop/runtime/engine.go +++ b/pkg/interop/runtime/engine.go @@ -9,8 +9,8 @@ import ( // execution context. It never changes in a single execution, no matter how deep // this execution goes. This function uses // `System.Runtime.GetScriptContainer` syscall. -func GetScriptContainer() blockchain.Transaction { - return blockchain.Transaction{} +func GetScriptContainer() *blockchain.Transaction { + return &blockchain.Transaction{} } // GetExecutingScriptHash returns script hash (160 bit in BE form represented From b319f127e7df01bde560844d6d5a388f92788dcf Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Tue, 8 Sep 2020 13:48:33 +0300 Subject: [PATCH 4/4] interop: make `Base*Encode` return string --- pkg/interop/binary/binary.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/interop/binary/binary.go b/pkg/interop/binary/binary.go index e6c1a0392..e5f834cfb 100644 --- a/pkg/interop/binary/binary.go +++ b/pkg/interop/binary/binary.go @@ -19,8 +19,8 @@ func Deserialize(b []byte) interface{} { // Base64Encode encodes given byte slice into a base64 string and returns byte // representation of this string. It uses `System.Binary.Base64Encode` interop. -func Base64Encode(b []byte) []byte { - return nil +func Base64Encode(b []byte) string { + return "" } // Base64Decode decodes given base64 string represented as a byte slice into @@ -31,8 +31,8 @@ func Base64Decode(b []byte) []byte { // Base58Encode encodes given byte slice into a base58 string and returns byte // representation of this string. It uses `System.Binary.Base58Encode` syscall. -func Base58Encode(b []byte) []byte { - return nil +func Base58Encode(b []byte) string { + return "" } // Base58Decode decodes given base58 string represented as a byte slice into