new mapping for interop api (CityOfZion/neo-storm#10)

* new mapping for interop api

* Fixed interop API mapping + added missing apis

* added engine apis

Imported from CityOfZion/neo-storm (ec5e6c8e2b587704a1e071e83b633d2d3a235300).
This commit is contained in:
Anthony De Meulemeester 2018-08-22 09:51:35 +02:00 committed by Roman Khimov
parent 2fbb269c0d
commit 0b33cf3193
7 changed files with 181 additions and 83 deletions

22
examples/engine/engine.go Normal file
View file

@ -0,0 +1,22 @@
package engine_contract
import (
"github.com/CityOfZion/neo-storm/interop/engine"
"github.com/CityOfZion/neo-storm/interop/runtime"
)
func Main() bool {
tx := engine.GetScriptContainer()
runtime.Notify(tx)
callingScriptHash := engine.GetCallingScriptHash()
runtime.Notify(callingScriptHash)
execScriptHash := engine.GetExecutingScriptHash()
runtime.Notify(execScriptHash)
entryScriptHash := engine.GetEntryScriptHash()
runtime.Notify(entryScriptHash)
return true
}

View file

@ -1,5 +1,7 @@
package contract package contract
import "github.com/CityOfZion/neo-storm/interop/storage"
// Package contract provides function signatures that can be used inside // Package contract provides function signatures that can be used inside
// smart contracts that are written in the neo-storm framework. // smart contracts that are written in the neo-storm framework.
@ -15,3 +17,39 @@ func GetScript(c Contract) []byte {
func IsPayable(c Contract) bool { func IsPayable(c Contract) bool {
return false return false
} }
// GetStorageContext returns the storage context for the given contract.
func GetStorageContext(c Contract) storage.Context {
return storage.Context{}
}
// Create creates a new contract.
// @FIXME What is the type of the returnType here?
func Create(
script []byte,
params []interface{},
returnType byte,
properties interface{},
name,
version,
author,
email,
description string) {
}
// Migrate migrates a new contract.
// @FIXME What is the type of the returnType here?
func Migrate(
script []byte,
params []interface{},
returnType byte,
properties interface{},
name,
version,
author,
email,
description string) {
}
// Destroy deletes a contract that is registered on the blockchain.
func Destroy(c Contract) {}

29
interop/engine/engine.go Normal file
View file

@ -0,0 +1,29 @@
package engine
import "github.com/CityOfZion/neo-storm/interop/transaction"
// Package engine provides function signatures that can be used inside
// smart contracts that are written in the neo-storm framework.
// GetScriptContainer returns the transaction that is in the execution context.
func GetScriptContainer() transaction.Transaction {
return transaction.Transaction{}
}
// GetExecutingScriptHash returns the script hash of the contract that is
// currently being executed.
func GetExecutingScriptHash() []byte {
return nil
}
// GetCallingScriptHash returns the script hash of the contract that started
// the execution of the current script.
func GetCallingScriptHash() []byte {
return nil
}
// GetEntryScriptHash returns the script hash of the contract the started the
// execution from the start.
func GetEntryScriptHash() []byte {
return nil
}

View file

@ -201,19 +201,12 @@ func isByteArray(lit *ast.CompositeLit, tInfo *types.Info) bool {
return false return false
} }
func isSyscall(name string) bool { func isSyscall(fun *funcScope) bool {
_, ok := syscalls[name] if fun.selector == nil {
return ok
}
// isNoRetSyscall checks if the syscall has a return value.
func isNoRetSyscall(name string) bool {
for _, s := range noRetSyscalls {
if s == name {
return true
}
}
return false return false
}
_, ok := syscalls[fun.selector.Name][fun.name]
return ok
} }
func isStringType(t types.Type) bool { func isStringType(t types.Type) bool {

View file

@ -185,7 +185,7 @@ func (c *codegen) convertFuncDecl(file ast.Node, decl *ast.FuncDecl) {
} }
// Load in all the global variables in to the scope of the function. // Load in all the global variables in to the scope of the function.
// This is not necessary for syscalls. // This is not necessary for syscalls.
if !isSyscall(f.name) { if !isSyscall(f) {
c.convertGlobals(file) c.convertGlobals(file)
} }
@ -394,7 +394,10 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
// Dont forget to add 1 extra argument when its a method. // Dont forget to add 1 extra argument when its a method.
numArgs++ numArgs++
} }
f, ok = c.funcs[fun.Sel.Name] f, ok = c.funcs[fun.Sel.Name]
// @FIXME this could cause runtime errors.
f.selector = fun.X.(*ast.Ident)
if !ok { if !ok {
log.Fatalf("could not resolve function %s", fun.Sel.Name) log.Fatalf("could not resolve function %s", fun.Sel.Name)
} }
@ -433,8 +436,8 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
// Use the ident to check, builtins are not in func scopes. // Use the ident to check, builtins are not in func scopes.
// We can be sure builtins are of type *ast.Ident. // We can be sure builtins are of type *ast.Ident.
c.convertBuiltin(n) c.convertBuiltin(n)
case isSyscall(f.name): case isSyscall(f):
c.convertSyscall(f.name) c.convertSyscall(f.selector.Name, f.name)
default: default:
emitCall(c.prog, vm.CALL, int16(f.label)) emitCall(c.prog, vm.CALL, int16(f.label))
} }
@ -531,8 +534,8 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
return c return c
} }
func (c *codegen) convertSyscall(name string) { func (c *codegen) convertSyscall(api, name string) {
api, ok := syscalls[name] api, ok := syscalls[api][name]
if !ok { if !ok {
log.Fatalf("unknown VM syscall api: %s", name) log.Fatalf("unknown VM syscall api: %s", name)
} }

View file

@ -10,6 +10,10 @@ type funcScope struct {
// identifier of the function. // identifier of the function.
name string name string
// Selector of the function if there is any. Only functions imported
// from other packages should have a selector.
selector *ast.Ident
// The declaration of the function in the AST. Nil if this scope is not a function. // The declaration of the function in the AST. Nil if this scope is not a function.
decl *ast.FuncDecl decl *ast.FuncDecl

View file

@ -1,18 +1,14 @@
package compiler package compiler
var syscalls = map[string]string{ var syscalls = map[string]map[string]string{
// "storage": {
// Standard library API
//
// Storage API
"GetContext": "System.Storage.GetContext", "GetContext": "System.Storage.GetContext",
"Put": "System.Storage.Put", "Put": "System.Storage.Put",
"Get": "System.Storage.Get", "Get": "System.Storage.Get",
"Delete": "System.Storage.Delete", "Delete": "System.Storage.Delete",
"Find": "System.Storage.Find", "Find": "System.Storage.Find",
},
// Runtime API "runtime": {
"GetTrigger": "System.Runtime.GetTrigger", "GetTrigger": "System.Runtime.GetTrigger",
"CheckWitness": "System.Runtime.CheckWitness", "CheckWitness": "System.Runtime.CheckWitness",
"Notify": "System.Runtime.Notify", "Notify": "System.Runtime.Notify",
@ -20,50 +16,63 @@ var syscalls = map[string]string{
"GetTime": "System.Runtime.GetTime", "GetTime": "System.Runtime.GetTime",
"Serialize": "System.Runtime.Serialize", "Serialize": "System.Runtime.Serialize",
"Deserialize": "System.Runtime.Deserialize", "Deserialize": "System.Runtime.Deserialize",
},
// Blockchain API "blockchain": {
"GetHeight": "System.Blockchain.GetHeight", "GetHeight": "System.Blockchain.GetHeight",
"GetHeader": "System.Blockchain.GetHeader", "GetHeader": "System.Blockchain.GetHeader",
"GetBlock": "System.Blockchain.GetBlock", "GetBlock": "System.Blockchain.GetBlock",
"GetTransaction": "System.Blockchain.GetTransaction", "GetTransaction": "System.Blockchain.GetTransaction",
"GetTransactionHeight": "System.Blockchain.GetTransactionHeight",
"GetContract": "System.Blockchain.GetContract", "GetContract": "System.Blockchain.GetContract",
// Header API
"GetIndex": "System.Header.GetContract",
"GetHash": "System.Header.GetHash",
"GetPrevHash": "System.Header.GetPrevHash",
"GetTimestamp": "System.Header.GetTimestamp",
// Block API
"GetTransactionCount": "System.Block.GetTransactionCount",
"GetTransactions": "System.Block.GetTransactions",
// TODO: Find solution for duplicated map entry
"NGetTransaction": "System.Block.GetTransaction",
//
// NEO specific API
//
// Blockchain API
"GetAccount": "Neo.Blockchain.GetAccount", "GetAccount": "Neo.Blockchain.GetAccount",
"GetValidators": "Neo.Blockchain.GetValidators", "GetValidators": "Neo.Blockchain.GetValidators",
"GetAsset": "Neo.Blockchain.GetAsset", "GetAsset": "Neo.Blockchain.GetAsset",
},
// Header API "header": {
"GetIndex": "System.Header.GetIndex",
"GetHash": "System.Header.GetHash",
"GetPrevHash": "System.Header.GetPrevHash",
"GetTimestamp": "System.Header.GetTimestamp",
"GetVersion": "Neo.Header.GetVersion", "GetVersion": "Neo.Header.GetVersion",
"GetMerkleRoot": "Neo.Header.GetMerkleRoot", "GetMerkleRoot": "Neo.Header.GetMerkleRoot",
"GetConsensusData": "Neo.Header.GetConsensusData", "GetConsensusData": "Neo.Header.GetConsensusData",
"GetNextConsensus": "Neo.Header.GetNextConsensus", "GetNextConsensus": "Neo.Header.GetNextConsensus",
},
// Transaction API "block": {
"GetTransactionCount": "System.Block.GetTransactionCount",
"GetTransactions": "System.Block.GetTransactions",
"GetTransaction": "System.Block.GetTransaction",
},
"transaction": {
"GetType": "Neo.Transaction.GetType", "GetType": "Neo.Transaction.GetType",
"GetAttributes": "Neo.Transaction.GetAttributes", "GetAttributes": "Neo.Transaction.GetAttributes",
"GetInputs": "Neo.Transaction.GetInputs", "GetInputs": "Neo.Transaction.GetInputs",
"GetOutputs": "Neo.Transaction.GetOutputs", "GetOutputs": "Neo.Transaction.GetOutputs",
"GetReferences": "Neo.Transaction.GetReferences", "GetReferences": "Neo.Transaction.GetReferences",
"GetUnspentCoins": "Neo.Transaction.GetUnspentCoins", "GetUnspentCoins": "Neo.Transaction.GetUnspentCoins",
"GetScript": "Neo.InvocationTransaction.GetScript", "GetScript": "Neo.Transaction.GetScript",
},
// TODO: Add the rest of the interop APIS "asset": {
"GetAssetID": "Neo.Asset.GetAssetID",
"GetAssetType": "Neo.Asset.GetAssetType",
"GetAmount": "Neo.Asset.GetAmount",
"Create": "Neo.Asset.Create",
"Renew": "Neo.Asset.Renew",
},
"contract": {
"GetScript": "Neo.Contract.GetScript",
"IsPayable": "Neo.Contract.IsPayable",
"Create": "Neo.Contract.Create",
"Destroy": "Neo.Contract.Destroy",
"Migrate": "Neo.Contract.Migrate",
"GetStorageContext": "Neo.Contract.GetStorageContext",
},
"input": {
"GetHash": "Neo.Input.GetHash",
"GetIndex": "Neo.Input.GetIndex",
},
"output": {
"GetAssetID": "Neo.Output.GetAssetID",
"GetValue": "Neo.Output.GetValue",
"GetScriptHash": "Neo.Output.GetScriptHash",
},
} }