Merge pull request #2447 from nspcc-dev/gettransactionsigners

core: add GetTransactionSigners method to native Ledger
This commit is contained in:
Roman Khimov 2022-04-29 11:58:38 +03:00 committed by GitHub
commit 3ae1647940
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 533 additions and 61 deletions

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/engine
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c h1:D0iDtGEnFbld/tllTbv3ah4BQPPaItTs/Y8Li5zrEOw=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47 h1:9PVLOwD2khKIb4BQR7nqeslE1pRSGxJoXvul2/Rk1wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/events
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c h1:D0iDtGEnFbld/tllTbv3ah4BQPPaItTs/Y8Li5zrEOw=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47 h1:9PVLOwD2khKIb4BQR7nqeslE1pRSGxJoXvul2/Rk1wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/iterator
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c h1:D0iDtGEnFbld/tllTbv3ah4BQPPaItTs/Y8Li5zrEOw=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47 h1:9PVLOwD2khKIb4BQR7nqeslE1pRSGxJoXvul2/Rk1wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/nft
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c h1:D0iDtGEnFbld/tllTbv3ah4BQPPaItTs/Y8Li5zrEOw=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47 h1:9PVLOwD2khKIb4BQR7nqeslE1pRSGxJoXvul2/Rk1wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -0,0 +1,8 @@
MSYS-1.0.19 Build:2016-07-13 17:45
Exception: STATUS_ACCESS_VIOLATION at eip=0072174E
eax=608F9138 ebx=00000000 ecx=60EA0000 edx=60EA4184 esi=00993208 edi=00000001
ebp=0069FEB0 esp=0069FE48 program=us
cs=0023 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
Frame Function Args
15750 [main] us 0 handle_exceptions: Error while dumping state (probably corrupted stack)

View file

@ -3,7 +3,7 @@ module github.com/nspcc-dev/neo-go/examples/nft-nd-nns
go 1.16
require (
github.com/nspcc-dev/neo-go v0.98.3-pre.0.20220421162730-3463d7292fb9
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c
github.com/nspcc-dev/neo-go v0.98.3-pre.0.20220429082343-69b70c5e933a
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47
github.com/stretchr/testify v1.7.0
)

View file

@ -177,10 +177,10 @@ github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y=
github.com/nspcc-dev/hrw v1.0.9/go.mod h1:l/W2vx83vMQo6aStyx2AuZrJ+07lGv2JQGlVkPG06MU=
github.com/nspcc-dev/neo-go v0.73.1-pre.0.20200303142215-f5a1b928ce09/go.mod h1:pPYwPZ2ks+uMnlRLUyXOpLieaDQSEaf4NM3zHVbRjmg=
github.com/nspcc-dev/neo-go v0.98.0/go.mod h1:E3cc1x6RXSXrJb2nDWXTXjnXk3rIqVN8YdFyWv+FrqM=
github.com/nspcc-dev/neo-go v0.98.3-pre.0.20220421162730-3463d7292fb9 h1:hflyJ+EnjaLPXtpxM4Wibqo4ppnfXCjf4kBUzxvp/MU=
github.com/nspcc-dev/neo-go v0.98.3-pre.0.20220421162730-3463d7292fb9/go.mod h1:LGZ16CRv4Nfh7KTt99CH/bhjOlTPQPbJcICJ4onP4Ds=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c h1:D0iDtGEnFbld/tllTbv3ah4BQPPaItTs/Y8Li5zrEOw=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go v0.98.3-pre.0.20220429082343-69b70c5e933a h1:5tTKYXxz/DRDopPpf2/2rcdkESDm/RWH3t5aNXyGtAc=
github.com/nspcc-dev/neo-go v0.98.3-pre.0.20220429082343-69b70c5e933a/go.mod h1:hKgAWnSYaq5FIg8XclLvG5gjsjjFMkFhklyO092/sGM=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47 h1:9PVLOwD2khKIb4BQR7nqeslE1pRSGxJoXvul2/Rk1wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neofs-api-go/v2 v2.11.0-pre.0.20211201134523-3604d96f3fe1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=
github.com/nspcc-dev/neofs-api-go/v2 v2.11.1 h1:SVqc523pZsSaS9vnPS1mm3VV6b6xY0gvdA0uYJ/GWZQ=
github.com/nspcc-dev/neofs-api-go/v2 v2.11.1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/nft-nd
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c h1:D0iDtGEnFbld/tllTbv3ah4BQPPaItTs/Y8Li5zrEOw=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47 h1:9PVLOwD2khKIb4BQR7nqeslE1pRSGxJoXvul2/Rk1wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/oracle
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c h1:D0iDtGEnFbld/tllTbv3ah4BQPPaItTs/Y8Li5zrEOw=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47 h1:9PVLOwD2khKIb4BQR7nqeslE1pRSGxJoXvul2/Rk1wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/runtime
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c h1:D0iDtGEnFbld/tllTbv3ah4BQPPaItTs/Y8Li5zrEOw=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47 h1:9PVLOwD2khKIb4BQR7nqeslE1pRSGxJoXvul2/Rk1wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/storage
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c h1:D0iDtGEnFbld/tllTbv3ah4BQPPaItTs/Y8Li5zrEOw=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47 h1:9PVLOwD2khKIb4BQR7nqeslE1pRSGxJoXvul2/Rk1wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/timer
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c h1:D0iDtGEnFbld/tllTbv3ah4BQPPaItTs/Y8Li5zrEOw=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47 h1:9PVLOwD2khKIb4BQR7nqeslE1pRSGxJoXvul2/Rk1wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/token
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c h1:D0iDtGEnFbld/tllTbv3ah4BQPPaItTs/Y8Li5zrEOw=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47 h1:9PVLOwD2khKIb4BQR7nqeslE1pRSGxJoXvul2/Rk1wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

2
go.mod
View file

@ -12,7 +12,7 @@ require (
github.com/mr-tron/base58 v1.2.0
github.com/nspcc-dev/dbft v0.0.0-20220414131237-e497bbf7868e
github.com/nspcc-dev/go-ordered-json v0.0.0-20220111165707-25110be27d22
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20220113123743-7f3162110659
github.com/nspcc-dev/rfc6979 v0.2.0
github.com/pierrec/lz4 v2.6.1+incompatible

4
go.sum
View file

@ -185,8 +185,8 @@ github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y=
github.com/nspcc-dev/hrw v1.0.9/go.mod h1:l/W2vx83vMQo6aStyx2AuZrJ+07lGv2JQGlVkPG06MU=
github.com/nspcc-dev/neo-go v0.73.1-pre.0.20200303142215-f5a1b928ce09/go.mod h1:pPYwPZ2ks+uMnlRLUyXOpLieaDQSEaf4NM3zHVbRjmg=
github.com/nspcc-dev/neo-go v0.98.0/go.mod h1:E3cc1x6RXSXrJb2nDWXTXjnXk3rIqVN8YdFyWv+FrqM=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c h1:D0iDtGEnFbld/tllTbv3ah4BQPPaItTs/Y8Li5zrEOw=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220421162616-d942940a826c/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47 h1:9PVLOwD2khKIb4BQR7nqeslE1pRSGxJoXvul2/Rk1wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220429082221-441a3eb34c47/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neofs-api-go/v2 v2.11.0-pre.0.20211201134523-3604d96f3fe1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=
github.com/nspcc-dev/neofs-api-go/v2 v2.11.1 h1:SVqc523pZsSaS9vnPS1mm3VV6b6xY0gvdA0uYJ/GWZQ=
github.com/nspcc-dev/neofs-api-go/v2 v2.11.1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=

View file

@ -89,6 +89,32 @@ func TestOracleContractValues(t *testing.T) {
require.EqualValues(t, oracle.MinimumResponseGas, native.MinimumResponseGas)
}
func TestLedgerTransactionWitnessScope(t *testing.T) {
require.EqualValues(t, ledger.None, transaction.None)
require.EqualValues(t, ledger.CalledByEntry, transaction.CalledByEntry)
require.EqualValues(t, ledger.CustomContracts, transaction.CustomContracts)
require.EqualValues(t, ledger.CustomGroups, transaction.CustomGroups)
require.EqualValues(t, ledger.Rules, transaction.Rules)
require.EqualValues(t, ledger.Global, transaction.Global)
}
func TestLedgerTransactionWitnessAction(t *testing.T) {
require.EqualValues(t, ledger.WitnessAllow, transaction.WitnessAllow)
require.EqualValues(t, ledger.WitnessDeny, transaction.WitnessDeny)
}
func TestLedgerTransactionWitnessCondition(t *testing.T) {
require.EqualValues(t, ledger.WitnessBoolean, transaction.WitnessBoolean)
require.EqualValues(t, ledger.WitnessNot, transaction.WitnessNot)
require.EqualValues(t, ledger.WitnessAnd, transaction.WitnessAnd)
require.EqualValues(t, ledger.WitnessOr, transaction.WitnessOr)
require.EqualValues(t, ledger.WitnessScriptHash, transaction.WitnessScriptHash)
require.EqualValues(t, ledger.WitnessGroup, transaction.WitnessGroup)
require.EqualValues(t, ledger.WitnessCalledByEntry, transaction.WitnessCalledByEntry)
require.EqualValues(t, ledger.WitnessCalledByContract, transaction.WitnessCalledByContract)
require.EqualValues(t, ledger.WitnessCalledByGroup, transaction.WitnessCalledByGroup)
}
func TestLedgerVMStates(t *testing.T) {
require.EqualValues(t, ledger.NoneState, vm.NoneState)
require.EqualValues(t, ledger.HaltState, vm.HaltState)
@ -158,6 +184,7 @@ func TestNativeHelpersCompile(t *testing.T) {
{"getTransaction", []string{u256}},
{"getTransactionFromBlock", []string{u256, "1"}},
{"getTransactionHeight", []string{u256}},
{"getTransactionSigners", []string{u256}},
{"getTransactionVMState", []string{u256}},
})
runNativeTestCases(t, cs.Notary.ContractMD, "notary", []nativeTestCase{

View file

@ -10,6 +10,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
@ -63,6 +64,11 @@ func newLedger() *Ledger {
md = newMethodAndPrice(l.getTransactionFromBlock, 1<<16, callflag.ReadStates)
l.AddMethod(md, desc)
desc = newDescriptor("getTransactionSigners", smartcontract.ArrayType,
manifest.NewParameter("hash", smartcontract.Hash256Type))
md = newMethodAndPrice(l.getTransactionSigners, 1<<15, callflag.ReadStates)
l.AddMethod(md, desc)
desc = newDescriptor("getTransactionVMState", smartcontract.IntegerType,
manifest.NewParameter("hash", smartcontract.Hash256Type))
md = newMethodAndPrice(l.getTransactionVMState, 1<<15, callflag.ReadStates)
@ -148,6 +154,15 @@ func (l *Ledger) getTransactionFromBlock(ic *interop.Context, params []stackitem
return TransactionToStackItem(block.Transactions[index])
}
// getTransactionSigners returns transaction signers to the SC.
func (l *Ledger) getTransactionSigners(ic *interop.Context, params []stackitem.Item) stackitem.Item {
tx, h, err := getTransactionAndHeight(ic.DAO, params[0])
if err != nil || !isTraceableBlock(ic.Chain, h) {
return stackitem.Null{}
}
return SignersToStackItem(tx.Signers)
}
// getTransactionVMState returns VM state got after transaction invocation.
func (l *Ledger) getTransactionVMState(ic *interop.Context, params []stackitem.Item) stackitem.Item {
hash, err := getUint256FromItem(params[0])
@ -242,3 +257,37 @@ func TransactionToStackItem(t *transaction.Transaction) stackitem.Item {
stackitem.NewByteArray(t.Script),
})
}
// SignersToStackItem converts transaction.Signers to stackitem.Item.
func SignersToStackItem(signers []transaction.Signer) stackitem.Item {
res := make([]stackitem.Item, len(signers))
bw := io.NewBufBinWriter()
for i, s := range signers {
s.EncodeBinary(bw.BinWriter)
if bw.Err != nil {
panic(fmt.Errorf("failed to serialize signer %d to stackitem: %w", i, bw.Err))
}
contracts := make([]stackitem.Item, len(s.AllowedContracts))
for j, c := range s.AllowedContracts {
contracts[j] = stackitem.NewByteArray(c.BytesBE())
}
groups := make([]stackitem.Item, len(s.AllowedGroups))
for j, g := range s.AllowedGroups {
groups[j] = stackitem.NewByteArray(g.Bytes())
}
rules := make([]stackitem.Item, len(s.Rules))
for j, r := range s.Rules {
rules[j] = r.ToStackItem()
}
res[i] = stackitem.NewArray([]stackitem.Item{
stackitem.NewByteArray(bw.Bytes()),
stackitem.NewByteArray(s.Account.BytesBE()),
stackitem.NewBigInteger(big.NewInt(int64(s.Scopes))),
stackitem.NewArray(contracts),
stackitem.NewArray(groups),
stackitem.NewArray(rules),
})
bw.Reset()
}
return stackitem.NewArray(res)
}

View file

@ -1,11 +1,16 @@
package native_test
import (
"fmt"
"math/big"
"strings"
"testing"
"github.com/nspcc-dev/neo-go/pkg/compiler"
"github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/neotest"
"github.com/nspcc-dev/neo-go/pkg/neotest/chain"
"github.com/nspcc-dev/neo-go/pkg/util"
@ -172,3 +177,127 @@ func TestLedger_GetBlock(t *testing.T) {
ledgerInvoker.Invoke(t, stackitem.Null{}, "getBlock", b.Hash())
})
}
func TestLedger_GetTransactionSigners(t *testing.T) {
c := newLedgerClient(t)
e := c.Executor
ledgerInvoker := c.WithSigners(c.Committee)
txHash := ledgerInvoker.Invoke(t, e.Chain.BlockHeight(), "currentIndex")
t.Run("good", func(t *testing.T) {
s := &transaction.Signer{
Account: c.CommitteeHash,
Scopes: transaction.Global,
}
bw := io.NewBufBinWriter()
s.EncodeBinary(bw.BinWriter)
require.NoError(t, bw.Err)
expected := stackitem.NewArray([]stackitem.Item{
stackitem.NewArray([]stackitem.Item{
stackitem.NewByteArray(bw.Bytes()),
stackitem.NewByteArray(s.Account.BytesBE()),
stackitem.NewBigInteger(big.NewInt(int64(s.Scopes))),
stackitem.NewArray([]stackitem.Item{}),
stackitem.NewArray([]stackitem.Item{}),
stackitem.NewArray([]stackitem.Item{}),
}),
})
ledgerInvoker.Invoke(t, expected, "getTransactionSigners", txHash)
})
t.Run("unknown transaction", func(t *testing.T) {
ledgerInvoker.Invoke(t, stackitem.Null{}, "getTransactionSigners", util.Uint256{1, 2, 3})
})
t.Run("not a hash", func(t *testing.T) {
ledgerInvoker.InvokeFail(t, "expected []byte of size 32", "getTransactionSigners", []byte{1, 2, 3})
})
}
func TestLedger_GetTransactionSignersInteropAPI(t *testing.T) {
c := newLedgerClient(t)
e := c.Executor
ledgerInvoker := c.WithSigners(c.Committee)
// Firstly, add transaction with CalledByEntry rule-based signer scope to the chain.
tx := e.NewUnsignedTx(t, ledgerInvoker.Hash, "currentIndex")
tx.Signers = []transaction.Signer{{
Account: c.Committee.ScriptHash(),
Scopes: transaction.Rules,
Rules: []transaction.WitnessRule{
{
Action: transaction.WitnessAllow,
Condition: transaction.ConditionCalledByEntry{},
},
},
}}
neotest.AddNetworkFee(e.Chain, tx, c.Committee)
neotest.AddSystemFee(e.Chain, tx, -1)
require.NoError(t, c.Committee.SignTx(e.Chain.GetConfig().Magic, tx))
c.AddNewBlock(t, tx)
c.CheckHalt(t, tx.Hash(), stackitem.Make(e.Chain.BlockHeight()-1))
var (
hashStr string
accStr string
txHash = tx.Hash().BytesBE()
acc = c.Committee.ScriptHash().BytesBE()
)
for i := 0; i < util.Uint256Size; i++ {
hashStr += fmt.Sprintf("%#x", txHash[i])
if i != util.Uint256Size-1 {
hashStr += ", "
}
}
for i := 0; i < util.Uint160Size; i++ {
accStr += fmt.Sprintf("%#x", acc[i])
if i != util.Uint160Size-1 {
accStr += ", "
}
}
// After that ensure interop API allows to retrieve signer with CalledByEntry rule-based scope.
src := `package callledger
import (
"github.com/nspcc-dev/neo-go/pkg/interop/native/ledger"
"github.com/nspcc-dev/neo-go/pkg/interop"
"github.com/nspcc-dev/neo-go/pkg/interop/util"
)
func CallLedger(accessValue bool) int {
signers := ledger.GetTransactionSigners(interop.Hash256{` + hashStr + `})
if len(signers) != 1 {
panic("bad length")
}
s0 := signers[0]
expectedAcc := interop.Hash160{` + accStr + `}
if !util.Equals(string(s0.Account), string(expectedAcc)) {
panic("bad account")
}
if s0.Scopes != ledger.Rules {
panic("bad signer scope")
}
if len(s0.Rules) != 1 {
panic("bad rules length")
}
r0 := s0.Rules[0]
if r0.Action != ledger.WitnessAllow {
panic("bad action")
}
c0 := r0.Condition
if c0.Type != ledger.WitnessCalledByEntry {
panic("bad condition type")
}
if accessValue {
// Panic should occur here, because there's only Type inside the CalledByEntry condition.
_ = c0.Value
}
return 1
}`
ctr := neotest.CompileSource(t, c.Committee.ScriptHash(), strings.NewReader(src), &compiler.Options{
Name: "calledger_contract",
})
e.DeployContract(t, ctr, nil)
ctrInvoker := e.NewInvoker(ctr.Hash, e.Committee)
ctrInvoker.Invoke(t, 1, "callLedger", false) // Firstly, don't access CalledByEnrty Condition value => the call should be successful.
ctrInvoker.InvokeFail(t, `(PICKITEM): unhandled exception: "The value 1 is out of range."`, "callLedger", true) // Then, access the value to ensure it will panic.
}

View file

@ -3,10 +3,12 @@ package transaction
import (
"encoding/json"
"errors"
"math/big"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)
//go:generate stringer -type=WitnessConditionType -linecomment
@ -50,6 +52,8 @@ type WitnessCondition interface {
// DecodeBinarySpecific decodes type-specific binary data from the given
// reader (not including type data).
DecodeBinarySpecific(*io.BinReader, int)
// ToStackItem converts WitnessCondition to stackitem.Item.
ToStackItem() stackitem.Item
json.Marshaler
}
@ -129,6 +133,12 @@ func (c *ConditionBoolean) MarshalJSON() ([]byte, error) {
return json.Marshal(aux)
}
// ToStackItem implements WitnessCondition interface allowing to convert
// to stackitem.Item.
func (c *ConditionBoolean) ToStackItem() stackitem.Item {
return condToStackItem(c.Type(), bool(*c))
}
// Type implements WitnessCondition interface and returns condition type.
func (c *ConditionNot) Type() WitnessConditionType {
return WitnessNot
@ -166,6 +176,12 @@ func (c *ConditionNot) MarshalJSON() ([]byte, error) {
return json.Marshal(aux)
}
// ToStackItem implements WitnessCondition interface allowing to convert
// to stackitem.Item.
func (c *ConditionNot) ToStackItem() stackitem.Item {
return condToStackItem(c.Type(), c.Condition)
}
// Type implements WitnessCondition interface and returns condition type.
func (c *ConditionAnd) Type() WitnessConditionType {
return WitnessAnd
@ -242,6 +258,12 @@ func (c *ConditionAnd) MarshalJSON() ([]byte, error) {
return arrayToJSON(c, []WitnessCondition(*c))
}
// ToStackItem implements WitnessCondition interface allowing to convert
// to stackitem.Item.
func (c *ConditionAnd) ToStackItem() stackitem.Item {
return condToStackItem(c.Type(), []WitnessCondition(*c))
}
// Type implements WitnessCondition interface and returns condition type.
func (c *ConditionOr) Type() WitnessConditionType {
return WitnessOr
@ -282,6 +304,12 @@ func (c *ConditionOr) MarshalJSON() ([]byte, error) {
return arrayToJSON(c, []WitnessCondition(*c))
}
// ToStackItem implements WitnessCondition interface allowing to convert
// to stackitem.Item.
func (c *ConditionOr) ToStackItem() stackitem.Item {
return condToStackItem(c.Type(), []WitnessCondition(*c))
}
// Type implements WitnessCondition interface and returns condition type.
func (c *ConditionScriptHash) Type() WitnessConditionType {
return WitnessScriptHash
@ -314,6 +342,12 @@ func (c *ConditionScriptHash) MarshalJSON() ([]byte, error) {
return json.Marshal(aux)
}
// ToStackItem implements WitnessCondition interface allowing to convert
// to stackitem.Item.
func (c *ConditionScriptHash) ToStackItem() stackitem.Item {
return condToStackItem(c.Type(), util.Uint160(*c))
}
// Type implements WitnessCondition interface and returns condition type.
func (c *ConditionGroup) Type() WitnessConditionType {
return WitnessGroup
@ -346,6 +380,12 @@ func (c *ConditionGroup) MarshalJSON() ([]byte, error) {
return json.Marshal(aux)
}
// ToStackItem implements WitnessCondition interface allowing to convert
// to stackitem.Item.
func (c *ConditionGroup) ToStackItem() stackitem.Item {
return condToStackItem(c.Type(), keys.PublicKey(*c))
}
// Type implements WitnessCondition interface and returns condition type.
func (c ConditionCalledByEntry) Type() WitnessConditionType {
return WitnessCalledByEntry
@ -376,6 +416,12 @@ func (c ConditionCalledByEntry) MarshalJSON() ([]byte, error) {
return json.Marshal(aux)
}
// ToStackItem implements WitnessCondition interface allowing to convert
// to stackitem.Item.
func (c ConditionCalledByEntry) ToStackItem() stackitem.Item {
return condToStackItem(c.Type(), nil)
}
// Type implements WitnessCondition interface and returns condition type.
func (c *ConditionCalledByContract) Type() WitnessConditionType {
return WitnessCalledByContract
@ -408,6 +454,12 @@ func (c *ConditionCalledByContract) MarshalJSON() ([]byte, error) {
return json.Marshal(aux)
}
// ToStackItem implements WitnessCondition interface allowing to convert
// to stackitem.Item.
func (c *ConditionCalledByContract) ToStackItem() stackitem.Item {
return condToStackItem(c.Type(), util.Uint160(*c))
}
// Type implements WitnessCondition interface and returns condition type.
func (c *ConditionCalledByGroup) Type() WitnessConditionType {
return WitnessCalledByGroup
@ -440,6 +492,12 @@ func (c *ConditionCalledByGroup) MarshalJSON() ([]byte, error) {
return json.Marshal(aux)
}
// ToStackItem implements WitnessCondition interface allowing to convert
// to stackitem.Item.
func (c *ConditionCalledByGroup) ToStackItem() stackitem.Item {
return condToStackItem(c.Type(), keys.PublicKey(*c))
}
// DecodeBinaryCondition decodes and returns condition from the given binary stream.
func DecodeBinaryCondition(r *io.BinReader) WitnessCondition {
return decodeBinaryCondition(r, MaxConditionNesting)
@ -573,3 +631,29 @@ func unmarshalConditionJSON(data []byte, maxDepth int) (WitnessCondition, error)
}
return res, nil
}
func condToStackItem(typ WitnessConditionType, c interface{}) stackitem.Item {
res := make([]stackitem.Item, 0, 2)
res = append(res, stackitem.NewBigInteger(big.NewInt(int64(typ))))
switch typ {
case WitnessBoolean:
res = append(res, stackitem.NewBool(c.(bool)))
case WitnessNot:
res = append(res, c.(WitnessCondition).ToStackItem())
case WitnessAnd, WitnessOr:
v := c.([]WitnessCondition)
operands := make([]stackitem.Item, len(v))
for i, op := range v {
operands[i] = op.ToStackItem()
}
res = append(res, stackitem.NewArray(operands))
case WitnessScriptHash, WitnessCalledByContract:
res = append(res, stackitem.NewByteArray(c.(util.Uint160).BytesBE()))
case WitnessGroup, WitnessCalledByGroup:
g := c.(keys.PublicKey)
res = append(res, stackitem.NewByteArray((&g).Bytes()))
case WitnessCalledByEntry:
// No additional item should be added.
}
return stackitem.NewArray(res)
}

View file

@ -8,6 +8,8 @@ import (
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -30,10 +32,14 @@ func (c InvalidCondition) MarshalJSON() ([]byte, error) {
}
return json.Marshal(aux)
}
func (c InvalidCondition) ToStackItem() stackitem.Item {
panic("invalid")
}
type condCase struct {
condition WitnessCondition
success bool
expectedStackItem []stackitem.Item
}
func TestWitnessConditionSerDes(t *testing.T) {
@ -41,19 +47,25 @@ func TestWitnessConditionSerDes(t *testing.T) {
pk, err := keys.NewPrivateKey()
require.NoError(t, err)
var cases = []condCase{
{(*ConditionBoolean)(&someBool), true},
{&ConditionNot{(*ConditionBoolean)(&someBool)}, true},
{&ConditionAnd{(*ConditionBoolean)(&someBool), (*ConditionBoolean)(&someBool)}, true},
{&ConditionOr{(*ConditionBoolean)(&someBool), (*ConditionBoolean)(&someBool)}, true},
{&ConditionScriptHash{1, 2, 3}, true},
{(*ConditionGroup)(pk.PublicKey()), true},
{ConditionCalledByEntry{}, true},
{&ConditionCalledByContract{1, 2, 3}, true},
{(*ConditionCalledByGroup)(pk.PublicKey()), true},
{InvalidCondition{}, false},
{&ConditionAnd{}, false},
{&ConditionOr{}, false},
{&ConditionNot{&ConditionNot{&ConditionNot{(*ConditionBoolean)(&someBool)}}}, false},
{(*ConditionBoolean)(&someBool), true, []stackitem.Item{stackitem.Make(WitnessBoolean), stackitem.Make(someBool)}},
{&ConditionNot{(*ConditionBoolean)(&someBool)}, true, []stackitem.Item{stackitem.Make(WitnessNot), stackitem.NewArray([]stackitem.Item{stackitem.Make(WitnessBoolean), stackitem.Make(someBool)})}},
{&ConditionAnd{(*ConditionBoolean)(&someBool), (*ConditionBoolean)(&someBool)}, true, []stackitem.Item{stackitem.Make(WitnessAnd), stackitem.Make([]stackitem.Item{
stackitem.NewArray([]stackitem.Item{stackitem.Make(WitnessBoolean), stackitem.Make(someBool)}),
stackitem.NewArray([]stackitem.Item{stackitem.Make(WitnessBoolean), stackitem.Make(someBool)}),
})}},
{&ConditionOr{(*ConditionBoolean)(&someBool), (*ConditionBoolean)(&someBool)}, true, []stackitem.Item{stackitem.Make(WitnessOr), stackitem.Make([]stackitem.Item{
stackitem.NewArray([]stackitem.Item{stackitem.Make(WitnessBoolean), stackitem.Make(someBool)}),
stackitem.NewArray([]stackitem.Item{stackitem.Make(WitnessBoolean), stackitem.Make(someBool)}),
})}},
{&ConditionScriptHash{1, 2, 3}, true, []stackitem.Item{stackitem.Make(WitnessScriptHash), stackitem.Make(util.Uint160{1, 2, 3}.BytesBE())}},
{(*ConditionGroup)(pk.PublicKey()), true, []stackitem.Item{stackitem.Make(WitnessGroup), stackitem.Make(pk.PublicKey().Bytes())}},
{ConditionCalledByEntry{}, true, []stackitem.Item{stackitem.Make(WitnessCalledByEntry)}},
{&ConditionCalledByContract{1, 2, 3}, true, []stackitem.Item{stackitem.Make(WitnessCalledByContract), stackitem.Make(util.Uint160{1, 2, 3}.BytesBE())}},
{(*ConditionCalledByGroup)(pk.PublicKey()), true, []stackitem.Item{stackitem.Make(WitnessCalledByGroup), stackitem.Make(pk.PublicKey().Bytes())}},
{InvalidCondition{}, false, nil},
{&ConditionAnd{}, false, nil},
{&ConditionOr{}, false, nil},
{&ConditionNot{&ConditionNot{&ConditionNot{(*ConditionBoolean)(&someBool)}}}, false, nil},
}
var maxSubCondAnd = &ConditionAnd{}
var maxSubCondOr = &ConditionAnd{}
@ -61,8 +73,8 @@ func TestWitnessConditionSerDes(t *testing.T) {
*maxSubCondAnd = append(*maxSubCondAnd, (*ConditionBoolean)(&someBool))
*maxSubCondOr = append(*maxSubCondOr, (*ConditionBoolean)(&someBool))
}
cases = append(cases, condCase{maxSubCondAnd, false})
cases = append(cases, condCase{maxSubCondOr, false})
cases = append(cases, condCase{maxSubCondAnd, false, nil})
cases = append(cases, condCase{maxSubCondOr, false, nil})
t.Run("binary", func(t *testing.T) {
for i, c := range cases {
w := io.NewBufBinWriter()
@ -94,6 +106,15 @@ func TestWitnessConditionSerDes(t *testing.T) {
require.Equal(t, c.condition, res)
}
})
t.Run("stackitem", func(t *testing.T) {
for i, c := range cases[1:] {
if c.expectedStackItem != nil {
expected := stackitem.NewArray(c.expectedStackItem)
actual := c.condition.ToStackItem()
assert.Equal(t, expected, actual, i)
}
}
})
}
func TestWitnessConditionZeroDeser(t *testing.T) {

View file

@ -3,8 +3,10 @@ package transaction
import (
"encoding/json"
"errors"
"math/big"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)
//go:generate stringer -type=WitnessAction -linecomment
@ -84,3 +86,11 @@ func (w *WitnessRule) UnmarshalJSON(data []byte) error {
w.Condition = cond
return nil
}
// ToStackItem implements Convertible interface.
func (w *WitnessRule) ToStackItem() stackitem.Item {
return stackitem.NewArray([]stackitem.Item{
stackitem.NewBigInteger(big.NewInt(int64(w.Action))),
w.Condition.ToStackItem(),
})
}

View file

@ -5,6 +5,7 @@ import (
"testing"
"github.com/nspcc-dev/neo-go/internal/testserdes"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/stretchr/testify/require"
)
@ -54,3 +55,21 @@ func TestWitnessRuleBadJSON(t *testing.T) {
require.Errorf(t, err, "case %d, json %s", i, cases[i])
}
}
func TestWitnessRule_ToStackItem(t *testing.T) {
var b bool
for _, act := range []WitnessAction{WitnessDeny, WitnessAllow} {
expected := stackitem.NewArray([]stackitem.Item{
stackitem.Make(int64(act)),
stackitem.Make([]stackitem.Item{
stackitem.Make(WitnessBoolean),
stackitem.Make(b),
}),
})
actual := (&WitnessRule{
Action: act,
Condition: (*ConditionBoolean)(&b),
}).ToStackItem()
require.Equal(t, expected, actual, act)
}
}

View file

@ -59,6 +59,12 @@ func GetTransactionFromBlock(indexOrHash interface{}, txIndex int) *Transaction
indexOrHash, txIndex).(*Transaction)
}
// GetTransactionSigners represents `getTransactionSigners` method of Ledger native contract.
func GetTransactionSigners(hash interop.Hash256) []TransactionSigner {
return neogointernal.CallWithToken(Hash, "getTransactionSigners", int(contract.ReadStates),
hash).([]TransactionSigner)
}
// GetTransactionVMState represents `getTransactionVMState` method of Ledger native contract.
func GetTransactionVMState(hash interop.Hash256) VMState {
return neogointernal.CallWithToken(Hash, "getTransactionVMState", int(contract.ReadStates), hash).(VMState)

View file

@ -0,0 +1,116 @@
package ledger
import "github.com/nspcc-dev/neo-go/pkg/interop"
// TransactionSigner represent the signer of a NEO transaction. It's similar to
// Signer class in Neo .net framework.
type TransactionSigner struct {
// Bytes is a binary serialized representation of the given signer.
Bytes []byte
// Account represents the account (160 bit BE value in a 20 byte slice) of
// the given signer.
Account interop.Hash160
// Scopes represents a set of witness flags for the given signer.
Scopes SignerScope
// Contracts represents the set of contract hashes (160 bit BE value in a 20
// byte slice) allowed to be called by the signer. It is only non-empty if
// CustomContracts scope flag is set.
AllowedContracts []interop.Hash160
// AllowedGroups represents the set of contract groups (ecdsa public key
// bytes in a 33 byte slice) allowed to be called by the signer. It is only
// non-empty if CustomGroups scope flag is set.
AllowedGroups []interop.PublicKey
// Rules represents a rule-based witness scope of the given signer. It is
// only non-empty if Rules scope flag is set.
Rules []WitnessRule
}
// SignerScope represents a signer's witness scope.
type SignerScope byte
// Various witness scopes.
const (
// None specifies that no contract was witnessed. Only signs the transaction
// and pays GAS fee if a sender.
None SignerScope = 0
// CalledByEntry means that the witness is valid only when the witness
// checking contract is called from the entry script.
CalledByEntry SignerScope = 0x01
// CustomContracts define custom hash for contract-specific witness.
CustomContracts SignerScope = 0x10
// CustomGroups define custom public key for group members.
CustomGroups SignerScope = 0x20
// Rules is a set of conditions with boolean operators.
Rules SignerScope = 0x40
// Global allows this witness in all contexts. This cannot be combined with
// other flags.
Global SignerScope = 0x80
)
// WitnessRule represents a single rule for Rules witness scope.
type WitnessRule struct {
// Action denotes whether the witness condition should be accepted or denied.
Action WitnessAction
// Condition holds a set of nested witness rules. Max nested depth is 2.
Condition WitnessCondition
}
// WitnessAction represents an action to perform in WitnessRule if
// witness condition matches.
type WitnessAction byte
// Various rule-based witness actions.
const (
// WitnessDeny rejects current witness if condition is met.
WitnessDeny WitnessAction = 0
// WitnessAllow approves current witness if condition is met.
WitnessAllow WitnessAction = 1
)
// WitnessCondition represents a single witness condition for a rule-based
// witness. Its type can always be safely accessed, but trying to access its
// value causes runtime exception for those types that don't have value
// (currently, it's only CalledByEntry witness condition).
type WitnessCondition struct {
Type WitnessConditionType
// Depends on the witness condition Type, its value can be asserted to the
// certain structure according to the following rule:
// WitnessBoolean -> bool
// WitnessNot -> []WitnessCondition with one element
// WitnessAnd -> []WitnessCondition
// WitnessOr -> []WitnessCondition
// WitnessScriptHash -> interop.Hash160
// WitnessGroup -> interop.PublicKey
// WitnessCalledByContract -> interop.Hash160
// WitnessCalledByGroup -> interop.PublicKey
// WitnessCalledByEntry -> doesn't have value, thus, an attempt to access the Value leads to runtime exception.
Value interface{}
}
// WitnessConditionType represents the type of rule-based witness condition.
type WitnessConditionType byte
// Various witness condition types
const (
// WitnessBoolean is a generic boolean condition.
WitnessBoolean WitnessConditionType = 0x00
// WitnessNot reverses another condition.
WitnessNot WitnessConditionType = 0x01
// WitnessAnd means that all conditions must be met.
WitnessAnd WitnessConditionType = 0x02
// WitnessOr means that any of conditions must be met.
WitnessOr WitnessConditionType = 0x03
// WitnessScriptHash matches executing contract's script hash.
WitnessScriptHash WitnessConditionType = 0x18
// WitnessGroup matches executing contract's group key.
WitnessGroup WitnessConditionType = 0x19
// WitnessCalledByEntry matches when current script is an entry script or is
// called by an entry script.
WitnessCalledByEntry WitnessConditionType = 0x20
// WitnessCalledByContract matches when current script is called by the
// specified contract.
WitnessCalledByContract WitnessConditionType = 0x28
// WitnessCalledByGroup matches when current script is called by contract
// belonging to the specified group.
WitnessCalledByGroup WitnessConditionType = 0x29
)

View file

@ -107,8 +107,8 @@ func (e *Executor) SignTx(t testing.TB, tx *transaction.Transaction, sysFee int6
Scopes: transaction.Global,
})
}
addNetworkFee(e.Chain, tx, signers...)
addSystemFee(e.Chain, tx, sysFee)
AddNetworkFee(e.Chain, tx, signers...)
AddSystemFee(e.Chain, tx, sysFee)
for _, acc := range signers {
require.NoError(t, acc.SignTx(e.Chain.GetConfig().Magic, tx))
@ -276,12 +276,14 @@ func NewDeployTxBy(t testing.TB, bc blockchainer.Blockchainer, signer Signer, c
Account: signer.ScriptHash(),
Scopes: transaction.Global,
}}
addNetworkFee(bc, tx, signer)
AddNetworkFee(bc, tx, signer)
require.NoError(t, signer.SignTx(netmode.UnitTestNet, tx))
return tx
}
func addSystemFee(bc blockchainer.Blockchainer, tx *transaction.Transaction, sysFee int64) {
// AddSystemFee adds system fee to the transaction. If negative value specified,
// then system fee is defined by test invocation.
func AddSystemFee(bc blockchainer.Blockchainer, tx *transaction.Transaction, sysFee int64) {
if sysFee >= 0 {
tx.SystemFee = sysFee
return
@ -290,7 +292,8 @@ func addSystemFee(bc blockchainer.Blockchainer, tx *transaction.Transaction, sys
tx.SystemFee = v.GasConsumed()
}
func addNetworkFee(bc blockchainer.Blockchainer, tx *transaction.Transaction, signers ...Signer) {
// AddNetworkFee adds network fee to the transaction.
func AddNetworkFee(bc blockchainer.Blockchainer, tx *transaction.Transaction, signers ...Signer) {
baseFee := bc.GetBaseExecFee()
size := io.GetVarSize(tx)
for _, sgr := range signers {