From 69c011b3e7f5594dc71de5f9cc7aa0b9de908984 Mon Sep 17 00:00:00 2001 From: Evgeniy Stratonikov Date: Mon, 8 Feb 2021 11:10:25 +0300 Subject: [PATCH] compiler: implement Ledger contract wrapper --- pkg/compiler/debug.go | 2 +- pkg/compiler/debug_test.go | 4 +-- pkg/interop/native/ledger/block.go | 29 +++++++++++++++++ pkg/interop/native/ledger/ledger.go | 40 ++++++++++++++++++++++++ pkg/interop/native/ledger/transaction.go | 27 ++++++++++++++++ pkg/interop/runtime/engine.go | 29 ++--------------- 6 files changed, 102 insertions(+), 29 deletions(-) create mode 100644 pkg/interop/native/ledger/block.go create mode 100644 pkg/interop/native/ledger/ledger.go create mode 100644 pkg/interop/native/ledger/transaction.go diff --git a/pkg/compiler/debug.go b/pkg/compiler/debug.go index fe8588ddf..042d47fd5 100644 --- a/pkg/compiler/debug.go +++ b/pkg/compiler/debug.go @@ -239,7 +239,7 @@ func scAndVMInteropTypeFromExpr(named *types.Named) (smartcontract.ParamType, st name := named.Obj().Name() pkg := named.Obj().Pkg().Name() switch pkg { - case "runtime", "contract": + case "ledger", "contract": return smartcontract.ArrayType, stackitem.ArrayT // Block, Transaction, Contract case "interop": if name != "Interface" { diff --git a/pkg/compiler/debug_test.go b/pkg/compiler/debug_test.go index 04f545384..5e1c0346d 100644 --- a/pkg/compiler/debug_test.go +++ b/pkg/compiler/debug_test.go @@ -16,7 +16,7 @@ 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/runtime" + import "github.com/nspcc-dev/neo-go/pkg/interop/native/ledger" func Main(op string) bool { var s string _ = s @@ -47,7 +47,7 @@ func unexportedMethod() int { return 1 } func MethodParams(addr interop.Hash160, h interop.Hash256, sig interop.Signature, pub interop.PublicKey, inter interop.Interface, - ctx storage.Context, tx runtime.Transaction) bool { + ctx storage.Context, tx ledger.Transaction) bool { return true } type MyStruct struct {} diff --git a/pkg/interop/native/ledger/block.go b/pkg/interop/native/ledger/block.go new file mode 100644 index 000000000..1196b5154 --- /dev/null +++ b/pkg/interop/native/ledger/block.go @@ -0,0 +1,29 @@ +package ledger + +import "github.com/nspcc-dev/neo-go/pkg/interop" + +// Block represents a NEO block, it's a data structure that you can get +// block-related data from. It's similar to the Block class in the Neo .net +// framework. To use it you need to get it via GetBlock function call. +type Block struct { + // Hash represents the hash (256 bit BE value in a 32 byte slice) of the + // given block. + 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 interop.Hash256 + // MerkleRoot represents the root hash (256 bit BE value in a 32 byte slice) + // of a transaction list. + 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 interop.Hash160 + // TransactionsLength represents the length of block's transactions array. + TransactionsLength int +} diff --git a/pkg/interop/native/ledger/ledger.go b/pkg/interop/native/ledger/ledger.go new file mode 100644 index 000000000..fe9787c30 --- /dev/null +++ b/pkg/interop/native/ledger/ledger.go @@ -0,0 +1,40 @@ +package ledger + +import ( + "github.com/nspcc-dev/neo-go/pkg/interop" + "github.com/nspcc-dev/neo-go/pkg/interop/contract" +) + +// Hash represents Ledger contract hash. +const Hash = "\x64\x87\x5a\x12\xc6\x03\xc6\x1d\xec\xff\xdf\xe7\x88\xce\x10\xdd\xc6\x69\x1d\x97" + +// CurrentHash represents `currentHash` method of Ledger native contract. +func CurrentHash() interop.Hash256 { + return contract.Call(interop.Hash160(Hash), "currentHash", contract.ReadStates).(interop.Hash256) +} + +// CurrentIndex represents `currentIndex` method of Ledger native contract. +func CurrentIndex() int { + return contract.Call(interop.Hash160(Hash), "currentIndex", contract.ReadStates).(int) +} + +// GetBlock represents `getBlock` method of Ledger native contract. +func GetBlock(indexOrHash interface{}) *Block { + return contract.Call(interop.Hash160(Hash), "getBlock", contract.ReadStates, indexOrHash).(*Block) +} + +// GetTransaction represents `getTransaction` method of Ledger native contract. +func GetTransaction(hash interop.Hash256) *Transaction { + return contract.Call(interop.Hash160(Hash), "getTransaction", contract.ReadStates, hash).(*Transaction) +} + +// GetTransactionHeight represents `getTransactionHeight` method of Ledger native contract. +func GetTransactionHeight(hash interop.Hash256) int { + return contract.Call(interop.Hash160(Hash), "getTransactionHeight", contract.ReadStates, hash).(int) +} + +// GetTransactionFromBlock represents `getTransactionFromBlock` method of Ledger native contract. +func GetTransactionFromBlock(indexOrHash interface{}, txIndex int) *Transaction { + return contract.Call(interop.Hash160(Hash), "getTransactionFromBlock", contract.ReadStates, + indexOrHash, txIndex).(*Transaction) +} diff --git a/pkg/interop/native/ledger/transaction.go b/pkg/interop/native/ledger/transaction.go new file mode 100644 index 000000000..0cc7c49d2 --- /dev/null +++ b/pkg/interop/native/ledger/transaction.go @@ -0,0 +1,27 @@ +package ledger + +import "github.com/nspcc-dev/neo-go/pkg/interop" + +// 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 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 interop.Hash160 + // SysFee represents fee to be burned. + SysFee int + // NetFee represents fee to be distributed to consensus nodes. + NetFee int + // ValidUntilBlock is the maximum blockchain height exceeding which + // transaction should fail verification. + ValidUntilBlock int + // Script represents code to run in NeoVM for this transaction. + Script []byte +} diff --git a/pkg/interop/runtime/engine.go b/pkg/interop/runtime/engine.go index a8180b457..9975b4e90 100644 --- a/pkg/interop/runtime/engine.go +++ b/pkg/interop/runtime/engine.go @@ -2,38 +2,15 @@ package runtime import ( "github.com/nspcc-dev/neo-go/pkg/interop" + "github.com/nspcc-dev/neo-go/pkg/interop/native/ledger" ) -// 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 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 interop.Hash160 - // SysFee represents fee to be burned. - SysFee int - // NetFee represents fee to be distributed to consensus nodes. - NetFee int - // ValidUntilBlock is the maximum blockchain height exceeding which - // transaction should fail verification. - ValidUntilBlock int - // Script represents code to run in NeoVM for this transaction. - Script []byte -} - // GetScriptContainer returns the transaction that initially triggered current // 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() *Transaction { - return &Transaction{} +func GetScriptContainer() *ledger.Transaction { + return &ledger.Transaction{} } // GetExecutingScriptHash returns script hash (160 bit in BE form represented