Merge pull request #1720 from nspcc-dev/compiler/syscall
Refactor syscall handing
This commit is contained in:
commit
46fbd940fe
13 changed files with 166 additions and 128 deletions
|
@ -277,8 +277,7 @@ func isSyscall(fun *funcScope) bool {
|
|||
if fun.selector == nil || fun.pkg == nil || !isInteropPath(fun.pkg.Path()) {
|
||||
return false
|
||||
}
|
||||
_, ok := syscalls[fun.pkg.Name()][fun.name]
|
||||
return ok
|
||||
return fun.pkg.Name() == "neogointernal" && strings.HasPrefix(fun.name, "Syscall")
|
||||
}
|
||||
|
||||
const interopPrefix = "github.com/nspcc-dev/neo-go/pkg/interop"
|
||||
|
@ -309,6 +308,13 @@ func canConvert(s string) bool {
|
|||
// Currently there is a static list of function which are inlined,
|
||||
// this may change in future.
|
||||
func canInline(s string) bool {
|
||||
return isNativeHelpersPath(s) ||
|
||||
strings.HasPrefix(s, "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline")
|
||||
if strings.HasPrefix(s, "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline") {
|
||||
return true
|
||||
}
|
||||
if !isInteropPath(s) {
|
||||
return false
|
||||
}
|
||||
return !strings.HasPrefix(s[len(interopPrefix):], "/neogointernal") &&
|
||||
!strings.HasPrefix(s[len(interopPrefix):], "/util") &&
|
||||
!strings.HasPrefix(s[len(interopPrefix):], "/convert")
|
||||
}
|
||||
|
|
|
@ -872,7 +872,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
|
||||
c.saveSequencePoint(n)
|
||||
|
||||
args := transformArgs(n.Fun, n.Args)
|
||||
args := transformArgs(f, n.Fun, n.Args)
|
||||
|
||||
// Handle the arguments
|
||||
for _, arg := range args {
|
||||
|
@ -888,7 +888,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
}
|
||||
}
|
||||
// Do not swap for builtin functions.
|
||||
if !isBuiltin {
|
||||
if !isBuiltin && (f != nil && !isSyscall(f)) {
|
||||
typ, ok := c.typeOf(n.Fun).(*types.Signature)
|
||||
if ok && typ.Variadic() && !n.Ellipsis.IsValid() {
|
||||
// pack variadic args into an array only if last argument is not of form `...`
|
||||
|
@ -932,7 +932,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
c.emittedEvents[name] = append(c.emittedEvents[name], params)
|
||||
}
|
||||
}
|
||||
c.convertSyscall(n, f.pkg.Name(), f.name)
|
||||
c.convertSyscall(n)
|
||||
default:
|
||||
emit.Call(c.prog.BinWriter, opcode.CALLL, f.label)
|
||||
}
|
||||
|
@ -1523,12 +1523,13 @@ func (c *codegen) getByteArray(expr ast.Expr) []byte {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *codegen) convertSyscall(expr *ast.CallExpr, api, name string) {
|
||||
syscall, ok := syscalls[api][name]
|
||||
if !ok {
|
||||
c.prog.Err = fmt.Errorf("unknown VM syscall api: %s.%s", api, name)
|
||||
return
|
||||
func (c *codegen) convertSyscall(expr *ast.CallExpr) {
|
||||
for _, arg := range expr.Args[1:] {
|
||||
ast.Walk(c, arg)
|
||||
}
|
||||
c.emitReverse(len(expr.Args) - 1)
|
||||
tv := c.typeAndValueOf(expr.Args[0])
|
||||
syscall := constant.StringVal(tv.Value)
|
||||
emit.Syscall(c.prog.BinWriter, syscall)
|
||||
|
||||
// This NOP instruction is basically not needed, but if we do, we have a
|
||||
|
@ -1714,12 +1715,15 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
|
|||
// so there is no need to push parameters on stack and perform an actual call
|
||||
// 2. With panic, generated code depends on if argument was nil or a string so
|
||||
// it should be handled accordingly.
|
||||
func transformArgs(fun ast.Expr, args []ast.Expr) []ast.Expr {
|
||||
func transformArgs(fs *funcScope, fun ast.Expr, args []ast.Expr) []ast.Expr {
|
||||
switch f := fun.(type) {
|
||||
case *ast.SelectorExpr:
|
||||
if f.Sel.Name == "FromAddress" {
|
||||
return args[1:]
|
||||
}
|
||||
if fs != nil && isSyscall(fs) {
|
||||
return nil
|
||||
}
|
||||
case *ast.Ident:
|
||||
switch f.Name {
|
||||
case "make", "copy", "append":
|
||||
|
|
|
@ -131,6 +131,11 @@ func (c *codegen) countLocalsInline(decl *ast.FuncDecl, pkg *types.Package, f *f
|
|||
return false
|
||||
}
|
||||
if inner, ok := c.funcs[name]; ok && canInline(name) {
|
||||
sig, ok := c.typeOf(n.Fun).(*types.Signature)
|
||||
if !ok {
|
||||
info := c.buildInfo.program.Package(pkg.Path())
|
||||
sig = info.Types[n.Fun].Type.(*types.Signature)
|
||||
}
|
||||
for i := range n.Args {
|
||||
switch n.Args[i].(type) {
|
||||
case *ast.Ident:
|
||||
|
@ -139,6 +144,10 @@ func (c *codegen) countLocalsInline(decl *ast.FuncDecl, pkg *types.Package, f *f
|
|||
size++
|
||||
}
|
||||
}
|
||||
// Variadic with direct var args.
|
||||
if sig.Variadic() && !n.Ellipsis.IsValid() {
|
||||
size++
|
||||
}
|
||||
innerSz, _ := c.countLocalsInline(inner.decl, inner.pkg, inner)
|
||||
size += innerSz
|
||||
}
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
package compiler
|
||||
|
||||
import "github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
|
||||
|
||||
// All lists are sorted, keep 'em this way, please.
|
||||
var syscalls = map[string]map[string]string{
|
||||
"binary": {
|
||||
"Atoi": interopnames.SystemBinaryAtoi,
|
||||
"Base58Decode": interopnames.SystemBinaryBase58Decode,
|
||||
"Base58Encode": interopnames.SystemBinaryBase58Encode,
|
||||
"Base64Decode": interopnames.SystemBinaryBase64Decode,
|
||||
"Base64Encode": interopnames.SystemBinaryBase64Encode,
|
||||
"Deserialize": interopnames.SystemBinaryDeserialize,
|
||||
"Itoa": interopnames.SystemBinaryItoa,
|
||||
"Serialize": interopnames.SystemBinarySerialize,
|
||||
},
|
||||
"contract": {
|
||||
"Call": interopnames.SystemContractCall,
|
||||
"CreateMultisigAccount": interopnames.SystemContractCreateMultisigAccount,
|
||||
"CreateStandardAccount": interopnames.SystemContractCreateStandardAccount,
|
||||
"IsStandard": interopnames.SystemContractIsStandard,
|
||||
"GetCallFlags": interopnames.SystemContractGetCallFlags,
|
||||
},
|
||||
"crypto": {
|
||||
"ECDsaSecp256k1Verify": interopnames.NeoCryptoVerifyWithECDsaSecp256k1,
|
||||
"ECDSASecp256k1CheckMultisig": interopnames.NeoCryptoCheckMultisigWithECDsaSecp256k1,
|
||||
"ECDsaSecp256r1Verify": interopnames.NeoCryptoVerifyWithECDsaSecp256r1,
|
||||
"ECDSASecp256r1CheckMultisig": interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1,
|
||||
"RIPEMD160": interopnames.NeoCryptoRIPEMD160,
|
||||
"SHA256": interopnames.NeoCryptoSHA256,
|
||||
},
|
||||
"iterator": {
|
||||
"Create": interopnames.SystemIteratorCreate,
|
||||
"Next": interopnames.SystemIteratorNext,
|
||||
"Value": interopnames.SystemIteratorValue,
|
||||
},
|
||||
"json": {
|
||||
"Deserialize": interopnames.SystemJSONDeserialize,
|
||||
"Serialize": interopnames.SystemJSONSerialize,
|
||||
},
|
||||
"runtime": {
|
||||
"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,
|
||||
"Delete": interopnames.SystemStorageDelete,
|
||||
"Find": interopnames.SystemStorageFind,
|
||||
"Get": interopnames.SystemStorageGet,
|
||||
"GetContext": interopnames.SystemStorageGetContext,
|
||||
"GetReadOnlyContext": interopnames.SystemStorageGetReadOnlyContext,
|
||||
"Put": interopnames.SystemStoragePut,
|
||||
"PutEx": interopnames.SystemStoragePutEx,
|
||||
},
|
||||
}
|
|
@ -3,52 +3,56 @@ Package binary provides binary serialization routines.
|
|||
*/
|
||||
package binary
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/neogointernal"
|
||||
)
|
||||
|
||||
// Serialize serializes any given item into a byte slice. It works for all
|
||||
// regular VM types (not ones from interop package) and allows to save them in
|
||||
// storage or pass into Notify and then Deserialize them on the next run or in
|
||||
// the external event receiver. It uses `System.Binary.Serialize` syscall.
|
||||
func Serialize(item interface{}) []byte {
|
||||
return nil
|
||||
return neogointernal.Syscall1("System.Binary.Serialize", item).([]byte)
|
||||
}
|
||||
|
||||
// Deserialize unpacks previously serialized value from a byte slice, it's the
|
||||
// opposite of Serialize. It uses `System.Binary.Deserialize` syscall.
|
||||
func Deserialize(b []byte) interface{} {
|
||||
return nil
|
||||
return neogointernal.Syscall1("System.Binary.Deserialize", b)
|
||||
}
|
||||
|
||||
// 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) string {
|
||||
return ""
|
||||
return neogointernal.Syscall1("System.Binary.Base64Encode", b).(string)
|
||||
}
|
||||
|
||||
// Base64Decode decodes given base64 string represented as a byte slice into
|
||||
// byte slice. It uses `System.Binary.Base64Decode` interop.
|
||||
func Base64Decode(b []byte) []byte {
|
||||
return nil
|
||||
return neogointernal.Syscall1("System.Binary.Base64Decode", b).([]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) string {
|
||||
return ""
|
||||
return neogointernal.Syscall1("System.Binary.Base58Encode", b).(string)
|
||||
}
|
||||
|
||||
// Base58Decode decodes given base58 string represented as a byte slice into
|
||||
// a new byte slice. It uses `System.Binary.Base58Decode` syscall.
|
||||
func Base58Decode(b []byte) []byte {
|
||||
return nil
|
||||
return neogointernal.Syscall1("System.Binary.Base64Decode", b).([]byte)
|
||||
}
|
||||
|
||||
// Itoa converts num in a given base to string. Base should be either 10 or 16.
|
||||
// It uses `System.Binary.Itoa` syscall.
|
||||
func Itoa(num int, base int) string {
|
||||
return ""
|
||||
return neogointernal.Syscall2("System.Binary.Itoa", num, base).(string)
|
||||
}
|
||||
|
||||
// Atoi converts string to a number in a given base. Base should be either 10 or 16.
|
||||
// It uses `System.Binary.Atoi` syscall.
|
||||
func Atoi(s string, base int) int {
|
||||
return 0
|
||||
return neogointernal.Syscall2("System.Binary.Atoi", s, base).(int)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,10 @@ Package contract provides functions to work with contracts.
|
|||
*/
|
||||
package contract
|
||||
|
||||
import "github.com/nspcc-dev/neo-go/pkg/interop"
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/neogointernal"
|
||||
)
|
||||
|
||||
// CallFlag specifies valid call flags.
|
||||
type CallFlag byte
|
||||
|
@ -24,26 +27,26 @@ const (
|
|||
// IsStandard checks if contract with provided hash is a standard signature/multisig contract.
|
||||
// This function uses `System.Contract.IsStandard` syscall.
|
||||
func IsStandard(h interop.Hash160) bool {
|
||||
return false
|
||||
return neogointernal.Syscall1("System.Contract.IsStandard", h).(bool)
|
||||
}
|
||||
|
||||
// CreateMultisigAccount calculates script hash of an m out of n multisignature
|
||||
// script using given m and a set of public keys bytes. This function uses
|
||||
// `System.Contract.CreateMultisigAccount` syscall.
|
||||
func CreateMultisigAccount(m int, pubs []interop.PublicKey) []byte {
|
||||
return nil
|
||||
return neogointernal.Syscall1("System.Contract.CreateMultisigAccount", pubs).([]byte)
|
||||
}
|
||||
|
||||
// CreateStandardAccount calculates script hash of a given public key.
|
||||
// This function uses `System.Contract.CreateStandardAccount` syscall.
|
||||
func CreateStandardAccount(pub interop.PublicKey) []byte {
|
||||
return nil
|
||||
return neogointernal.Syscall1("System.Contract.CreateStandardAccount", pub).([]byte)
|
||||
}
|
||||
|
||||
// GetCallFlags returns calling flags which execution context was created with.
|
||||
// This function uses `System.Contract.GetCallFlags` syscall.
|
||||
func GetCallFlags() int64 {
|
||||
return 0
|
||||
return neogointernal.Syscall0("System.Contract.GetFlags").(int64)
|
||||
}
|
||||
|
||||
// Call executes previously deployed blockchain contract with specified hash
|
||||
|
@ -51,5 +54,5 @@ func GetCallFlags() int64 {
|
|||
// It returns whatever this contract returns. This function uses
|
||||
// `System.Contract.Call` syscall.
|
||||
func Call(scriptHash interop.Hash160, method string, f CallFlag, args ...interface{}) interface{} {
|
||||
return nil
|
||||
return neogointernal.Syscall4("System.Contract.Call", scriptHash, method, f, args)
|
||||
}
|
||||
|
|
|
@ -3,38 +3,41 @@ Package crypto provides an interface to cryptographic syscalls.
|
|||
*/
|
||||
package crypto
|
||||
|
||||
import "github.com/nspcc-dev/neo-go/pkg/interop"
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/neogointernal"
|
||||
)
|
||||
|
||||
// SHA256 computes SHA256 hash of b. It uses `Neo.Crypto.SHA256` syscall.
|
||||
func SHA256(b []byte) interop.Hash256 {
|
||||
return nil
|
||||
return neogointernal.Syscall1("Neo.Crypto.SHA256", b).(interop.Hash256)
|
||||
}
|
||||
|
||||
// RIPEMD160 computes RIPEMD160 hash of b. It uses `Neo.Crypto.RIPEMD160` syscall.
|
||||
func RIPEMD160(b []byte) interop.Hash160 {
|
||||
return nil
|
||||
return neogointernal.Syscall1("Neo.Crypto.RIPEMD160", b).(interop.Hash160)
|
||||
}
|
||||
|
||||
// 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 interop.PublicKey, sig interop.Signature) bool {
|
||||
return false
|
||||
return neogointernal.Syscall3("Neo.Crypto.VerifyWithECDsaSecp256r1", msg, pub, sig).(bool)
|
||||
}
|
||||
|
||||
// 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 interop.PublicKey, sig interop.Signature) bool {
|
||||
return false
|
||||
return neogointernal.Syscall3("Neo.Crypto.VerifyWithECDsaSecp256k1", msg, pub, sig).(bool)
|
||||
}
|
||||
|
||||
// ECDSASecp256r1CheckMultisig checks multiple ECDSA signatures at once. It uses
|
||||
// `Neo.Crypto.CheckMultisigWithECDsaSecp256r1` syscall.
|
||||
func ECDSASecp256r1CheckMultisig(msg []byte, pubs []interop.PublicKey, sigs []interop.Signature) bool {
|
||||
return false
|
||||
return neogointernal.Syscall3("Neo.Crypto.CheckMultisigWithECDsaSecp256r1", msg, pubs, sigs).(bool)
|
||||
}
|
||||
|
||||
// ECDSASecp256k1CheckMultisig checks multiple ECDSA signatures at once. It uses
|
||||
// `Neo.Crypto.CheckMultisigWithECDsaSecp256k1` syscall.
|
||||
func ECDSASecp256k1CheckMultisig(msg []byte, pubs []interop.PublicKey, sigs []interop.Signature) bool {
|
||||
return false
|
||||
return neogointernal.Syscall3("Neo.Crypto.CheckMultisigWithECDsaSecp256k1", msg, pubs, sigs).(bool)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ Package iterator provides functions to work with Neo iterators.
|
|||
*/
|
||||
package iterator
|
||||
|
||||
import "github.com/nspcc-dev/neo-go/pkg/interop/neogointernal"
|
||||
|
||||
// Iterator represents a Neo iterator, it's an opaque data structure that can
|
||||
// be properly created by Create or storage.Find. Unlike enumerators, iterators
|
||||
// range over key-value pairs, so it's convenient to use them for maps. This
|
||||
|
@ -14,14 +16,14 @@ type Iterator struct{}
|
|||
// to point at element -1, so to access its first element you need to call Next
|
||||
// first. This function uses `System.Iterator.Create` syscall.
|
||||
func Create(items interface{}) Iterator {
|
||||
return Iterator{}
|
||||
return neogointernal.Syscall1("System.Iterator.Create", items).(Iterator)
|
||||
}
|
||||
|
||||
// Next advances the iterator returning true if it is was successful (and you
|
||||
// can use Key or Value) and false otherwise (and there are no more elements in
|
||||
// this Iterator). This function uses `System.Iterator.Next` syscall.
|
||||
func Next(it Iterator) bool {
|
||||
return true
|
||||
return neogointernal.Syscall1("System.Iterator.Next", it).(bool)
|
||||
}
|
||||
|
||||
// Value returns iterator's current value. It's only valid to call after
|
||||
|
@ -30,5 +32,5 @@ func Next(it Iterator) bool {
|
|||
// For maps the result can be casted to a slice of 2 elements: key and value.
|
||||
// For storage iterators refer to `storage.FindFlags` documentation.
|
||||
func Value(it Iterator) interface{} {
|
||||
return nil
|
||||
return neogointernal.Syscall1("System.Iterator.Value", it)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ Package json provides various JSON serialization/deserialization routines.
|
|||
*/
|
||||
package json
|
||||
|
||||
import "github.com/nspcc-dev/neo-go/pkg/interop/neogointernal"
|
||||
|
||||
// ToJSON serializes value to json. It uses `System.Json.Serialize` syscall.
|
||||
// Serialization format is the following:
|
||||
// []byte -> base64 string
|
||||
|
@ -13,7 +15,7 @@ package json
|
|||
// []interface{} -> json array
|
||||
// map[type1]type2 -> json object with string keys marshaled as strings (not base64).
|
||||
func ToJSON(item interface{}) []byte {
|
||||
return nil
|
||||
return neogointernal.Syscall1("System.Json.Serialize", item).([]byte)
|
||||
}
|
||||
|
||||
// FromJSON deserializes value from json. It uses `System.Json.Deserialize` syscall.
|
||||
|
@ -24,5 +26,5 @@ func ToJSON(item interface{}) []byte {
|
|||
// arrays -> []interface{}
|
||||
// maps -> map[string]interface{}
|
||||
func FromJSON(data []byte) interface{} {
|
||||
return nil
|
||||
return neogointernal.Syscall1("System.Json.Deserialize", data).(interface{})
|
||||
}
|
||||
|
|
46
pkg/interop/neogointernal/syscall.go
Normal file
46
pkg/interop/neogointernal/syscall.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
package neogointernal
|
||||
|
||||
// Syscall0 performs syscall with 0 arguments.
|
||||
func Syscall0(name string) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Syscall0NoReturn performs syscall with 0 arguments.
|
||||
func Syscall0NoReturn(name string) {
|
||||
}
|
||||
|
||||
// Syscall1 performs syscall with 1 arguments.
|
||||
func Syscall1(name string, arg interface{}) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Syscall1NoReturn performs syscall with 1 arguments.
|
||||
func Syscall1NoReturn(name string, arg interface{}) {
|
||||
}
|
||||
|
||||
// Syscall2 performs syscall with 2 arguments.
|
||||
func Syscall2(name string, arg1, arg2 interface{}) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Syscall2NoReturn performs syscall with 2 arguments.
|
||||
func Syscall2NoReturn(name string, arg1, arg2 interface{}) {
|
||||
}
|
||||
|
||||
// Syscall3 performs syscall with 3 arguments.
|
||||
func Syscall3(name string, arg1, arg2, arg3 interface{}) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Syscall3NoReturn performs syscall with 3 arguments.
|
||||
func Syscall3NoReturn(name string, arg1, arg2, arg3 interface{}) {
|
||||
}
|
||||
|
||||
// Syscall4 performs syscall with 4 arguments.
|
||||
func Syscall4(name string, arg1, arg2, arg3, arg4 interface{}) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Syscall4NoReturn performs syscall with 4 arguments.
|
||||
func Syscall4NoReturn(name string, arg1, arg2, arg3, arg4 interface{}) {
|
||||
}
|
|
@ -3,6 +3,7 @@ package runtime
|
|||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/native/ledger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/neogointernal"
|
||||
)
|
||||
|
||||
// GetScriptContainer returns the transaction that initially triggered current
|
||||
|
@ -10,7 +11,7 @@ import (
|
|||
// this execution goes. This function uses
|
||||
// `System.Runtime.GetScriptContainer` syscall.
|
||||
func GetScriptContainer() *ledger.Transaction {
|
||||
return &ledger.Transaction{}
|
||||
return neogointernal.Syscall0("System.Runtime.GetScriptContainer").(*ledger.Transaction)
|
||||
}
|
||||
|
||||
// GetExecutingScriptHash returns script hash (160 bit in BE form represented
|
||||
|
@ -19,7 +20,7 @@ func GetScriptContainer() *ledger.Transaction {
|
|||
// different contract. This function uses
|
||||
// `System.Runtime.GetExecutingScriptHash` syscall.
|
||||
func GetExecutingScriptHash() interop.Hash160 {
|
||||
return nil
|
||||
return neogointernal.Syscall0("System.Runtime.GetExecutingScriptHash").(interop.Hash160)
|
||||
}
|
||||
|
||||
// GetCallingScriptHash returns script hash (160 bit in BE form represented
|
||||
|
@ -28,7 +29,7 @@ func GetExecutingScriptHash() interop.Hash160 {
|
|||
// above the GetExecutingScriptHash in the call stack. It uses
|
||||
// `System.Runtime.GetCallingScriptHash` syscall.
|
||||
func GetCallingScriptHash() interop.Hash160 {
|
||||
return nil
|
||||
return neogointernal.Syscall0("System.Runtime.GetCallingScriptHash").(interop.Hash160)
|
||||
}
|
||||
|
||||
// GetEntryScriptHash returns script hash (160 bit in BE form represented
|
||||
|
@ -37,5 +38,5 @@ func GetCallingScriptHash() interop.Hash160 {
|
|||
// GetScriptContainer) execution from the start. This function uses
|
||||
// `System.Runtime.GetEntryScriptHash` syscall.
|
||||
func GetEntryScriptHash() interop.Hash160 {
|
||||
return nil
|
||||
return neogointernal.Syscall0("System.Runtime.GetEntryScriptHash").(interop.Hash160)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,10 @@ It has similar function to Runtime class in .net framwork for Neo.
|
|||
*/
|
||||
package runtime
|
||||
|
||||
import "github.com/nspcc-dev/neo-go/pkg/interop"
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/neogointernal"
|
||||
)
|
||||
|
||||
// Trigger values to compare with GetTrigger result.
|
||||
const (
|
||||
|
@ -18,13 +21,15 @@ const (
|
|||
// slice) or key (compressed serialized 33-byte form) is one of the signers of
|
||||
// this invocation. It uses `System.Runtime.CheckWitness` syscall.
|
||||
func CheckWitness(hashOrKey []byte) bool {
|
||||
return true
|
||||
return neogointernal.Syscall1("System.Runtime.CheckWitness", hashOrKey).(bool)
|
||||
}
|
||||
|
||||
// Log instructs VM to log the given message. It's mostly used for debugging
|
||||
// purposes as these messages are not saved anywhere normally and usually are
|
||||
// only visible in the VM logs. This function uses `System.Runtime.Log` syscall.
|
||||
func Log(message string) {}
|
||||
func Log(message string) {
|
||||
neogointernal.Syscall1NoReturn("System.Runtime.Log", message)
|
||||
}
|
||||
|
||||
// Notify sends a notification (collecting all arguments in an array) to the
|
||||
// executing environment. Unlike Log it can accept any data along with the event name
|
||||
|
@ -32,7 +37,9 @@ func Log(message string) {}
|
|||
// part of contract's API to external systems, these events can be monitored
|
||||
// from outside and act upon accordingly. This function uses
|
||||
// `System.Runtime.Notify` syscall.
|
||||
func Notify(name string, arg ...interface{}) {}
|
||||
func Notify(name string, args ...interface{}) {
|
||||
neogointernal.Syscall2NoReturn("System.Runtime.Notify", name, args)
|
||||
}
|
||||
|
||||
// GetTime returns the timestamp of the most recent block. Note that when running
|
||||
// script in test mode this would be the last accepted (persisted) block in the
|
||||
|
@ -40,7 +47,7 @@ func Notify(name string, arg ...interface{}) {}
|
|||
// time of this (currently being processed) block. This function uses
|
||||
// `System.Runtime.GetTime` syscall.
|
||||
func GetTime() int {
|
||||
return 0
|
||||
return neogointernal.Syscall0("System.Runtime.GetTime").(int)
|
||||
}
|
||||
|
||||
// GetTrigger returns the smart contract invocation trigger which can be either
|
||||
|
@ -50,13 +57,13 @@ func GetTime() int {
|
|||
// not available when running with verification trigger. This function uses
|
||||
// `System.Runtime.GetTrigger` syscall.
|
||||
func GetTrigger() byte {
|
||||
return 0x00
|
||||
return neogointernal.Syscall0("System.Runtime.GetTrigger").(byte)
|
||||
}
|
||||
|
||||
// GasLeft returns the amount of gas available for the current execution.
|
||||
// This function uses `System.Runtime.GasLeft` syscall.
|
||||
func GasLeft() int64 {
|
||||
return 0
|
||||
return neogointernal.Syscall0("System.Runtime.GasLeft").(int64)
|
||||
}
|
||||
|
||||
// GetNotifications returns notifications emitted by contract h.
|
||||
|
@ -64,17 +71,17 @@ func GasLeft() int64 {
|
|||
// [ scripthash of notification's contract , emitted item ].
|
||||
// This function uses `System.Runtime.GetNotifications` syscall.
|
||||
func GetNotifications(h interop.Hash160) [][]interface{} {
|
||||
return nil
|
||||
return neogointernal.Syscall1("System.Runtime.GetNotifications", h).([][]interface{})
|
||||
}
|
||||
|
||||
// GetInvocationCounter returns how many times current contract was invoked during current tx execution.
|
||||
// This function uses `System.Runtime.GetInvocationCounter` syscall.
|
||||
func GetInvocationCounter() int {
|
||||
return 0
|
||||
return neogointernal.Syscall0("System.Runtime.GetInvocationCounter").(int)
|
||||
}
|
||||
|
||||
// Platform returns the platform name, which is set to be `NEO`. This function uses
|
||||
// `System.Runtime.Platform` syscall.
|
||||
func Platform() []byte {
|
||||
return nil
|
||||
return neogointernal.Syscall0("System.Runtime.Platform").([]byte)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,10 @@ contract.
|
|||
*/
|
||||
package storage
|
||||
|
||||
import "github.com/nspcc-dev/neo-go/pkg/interop/iterator"
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/iterator"
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/neogointernal"
|
||||
)
|
||||
|
||||
// Context represents storage context that is mandatory for Put/Get/Delete
|
||||
// operations. It's an opaque type that can only be created properly by
|
||||
|
@ -39,46 +42,60 @@ const (
|
|||
// writing capability turned off, so that you could only invoke Get and Find
|
||||
// using this new Context. If Context is already read-only this function is a
|
||||
// no-op. It uses `System.Storage.AsReadOnly` syscall.
|
||||
func ConvertContextToReadOnly(ctx Context) Context { return Context{} }
|
||||
func ConvertContextToReadOnly(ctx Context) Context {
|
||||
return neogointernal.Syscall0("System.Storage.AsReadOnly").(Context)
|
||||
}
|
||||
|
||||
// GetContext returns current contract's (that invokes this function) storage
|
||||
// context. It uses `System.Storage.GetContext` syscall.
|
||||
func GetContext() Context { return Context{} }
|
||||
func GetContext() Context {
|
||||
return neogointernal.Syscall0("System.Storage.GetContext").(Context)
|
||||
}
|
||||
|
||||
// GetReadOnlyContext returns current contract's (that invokes this function)
|
||||
// storage context in read-only mode, you can use this context for Get and Find
|
||||
// functions, but using it for Put and Delete will fail. It uses
|
||||
// `System.Storage.GetReadOnlyContext` syscall.
|
||||
func GetReadOnlyContext() Context { return Context{} }
|
||||
func GetReadOnlyContext() Context {
|
||||
return neogointernal.Syscall0("System.Storage.GetReadOnlyContext").(Context)
|
||||
}
|
||||
|
||||
// Put saves given value with given key in the storage using given Context.
|
||||
// Even though it accepts interface{} for both, you can only pass simple types
|
||||
// there like string, []byte, int or bool (not structures or slices of more
|
||||
// complex types). To put more complex types there serialize them first using
|
||||
// runtime.Serialize. This function uses `System.Storage.Put` syscall.
|
||||
func Put(ctx Context, key interface{}, value interface{}) {}
|
||||
func Put(ctx Context, key interface{}, value interface{}) {
|
||||
neogointernal.Syscall3NoReturn("System.Storage.Put", ctx, key, value)
|
||||
}
|
||||
|
||||
// PutEx is an advanced version of Put which saves given value with given key
|
||||
// and given ReadOnly flag in the storage using given Context. `flag` argument
|
||||
// can either be odd for constant storage items or even for variable storage items.
|
||||
// Refer to Put function description for details on how to pass the remaining
|
||||
// arguments. This function uses `System.Storage.PutEx` syscall.
|
||||
func PutEx(ctx Context, key interface{}, value interface{}, flag int64) {}
|
||||
func PutEx(ctx Context, key interface{}, value interface{}, flag int64) {
|
||||
neogointernal.Syscall4NoReturn("System.Storage.PutEx", ctx, key, value, flag)
|
||||
}
|
||||
|
||||
// Get retrieves value stored for the given key using given Context. See Put
|
||||
// documentation on possible key and value types. If the value is not present in
|
||||
// the database it returns nil. This function uses `System.Storage.Get` syscall.
|
||||
func Get(ctx Context, key interface{}) interface{} { return nil }
|
||||
func Get(ctx Context, key interface{}) interface{} {
|
||||
return neogointernal.Syscall2("System.Storage.Get", ctx, key)
|
||||
}
|
||||
|
||||
// Delete removes key-value pair from storage by the given key using given
|
||||
// Context. See Put documentation on possible key types. This function uses
|
||||
// `System.Storage.Delete` syscall.
|
||||
func Delete(ctx Context, key interface{}) {}
|
||||
func Delete(ctx Context, key interface{}) {
|
||||
neogointernal.Syscall2NoReturn("System.Storage.Delete", ctx, key)
|
||||
}
|
||||
|
||||
// Find returns an iterator.Iterator over key-value pairs in the given Context
|
||||
// that match the given key (contain it as a prefix). See Put documentation on
|
||||
// possible key types and iterator package documentation on how to use the
|
||||
// returned value. This function uses `System.Storage.Find` syscall.
|
||||
func Find(ctx Context, key interface{}, options FindFlags) iterator.Iterator {
|
||||
return iterator.Iterator{}
|
||||
return neogointernal.Syscall3("System.Storage.Find", ctx, key, options).(iterator.Iterator)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue