2023-05-23 11:17:39 +00:00
|
|
|
// Package structs contains RPC wrappers for Notifications contract.
|
|
|
|
package structs
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/elliptic"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
|
|
|
"math/big"
|
2023-05-23 15:20:51 +00:00
|
|
|
"unicode/utf8"
|
2023-05-23 11:17:39 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Hash contains contract hash.
|
|
|
|
var Hash = util.Uint160{0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x0}
|
|
|
|
|
|
|
|
// LedgerBlock is a contract-specific ledger.Block type used by its methods.
|
|
|
|
type LedgerBlock struct {
|
|
|
|
Hash util.Uint256
|
|
|
|
Version *big.Int
|
|
|
|
PrevHash util.Uint256
|
|
|
|
MerkleRoot util.Uint256
|
|
|
|
Timestamp *big.Int
|
|
|
|
Nonce *big.Int
|
|
|
|
Index *big.Int
|
|
|
|
NextConsensus util.Uint160
|
|
|
|
TransactionsLength *big.Int
|
|
|
|
}
|
|
|
|
|
|
|
|
// LedgerBlockSR is a contract-specific ledger.BlockSR type used by its methods.
|
|
|
|
type LedgerBlockSR struct {
|
|
|
|
Hash util.Uint256
|
|
|
|
Version *big.Int
|
|
|
|
PrevHash util.Uint256
|
|
|
|
MerkleRoot util.Uint256
|
|
|
|
Timestamp *big.Int
|
|
|
|
Nonce *big.Int
|
|
|
|
Index *big.Int
|
|
|
|
NextConsensus util.Uint160
|
|
|
|
TransactionsLength *big.Int
|
|
|
|
PrevStateRoot util.Uint256
|
|
|
|
}
|
|
|
|
|
|
|
|
// LedgerTransaction is a contract-specific ledger.Transaction type used by its methods.
|
|
|
|
type LedgerTransaction struct {
|
|
|
|
Hash util.Uint256
|
|
|
|
Version *big.Int
|
|
|
|
Nonce *big.Int
|
|
|
|
Sender util.Uint160
|
|
|
|
SysFee *big.Int
|
|
|
|
NetFee *big.Int
|
|
|
|
ValidUntilBlock *big.Int
|
|
|
|
Script []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
// LedgerTransactionSigner is a contract-specific ledger.TransactionSigner type used by its methods.
|
|
|
|
type LedgerTransactionSigner struct {
|
|
|
|
Account util.Uint160
|
|
|
|
Scopes *big.Int
|
|
|
|
AllowedContracts []util.Uint160
|
|
|
|
AllowedGroups keys.PublicKeys
|
|
|
|
Rules []*LedgerWitnessRule
|
|
|
|
}
|
|
|
|
|
|
|
|
// LedgerWitnessCondition is a contract-specific ledger.WitnessCondition type used by its methods.
|
|
|
|
type LedgerWitnessCondition struct {
|
|
|
|
Type *big.Int
|
|
|
|
Value any
|
|
|
|
}
|
|
|
|
|
|
|
|
// LedgerWitnessRule is a contract-specific ledger.WitnessRule type used by its methods.
|
|
|
|
type LedgerWitnessRule struct {
|
|
|
|
Action *big.Int
|
|
|
|
Condition *LedgerWitnessCondition
|
|
|
|
}
|
|
|
|
|
|
|
|
// ComplicatedNameEvent represents "! complicated name %$#" event emitted by the contract.
|
|
|
|
type ComplicatedNameEvent struct {
|
|
|
|
ComplicatedParam string
|
|
|
|
}
|
|
|
|
|
rpcbinding: support map[any]any conversion for extended types
Unfortunately, without pre-set user extended types configuration for events
and without --guess-eventtypes flag set we are allowed to rely only on manifest
information about types. Manifest can't give us a lot of information, but we
still need to be able to generate RPC binding. Arrays and structs are correctly
handled by the current code, but maps always rely on the fact that map's value
type is set. It's not true in the described case, so make the maps type convertor
handle this situation in a similar way how arrays are handled.
Without this commit the following panic occurs on attempt to generate RPC binding:
```
--- FAIL: TestAssistedRPCBindings/testdata/notifications (0.01s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x7f7c0e]
goroutine 190 [running]:
testing.tRunner.func1.2({0x109cb40, 0x1d58760})
/usr/local/go/src/testing/testing.go:1396 +0x24e
testing.tRunner.func1()
/usr/local/go/src/testing/testing.go:1399 +0x39f
panic({0x109cb40, 0x1d58760})
/usr/local/go/src/runtime/panic.go:884 +0x212
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.extendedTypeToGo({0x22, {0x0, 0x0}, {0x0, 0x0}, 0x0, 0x0, {0x0, 0x0, 0x0}}, ...)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:515 +0x36e
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.scTypeToGo({0xc000206d92?, 0xc000206d80?}, 0x22, 0xc0005d70e0)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:643 +0x138
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.scTemplateToRPC({{0xc00049bb07, 0x7}, 0xc0004c89c0, {0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, ...}, ...}, ...)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:686 +0xbc4
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.Generate({{0xc00049bb07, 0x7}, 0xc0004c89c0, {0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, ...}, ...})
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:421 +0x387
github.com/nspcc-dev/neo-go/cli/smartcontract.contractGenerateSomething(0xc00043e2c0, 0x137cd00)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/generate.go:99 +0x855
github.com/nspcc-dev/neo-go/cli/smartcontract.contractGenerateRPCWrapper(0xc00043e2c0?)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/generate.go:60 +0x25
github.com/urfave/cli.HandleAction({0x1048380?, 0x137c660?}, 0x13?)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:524 +0x50
github.com/urfave/cli.Command.Run({{0x123539d, 0x13}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x12577ad, 0x2a}, {0x127ad35, ...}, ...}, ...)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:173 +0x65b
github.com/urfave/cli.(*App).RunAsSubcommand(0xc0001f4000, 0xc00043e000)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:405 +0x91b
github.com/urfave/cli.Command.startApp({{0x12281e1, 0x8}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x1254d8a, 0x28}, {0x0, ...}, ...}, ...)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:372 +0x6e7
github.com/urfave/cli.Command.Run({{0x12281e1, 0x8}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x1254d8a, 0x28}, {0x0, ...}, ...}, ...)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:102 +0x825
github.com/urfave/cli.(*App).Run(0xc00024e000, {0xc0004f6420, 0xb, 0xb})
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:277 +0x8a7
github.com/nspcc-dev/neo-go/cli/smartcontract.TestAssistedRPCBindings.func1.1(0x9f8829?)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/generate_test.go:395 +0x5fc
testing.tRunner(0xc0006824e0, 0xc0004a3680)
/usr/local/go/src/testing/testing.go:1446 +0x10b
created by testing.(*T).Run
/usr/local/go/src/testing/testing.go:1493 +0x35f
```
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-03 16:13:05 +00:00
|
|
|
// SomeMapEvent represents "SomeMap" event emitted by the contract.
|
|
|
|
type SomeMapEvent struct {
|
|
|
|
M map[any]any
|
|
|
|
}
|
|
|
|
|
|
|
|
// SomeStructEvent represents "SomeStruct" event emitted by the contract.
|
|
|
|
type SomeStructEvent struct {
|
|
|
|
S []any
|
|
|
|
}
|
|
|
|
|
2023-05-23 11:17:39 +00:00
|
|
|
// Actor is used by Contract to call state-changing methods.
|
|
|
|
type Actor interface {
|
|
|
|
MakeCall(contract util.Uint160, method string, params ...any) (*transaction.Transaction, error)
|
|
|
|
MakeRun(script []byte) (*transaction.Transaction, error)
|
|
|
|
MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...any) (*transaction.Transaction, error)
|
|
|
|
MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error)
|
|
|
|
SendCall(contract util.Uint160, method string, params ...any) (util.Uint256, uint32, error)
|
|
|
|
SendRun(script []byte) (util.Uint256, uint32, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Contract implements all contract methods.
|
|
|
|
type Contract struct {
|
|
|
|
actor Actor
|
|
|
|
}
|
|
|
|
|
|
|
|
// New creates an instance of Contract using Hash and the given Actor.
|
|
|
|
func New(actor Actor) *Contract {
|
|
|
|
return &Contract{actor}
|
|
|
|
}
|
|
|
|
|
rpcbinding: support map[any]any conversion for extended types
Unfortunately, without pre-set user extended types configuration for events
and without --guess-eventtypes flag set we are allowed to rely only on manifest
information about types. Manifest can't give us a lot of information, but we
still need to be able to generate RPC binding. Arrays and structs are correctly
handled by the current code, but maps always rely on the fact that map's value
type is set. It's not true in the described case, so make the maps type convertor
handle this situation in a similar way how arrays are handled.
Without this commit the following panic occurs on attempt to generate RPC binding:
```
--- FAIL: TestAssistedRPCBindings/testdata/notifications (0.01s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x7f7c0e]
goroutine 190 [running]:
testing.tRunner.func1.2({0x109cb40, 0x1d58760})
/usr/local/go/src/testing/testing.go:1396 +0x24e
testing.tRunner.func1()
/usr/local/go/src/testing/testing.go:1399 +0x39f
panic({0x109cb40, 0x1d58760})
/usr/local/go/src/runtime/panic.go:884 +0x212
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.extendedTypeToGo({0x22, {0x0, 0x0}, {0x0, 0x0}, 0x0, 0x0, {0x0, 0x0, 0x0}}, ...)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:515 +0x36e
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.scTypeToGo({0xc000206d92?, 0xc000206d80?}, 0x22, 0xc0005d70e0)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:643 +0x138
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.scTemplateToRPC({{0xc00049bb07, 0x7}, 0xc0004c89c0, {0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, ...}, ...}, ...)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:686 +0xbc4
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.Generate({{0xc00049bb07, 0x7}, 0xc0004c89c0, {0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, ...}, ...})
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:421 +0x387
github.com/nspcc-dev/neo-go/cli/smartcontract.contractGenerateSomething(0xc00043e2c0, 0x137cd00)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/generate.go:99 +0x855
github.com/nspcc-dev/neo-go/cli/smartcontract.contractGenerateRPCWrapper(0xc00043e2c0?)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/generate.go:60 +0x25
github.com/urfave/cli.HandleAction({0x1048380?, 0x137c660?}, 0x13?)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:524 +0x50
github.com/urfave/cli.Command.Run({{0x123539d, 0x13}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x12577ad, 0x2a}, {0x127ad35, ...}, ...}, ...)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:173 +0x65b
github.com/urfave/cli.(*App).RunAsSubcommand(0xc0001f4000, 0xc00043e000)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:405 +0x91b
github.com/urfave/cli.Command.startApp({{0x12281e1, 0x8}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x1254d8a, 0x28}, {0x0, ...}, ...}, ...)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:372 +0x6e7
github.com/urfave/cli.Command.Run({{0x12281e1, 0x8}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x1254d8a, 0x28}, {0x0, ...}, ...}, ...)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:102 +0x825
github.com/urfave/cli.(*App).Run(0xc00024e000, {0xc0004f6420, 0xb, 0xb})
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:277 +0x8a7
github.com/nspcc-dev/neo-go/cli/smartcontract.TestAssistedRPCBindings.func1.1(0x9f8829?)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/generate_test.go:395 +0x5fc
testing.tRunner(0xc0006824e0, 0xc0004a3680)
/usr/local/go/src/testing/testing.go:1446 +0x10b
created by testing.(*T).Run
/usr/local/go/src/testing/testing.go:1493 +0x35f
```
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-03 16:13:05 +00:00
|
|
|
// CrazyMap creates a transaction invoking `crazyMap` method of the contract.
|
|
|
|
// This transaction is signed and immediately sent to the network.
|
|
|
|
// The values returned are its hash, ValidUntilBlock value and error if any.
|
|
|
|
func (c *Contract) CrazyMap() (util.Uint256, uint32, error) {
|
|
|
|
return c.actor.SendCall(Hash, "crazyMap")
|
|
|
|
}
|
|
|
|
|
|
|
|
// CrazyMapTransaction creates a transaction invoking `crazyMap` method of the contract.
|
|
|
|
// This transaction is signed, but not sent to the network, instead it's
|
|
|
|
// returned to the caller.
|
|
|
|
func (c *Contract) CrazyMapTransaction() (*transaction.Transaction, error) {
|
|
|
|
return c.actor.MakeCall(Hash, "crazyMap")
|
|
|
|
}
|
|
|
|
|
|
|
|
// CrazyMapUnsigned creates a transaction invoking `crazyMap` method of the contract.
|
|
|
|
// This transaction is not signed, it's simply returned to the caller.
|
|
|
|
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
|
|
|
|
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
|
|
|
|
func (c *Contract) CrazyMapUnsigned() (*transaction.Transaction, error) {
|
|
|
|
return c.actor.MakeUnsignedCall(Hash, "crazyMap", nil)
|
|
|
|
}
|
|
|
|
|
2023-05-23 11:17:39 +00:00
|
|
|
// Main creates a transaction invoking `main` method of the contract.
|
|
|
|
// This transaction is signed and immediately sent to the network.
|
|
|
|
// The values returned are its hash, ValidUntilBlock value and error if any.
|
|
|
|
func (c *Contract) Main() (util.Uint256, uint32, error) {
|
|
|
|
return c.actor.SendCall(Hash, "main")
|
|
|
|
}
|
|
|
|
|
|
|
|
// MainTransaction creates a transaction invoking `main` method of the contract.
|
|
|
|
// This transaction is signed, but not sent to the network, instead it's
|
|
|
|
// returned to the caller.
|
|
|
|
func (c *Contract) MainTransaction() (*transaction.Transaction, error) {
|
|
|
|
return c.actor.MakeCall(Hash, "main")
|
|
|
|
}
|
|
|
|
|
|
|
|
// MainUnsigned creates a transaction invoking `main` method of the contract.
|
|
|
|
// This transaction is not signed, it's simply returned to the caller.
|
|
|
|
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
|
|
|
|
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
|
|
|
|
func (c *Contract) MainUnsigned() (*transaction.Transaction, error) {
|
|
|
|
return c.actor.MakeUnsignedCall(Hash, "main", nil)
|
|
|
|
}
|
|
|
|
|
rpcbinding: support map[any]any conversion for extended types
Unfortunately, without pre-set user extended types configuration for events
and without --guess-eventtypes flag set we are allowed to rely only on manifest
information about types. Manifest can't give us a lot of information, but we
still need to be able to generate RPC binding. Arrays and structs are correctly
handled by the current code, but maps always rely on the fact that map's value
type is set. It's not true in the described case, so make the maps type convertor
handle this situation in a similar way how arrays are handled.
Without this commit the following panic occurs on attempt to generate RPC binding:
```
--- FAIL: TestAssistedRPCBindings/testdata/notifications (0.01s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x7f7c0e]
goroutine 190 [running]:
testing.tRunner.func1.2({0x109cb40, 0x1d58760})
/usr/local/go/src/testing/testing.go:1396 +0x24e
testing.tRunner.func1()
/usr/local/go/src/testing/testing.go:1399 +0x39f
panic({0x109cb40, 0x1d58760})
/usr/local/go/src/runtime/panic.go:884 +0x212
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.extendedTypeToGo({0x22, {0x0, 0x0}, {0x0, 0x0}, 0x0, 0x0, {0x0, 0x0, 0x0}}, ...)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:515 +0x36e
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.scTypeToGo({0xc000206d92?, 0xc000206d80?}, 0x22, 0xc0005d70e0)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:643 +0x138
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.scTemplateToRPC({{0xc00049bb07, 0x7}, 0xc0004c89c0, {0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, ...}, ...}, ...)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:686 +0xbc4
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.Generate({{0xc00049bb07, 0x7}, 0xc0004c89c0, {0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, ...}, ...})
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:421 +0x387
github.com/nspcc-dev/neo-go/cli/smartcontract.contractGenerateSomething(0xc00043e2c0, 0x137cd00)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/generate.go:99 +0x855
github.com/nspcc-dev/neo-go/cli/smartcontract.contractGenerateRPCWrapper(0xc00043e2c0?)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/generate.go:60 +0x25
github.com/urfave/cli.HandleAction({0x1048380?, 0x137c660?}, 0x13?)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:524 +0x50
github.com/urfave/cli.Command.Run({{0x123539d, 0x13}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x12577ad, 0x2a}, {0x127ad35, ...}, ...}, ...)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:173 +0x65b
github.com/urfave/cli.(*App).RunAsSubcommand(0xc0001f4000, 0xc00043e000)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:405 +0x91b
github.com/urfave/cli.Command.startApp({{0x12281e1, 0x8}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x1254d8a, 0x28}, {0x0, ...}, ...}, ...)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:372 +0x6e7
github.com/urfave/cli.Command.Run({{0x12281e1, 0x8}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x1254d8a, 0x28}, {0x0, ...}, ...}, ...)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:102 +0x825
github.com/urfave/cli.(*App).Run(0xc00024e000, {0xc0004f6420, 0xb, 0xb})
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:277 +0x8a7
github.com/nspcc-dev/neo-go/cli/smartcontract.TestAssistedRPCBindings.func1.1(0x9f8829?)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/generate_test.go:395 +0x5fc
testing.tRunner(0xc0006824e0, 0xc0004a3680)
/usr/local/go/src/testing/testing.go:1446 +0x10b
created by testing.(*T).Run
/usr/local/go/src/testing/testing.go:1493 +0x35f
```
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-03 16:13:05 +00:00
|
|
|
// Struct creates a transaction invoking `struct` method of the contract.
|
|
|
|
// This transaction is signed and immediately sent to the network.
|
|
|
|
// The values returned are its hash, ValidUntilBlock value and error if any.
|
|
|
|
func (c *Contract) Struct() (util.Uint256, uint32, error) {
|
|
|
|
return c.actor.SendCall(Hash, "struct")
|
|
|
|
}
|
|
|
|
|
|
|
|
// StructTransaction creates a transaction invoking `struct` method of the contract.
|
|
|
|
// This transaction is signed, but not sent to the network, instead it's
|
|
|
|
// returned to the caller.
|
|
|
|
func (c *Contract) StructTransaction() (*transaction.Transaction, error) {
|
|
|
|
return c.actor.MakeCall(Hash, "struct")
|
|
|
|
}
|
|
|
|
|
|
|
|
// StructUnsigned creates a transaction invoking `struct` method of the contract.
|
|
|
|
// This transaction is not signed, it's simply returned to the caller.
|
|
|
|
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
|
|
|
|
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
|
|
|
|
func (c *Contract) StructUnsigned() (*transaction.Transaction, error) {
|
|
|
|
return c.actor.MakeUnsignedCall(Hash, "struct", nil)
|
|
|
|
}
|
|
|
|
|
2023-05-23 11:17:39 +00:00
|
|
|
// itemToLedgerBlock converts stack item into *LedgerBlock.
|
|
|
|
func itemToLedgerBlock(item stackitem.Item, err error) (*LedgerBlock, error) {
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
var res = new(LedgerBlock)
|
|
|
|
err = res.FromStackItem(item)
|
|
|
|
return res, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// FromStackItem retrieves fields of LedgerBlock from the given stack item
|
|
|
|
// and returns an error if so.
|
|
|
|
func (res *LedgerBlock) FromStackItem(item stackitem.Item) error {
|
|
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
|
|
if !ok {
|
|
|
|
return errors.New("not an array")
|
|
|
|
}
|
|
|
|
if len(arr) != 9 {
|
|
|
|
return errors.New("wrong number of structure elements")
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
index = -1
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
index++
|
|
|
|
res.Hash, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
|
|
b, err := item.TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint256{}, err
|
|
|
|
}
|
|
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint256{}, err
|
|
|
|
}
|
|
|
|
return u, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Hash: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.Version, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Version: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.PrevHash, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
|
|
b, err := item.TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint256{}, err
|
|
|
|
}
|
|
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint256{}, err
|
|
|
|
}
|
|
|
|
return u, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field PrevHash: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.MerkleRoot, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
|
|
b, err := item.TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint256{}, err
|
|
|
|
}
|
|
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint256{}, err
|
|
|
|
}
|
|
|
|
return u, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field MerkleRoot: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.Timestamp, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Timestamp: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.Nonce, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Nonce: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.Index, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Index: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.NextConsensus, err = func (item stackitem.Item) (util.Uint160, error) {
|
|
|
|
b, err := item.TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint160{}, err
|
|
|
|
}
|
|
|
|
u, err := util.Uint160DecodeBytesBE(b)
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint160{}, err
|
|
|
|
}
|
|
|
|
return u, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field NextConsensus: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.TransactionsLength, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field TransactionsLength: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// itemToLedgerBlockSR converts stack item into *LedgerBlockSR.
|
|
|
|
func itemToLedgerBlockSR(item stackitem.Item, err error) (*LedgerBlockSR, error) {
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
var res = new(LedgerBlockSR)
|
|
|
|
err = res.FromStackItem(item)
|
|
|
|
return res, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// FromStackItem retrieves fields of LedgerBlockSR from the given stack item
|
|
|
|
// and returns an error if so.
|
|
|
|
func (res *LedgerBlockSR) FromStackItem(item stackitem.Item) error {
|
|
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
|
|
if !ok {
|
|
|
|
return errors.New("not an array")
|
|
|
|
}
|
|
|
|
if len(arr) != 10 {
|
|
|
|
return errors.New("wrong number of structure elements")
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
index = -1
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
index++
|
|
|
|
res.Hash, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
|
|
b, err := item.TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint256{}, err
|
|
|
|
}
|
|
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint256{}, err
|
|
|
|
}
|
|
|
|
return u, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Hash: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.Version, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Version: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.PrevHash, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
|
|
b, err := item.TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint256{}, err
|
|
|
|
}
|
|
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint256{}, err
|
|
|
|
}
|
|
|
|
return u, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field PrevHash: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.MerkleRoot, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
|
|
b, err := item.TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint256{}, err
|
|
|
|
}
|
|
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint256{}, err
|
|
|
|
}
|
|
|
|
return u, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field MerkleRoot: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.Timestamp, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Timestamp: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.Nonce, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Nonce: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.Index, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Index: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.NextConsensus, err = func (item stackitem.Item) (util.Uint160, error) {
|
|
|
|
b, err := item.TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint160{}, err
|
|
|
|
}
|
|
|
|
u, err := util.Uint160DecodeBytesBE(b)
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint160{}, err
|
|
|
|
}
|
|
|
|
return u, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field NextConsensus: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.TransactionsLength, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field TransactionsLength: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.PrevStateRoot, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
|
|
b, err := item.TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint256{}, err
|
|
|
|
}
|
|
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint256{}, err
|
|
|
|
}
|
|
|
|
return u, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field PrevStateRoot: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// itemToLedgerTransaction converts stack item into *LedgerTransaction.
|
|
|
|
func itemToLedgerTransaction(item stackitem.Item, err error) (*LedgerTransaction, error) {
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
var res = new(LedgerTransaction)
|
|
|
|
err = res.FromStackItem(item)
|
|
|
|
return res, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// FromStackItem retrieves fields of LedgerTransaction from the given stack item
|
|
|
|
// and returns an error if so.
|
|
|
|
func (res *LedgerTransaction) FromStackItem(item stackitem.Item) error {
|
|
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
|
|
if !ok {
|
|
|
|
return errors.New("not an array")
|
|
|
|
}
|
|
|
|
if len(arr) != 8 {
|
|
|
|
return errors.New("wrong number of structure elements")
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
index = -1
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
index++
|
|
|
|
res.Hash, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
|
|
b, err := item.TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint256{}, err
|
|
|
|
}
|
|
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint256{}, err
|
|
|
|
}
|
|
|
|
return u, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Hash: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.Version, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Version: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.Nonce, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Nonce: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.Sender, err = func (item stackitem.Item) (util.Uint160, error) {
|
|
|
|
b, err := item.TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint160{}, err
|
|
|
|
}
|
|
|
|
u, err := util.Uint160DecodeBytesBE(b)
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint160{}, err
|
|
|
|
}
|
|
|
|
return u, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Sender: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.SysFee, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field SysFee: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.NetFee, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field NetFee: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.ValidUntilBlock, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field ValidUntilBlock: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.Script, err = arr[index].TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Script: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// itemToLedgerTransactionSigner converts stack item into *LedgerTransactionSigner.
|
|
|
|
func itemToLedgerTransactionSigner(item stackitem.Item, err error) (*LedgerTransactionSigner, error) {
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
var res = new(LedgerTransactionSigner)
|
|
|
|
err = res.FromStackItem(item)
|
|
|
|
return res, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// FromStackItem retrieves fields of LedgerTransactionSigner from the given stack item
|
|
|
|
// and returns an error if so.
|
|
|
|
func (res *LedgerTransactionSigner) FromStackItem(item stackitem.Item) error {
|
|
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
|
|
if !ok {
|
|
|
|
return errors.New("not an array")
|
|
|
|
}
|
|
|
|
if len(arr) != 5 {
|
|
|
|
return errors.New("wrong number of structure elements")
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
index = -1
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
index++
|
|
|
|
res.Account, err = func (item stackitem.Item) (util.Uint160, error) {
|
|
|
|
b, err := item.TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint160{}, err
|
|
|
|
}
|
|
|
|
u, err := util.Uint160DecodeBytesBE(b)
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint160{}, err
|
|
|
|
}
|
|
|
|
return u, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Account: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.Scopes, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Scopes: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.AllowedContracts, err = func (item stackitem.Item) ([]util.Uint160, error) {
|
|
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
|
|
if !ok {
|
|
|
|
return nil, errors.New("not an array")
|
|
|
|
}
|
|
|
|
res := make([]util.Uint160, len(arr))
|
|
|
|
for i := range res {
|
|
|
|
res[i], err = func (item stackitem.Item) (util.Uint160, error) {
|
|
|
|
b, err := item.TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint160{}, err
|
|
|
|
}
|
|
|
|
u, err := util.Uint160DecodeBytesBE(b)
|
|
|
|
if err != nil {
|
|
|
|
return util.Uint160{}, err
|
|
|
|
}
|
|
|
|
return u, nil
|
|
|
|
} (arr[i])
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field AllowedContracts: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.AllowedGroups, err = func (item stackitem.Item) (keys.PublicKeys, error) {
|
|
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
|
|
if !ok {
|
|
|
|
return nil, errors.New("not an array")
|
|
|
|
}
|
|
|
|
res := make(keys.PublicKeys, len(arr))
|
|
|
|
for i := range res {
|
|
|
|
res[i], err = func (item stackitem.Item) (*keys.PublicKey, error) {
|
|
|
|
b, err := item.TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
k, err := keys.NewPublicKeyFromBytes(b, elliptic.P256())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return k, nil
|
|
|
|
} (arr[i])
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field AllowedGroups: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.Rules, err = func (item stackitem.Item) ([]*LedgerWitnessRule, error) {
|
|
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
|
|
if !ok {
|
|
|
|
return nil, errors.New("not an array")
|
|
|
|
}
|
|
|
|
res := make([]*LedgerWitnessRule, len(arr))
|
|
|
|
for i := range res {
|
|
|
|
res[i], err = itemToLedgerWitnessRule(arr[i], nil)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Rules: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// itemToLedgerWitnessCondition converts stack item into *LedgerWitnessCondition.
|
|
|
|
func itemToLedgerWitnessCondition(item stackitem.Item, err error) (*LedgerWitnessCondition, error) {
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
var res = new(LedgerWitnessCondition)
|
|
|
|
err = res.FromStackItem(item)
|
|
|
|
return res, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// FromStackItem retrieves fields of LedgerWitnessCondition from the given stack item
|
|
|
|
// and returns an error if so.
|
|
|
|
func (res *LedgerWitnessCondition) FromStackItem(item stackitem.Item) error {
|
|
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
|
|
if !ok {
|
|
|
|
return errors.New("not an array")
|
|
|
|
}
|
|
|
|
if len(arr) != 2 {
|
|
|
|
return errors.New("wrong number of structure elements")
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
index = -1
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
index++
|
|
|
|
res.Type, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Type: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.Value, err = arr[index].Value(), error(nil)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Value: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// itemToLedgerWitnessRule converts stack item into *LedgerWitnessRule.
|
|
|
|
func itemToLedgerWitnessRule(item stackitem.Item, err error) (*LedgerWitnessRule, error) {
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
var res = new(LedgerWitnessRule)
|
|
|
|
err = res.FromStackItem(item)
|
|
|
|
return res, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// FromStackItem retrieves fields of LedgerWitnessRule from the given stack item
|
|
|
|
// and returns an error if so.
|
|
|
|
func (res *LedgerWitnessRule) FromStackItem(item stackitem.Item) error {
|
|
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
|
|
if !ok {
|
|
|
|
return errors.New("not an array")
|
|
|
|
}
|
|
|
|
if len(arr) != 2 {
|
|
|
|
return errors.New("wrong number of structure elements")
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
index = -1
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
index++
|
|
|
|
res.Action, err = arr[index].TryInteger()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Action: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
index++
|
|
|
|
res.Condition, err = itemToLedgerWitnessCondition(arr[index], nil)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field Condition: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ComplicatedNameEventsFromApplicationLog retrieves a set of all emitted events
|
|
|
|
// with "! complicated name %$#" name from the provided ApplicationLog.
|
|
|
|
func ComplicatedNameEventsFromApplicationLog(log *result.ApplicationLog) ([]*ComplicatedNameEvent, error) {
|
|
|
|
if log == nil {
|
|
|
|
return nil, errors.New("nil application log")
|
|
|
|
}
|
|
|
|
|
|
|
|
var res []*ComplicatedNameEvent
|
|
|
|
for i, ex := range log.Executions {
|
|
|
|
for j, e := range ex.Events {
|
|
|
|
if e.Name != "! complicated name %$#" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
event := new(ComplicatedNameEvent)
|
|
|
|
err := event.FromStackItem(e.Item)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to deserialize ComplicatedNameEvent from stackitem (execution %d, event %d): %w", i, j, err)
|
|
|
|
}
|
|
|
|
res = append(res, event)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return res, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// FromStackItem converts provided stackitem.Array to ComplicatedNameEvent and
|
|
|
|
// returns an error if so.
|
|
|
|
func (e *ComplicatedNameEvent) FromStackItem(item *stackitem.Array) error {
|
|
|
|
if item == nil {
|
|
|
|
return errors.New("nil item")
|
|
|
|
}
|
|
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
|
|
if !ok {
|
|
|
|
return errors.New("not an array")
|
|
|
|
}
|
|
|
|
if len(arr) != 1 {
|
|
|
|
return errors.New("wrong number of structure elements")
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
index = -1
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
index++
|
|
|
|
e.ComplicatedParam, err = func (item stackitem.Item) (string, error) {
|
|
|
|
b, err := item.TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
if !utf8.Valid(b) {
|
|
|
|
return "", errors.New("not a UTF-8 string")
|
|
|
|
}
|
|
|
|
return string(b), nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field ComplicatedParam: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
rpcbinding: support map[any]any conversion for extended types
Unfortunately, without pre-set user extended types configuration for events
and without --guess-eventtypes flag set we are allowed to rely only on manifest
information about types. Manifest can't give us a lot of information, but we
still need to be able to generate RPC binding. Arrays and structs are correctly
handled by the current code, but maps always rely on the fact that map's value
type is set. It's not true in the described case, so make the maps type convertor
handle this situation in a similar way how arrays are handled.
Without this commit the following panic occurs on attempt to generate RPC binding:
```
--- FAIL: TestAssistedRPCBindings/testdata/notifications (0.01s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x7f7c0e]
goroutine 190 [running]:
testing.tRunner.func1.2({0x109cb40, 0x1d58760})
/usr/local/go/src/testing/testing.go:1396 +0x24e
testing.tRunner.func1()
/usr/local/go/src/testing/testing.go:1399 +0x39f
panic({0x109cb40, 0x1d58760})
/usr/local/go/src/runtime/panic.go:884 +0x212
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.extendedTypeToGo({0x22, {0x0, 0x0}, {0x0, 0x0}, 0x0, 0x0, {0x0, 0x0, 0x0}}, ...)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:515 +0x36e
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.scTypeToGo({0xc000206d92?, 0xc000206d80?}, 0x22, 0xc0005d70e0)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:643 +0x138
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.scTemplateToRPC({{0xc00049bb07, 0x7}, 0xc0004c89c0, {0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, ...}, ...}, ...)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:686 +0xbc4
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.Generate({{0xc00049bb07, 0x7}, 0xc0004c89c0, {0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, ...}, ...})
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:421 +0x387
github.com/nspcc-dev/neo-go/cli/smartcontract.contractGenerateSomething(0xc00043e2c0, 0x137cd00)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/generate.go:99 +0x855
github.com/nspcc-dev/neo-go/cli/smartcontract.contractGenerateRPCWrapper(0xc00043e2c0?)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/generate.go:60 +0x25
github.com/urfave/cli.HandleAction({0x1048380?, 0x137c660?}, 0x13?)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:524 +0x50
github.com/urfave/cli.Command.Run({{0x123539d, 0x13}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x12577ad, 0x2a}, {0x127ad35, ...}, ...}, ...)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:173 +0x65b
github.com/urfave/cli.(*App).RunAsSubcommand(0xc0001f4000, 0xc00043e000)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:405 +0x91b
github.com/urfave/cli.Command.startApp({{0x12281e1, 0x8}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x1254d8a, 0x28}, {0x0, ...}, ...}, ...)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:372 +0x6e7
github.com/urfave/cli.Command.Run({{0x12281e1, 0x8}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x1254d8a, 0x28}, {0x0, ...}, ...}, ...)
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:102 +0x825
github.com/urfave/cli.(*App).Run(0xc00024e000, {0xc0004f6420, 0xb, 0xb})
/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:277 +0x8a7
github.com/nspcc-dev/neo-go/cli/smartcontract.TestAssistedRPCBindings.func1.1(0x9f8829?)
/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/generate_test.go:395 +0x5fc
testing.tRunner(0xc0006824e0, 0xc0004a3680)
/usr/local/go/src/testing/testing.go:1446 +0x10b
created by testing.(*T).Run
/usr/local/go/src/testing/testing.go:1493 +0x35f
```
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-03 16:13:05 +00:00
|
|
|
|
|
|
|
// SomeMapEventsFromApplicationLog retrieves a set of all emitted events
|
|
|
|
// with "SomeMap" name from the provided ApplicationLog.
|
|
|
|
func SomeMapEventsFromApplicationLog(log *result.ApplicationLog) ([]*SomeMapEvent, error) {
|
|
|
|
if log == nil {
|
|
|
|
return nil, errors.New("nil application log")
|
|
|
|
}
|
|
|
|
|
|
|
|
var res []*SomeMapEvent
|
|
|
|
for i, ex := range log.Executions {
|
|
|
|
for j, e := range ex.Events {
|
|
|
|
if e.Name != "SomeMap" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
event := new(SomeMapEvent)
|
|
|
|
err := event.FromStackItem(e.Item)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to deserialize SomeMapEvent from stackitem (execution %d, event %d): %w", i, j, err)
|
|
|
|
}
|
|
|
|
res = append(res, event)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return res, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// FromStackItem converts provided stackitem.Array to SomeMapEvent and
|
|
|
|
// returns an error if so.
|
|
|
|
func (e *SomeMapEvent) FromStackItem(item *stackitem.Array) error {
|
|
|
|
if item == nil {
|
|
|
|
return errors.New("nil item")
|
|
|
|
}
|
|
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
|
|
if !ok {
|
|
|
|
return errors.New("not an array")
|
|
|
|
}
|
|
|
|
if len(arr) != 1 {
|
|
|
|
return errors.New("wrong number of structure elements")
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
index = -1
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
index++
|
|
|
|
e.M, err = func (item stackitem.Item) (map[any]any, error) {
|
|
|
|
m, ok := item.Value().([]stackitem.MapElement)
|
|
|
|
if !ok {
|
|
|
|
return nil, fmt.Errorf("%s is not a map", item.Type().String())
|
|
|
|
}
|
|
|
|
res := make(map[any]any)
|
|
|
|
for i := range m {
|
|
|
|
k, err := m[i].Key.Value(), error(nil)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("key %d: %w", i, err)
|
|
|
|
}
|
|
|
|
v, err := m[i].Value.Value(), error(nil)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("value %d: %w", i, err)
|
|
|
|
}
|
|
|
|
res[k] = v
|
|
|
|
}
|
|
|
|
return res, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field M: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// SomeStructEventsFromApplicationLog retrieves a set of all emitted events
|
|
|
|
// with "SomeStruct" name from the provided ApplicationLog.
|
|
|
|
func SomeStructEventsFromApplicationLog(log *result.ApplicationLog) ([]*SomeStructEvent, error) {
|
|
|
|
if log == nil {
|
|
|
|
return nil, errors.New("nil application log")
|
|
|
|
}
|
|
|
|
|
|
|
|
var res []*SomeStructEvent
|
|
|
|
for i, ex := range log.Executions {
|
|
|
|
for j, e := range ex.Events {
|
|
|
|
if e.Name != "SomeStruct" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
event := new(SomeStructEvent)
|
|
|
|
err := event.FromStackItem(e.Item)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to deserialize SomeStructEvent from stackitem (execution %d, event %d): %w", i, j, err)
|
|
|
|
}
|
|
|
|
res = append(res, event)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return res, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// FromStackItem converts provided stackitem.Array to SomeStructEvent and
|
|
|
|
// returns an error if so.
|
|
|
|
func (e *SomeStructEvent) FromStackItem(item *stackitem.Array) error {
|
|
|
|
if item == nil {
|
|
|
|
return errors.New("nil item")
|
|
|
|
}
|
|
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
|
|
if !ok {
|
|
|
|
return errors.New("not an array")
|
|
|
|
}
|
|
|
|
if len(arr) != 1 {
|
|
|
|
return errors.New("wrong number of structure elements")
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
index = -1
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
index++
|
|
|
|
e.S, err = func (item stackitem.Item) ([]any, error) {
|
|
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
|
|
if !ok {
|
|
|
|
return nil, errors.New("not an array")
|
|
|
|
}
|
|
|
|
res := make([]any, len(arr))
|
|
|
|
for i := range res {
|
|
|
|
res[i], err = arr[i].Value(), error(nil)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res, nil
|
|
|
|
} (arr[index])
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("field S: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|