mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-25 23:42:23 +00:00
cli: fetch extended evet types from contract config
The user should specify it via parameter's `extendedtype` field and via upper-level `namedtypes` field of the contract configuration YAML. Also, as we have proper event structure source, make the `--guess-eventtype` compilation option and make event types guess optional. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
This commit is contained in:
parent
194639bb15
commit
e2580187a1
8 changed files with 216 additions and 36 deletions
|
@ -24,6 +24,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/management"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/management"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/binding"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -125,7 +126,7 @@ func NewCommands() []cli.Command {
|
||||||
{
|
{
|
||||||
Name: "compile",
|
Name: "compile",
|
||||||
Usage: "compile a smart contract to a .nef file",
|
Usage: "compile a smart contract to a .nef file",
|
||||||
UsageText: "neo-go contract compile -i path [-o nef] [-v] [-d] [-m manifest] [-c yaml] [--bindings file] [--no-standards] [--no-events] [--no-permissions]",
|
UsageText: "neo-go contract compile -i path [-o nef] [-v] [-d] [-m manifest] [-c yaml] [--bindings file] [--no-standards] [--no-events] [--no-permissions] [--guess-eventtypes]",
|
||||||
Description: `Compiles given smart contract to a .nef file and emits other associated
|
Description: `Compiles given smart contract to a .nef file and emits other associated
|
||||||
information (manifest, bindings configuration, debug information files) if
|
information (manifest, bindings configuration, debug information files) if
|
||||||
asked to. If none of --out, --manifest, --config, --bindings flags are specified,
|
asked to. If none of --out, --manifest, --config, --bindings flags are specified,
|
||||||
|
@ -171,6 +172,10 @@ func NewCommands() []cli.Command {
|
||||||
Name: "no-permissions",
|
Name: "no-permissions",
|
||||||
Usage: "do not check if invoked contracts are allowed in manifest",
|
Usage: "do not check if invoked contracts are allowed in manifest",
|
||||||
},
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "guess-eventtypes",
|
||||||
|
Usage: "guess event types for smart-contract bindings configuration from the code usages",
|
||||||
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "bindings",
|
Name: "bindings",
|
||||||
Usage: "output file for smart-contract bindings configuration",
|
Usage: "output file for smart-contract bindings configuration",
|
||||||
|
@ -352,17 +357,19 @@ func initSmartContract(ctx *cli.Context) error {
|
||||||
SourceURL: "http://example.com/",
|
SourceURL: "http://example.com/",
|
||||||
SupportedStandards: []string{},
|
SupportedStandards: []string{},
|
||||||
SafeMethods: []string{},
|
SafeMethods: []string{},
|
||||||
Events: []manifest.Event{
|
Events: []compiler.HybridEvent{
|
||||||
{
|
{
|
||||||
Name: "Hello world!",
|
Name: "Hello world!",
|
||||||
Parameters: []manifest.Parameter{
|
Parameters: []compiler.HybridParameter{
|
||||||
{
|
{
|
||||||
|
Parameter: manifest.Parameter{
|
||||||
Name: "args",
|
Name: "args",
|
||||||
Type: smartcontract.ArrayType,
|
Type: smartcontract.ArrayType,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
Permissions: []permission{permission(*manifest.NewPermission(manifest.PermissionWildcard))},
|
Permissions: []permission{permission(*manifest.NewPermission(manifest.PermissionWildcard))},
|
||||||
}
|
}
|
||||||
b, err := yaml.Marshal(m)
|
b, err := yaml.Marshal(m)
|
||||||
|
@ -447,6 +454,8 @@ func contractCompile(ctx *cli.Context) error {
|
||||||
NoStandardCheck: ctx.Bool("no-standards"),
|
NoStandardCheck: ctx.Bool("no-standards"),
|
||||||
NoEventsCheck: ctx.Bool("no-events"),
|
NoEventsCheck: ctx.Bool("no-events"),
|
||||||
NoPermissionsCheck: ctx.Bool("no-permissions"),
|
NoPermissionsCheck: ctx.Bool("no-permissions"),
|
||||||
|
|
||||||
|
GuessEventTypes: ctx.Bool("guess-eventtypes"),
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(confFile) != 0 {
|
if len(confFile) != 0 {
|
||||||
|
@ -457,6 +466,7 @@ func contractCompile(ctx *cli.Context) error {
|
||||||
o.Name = conf.Name
|
o.Name = conf.Name
|
||||||
o.SourceURL = conf.SourceURL
|
o.SourceURL = conf.SourceURL
|
||||||
o.ContractEvents = conf.Events
|
o.ContractEvents = conf.Events
|
||||||
|
o.DeclaredNamedTypes = conf.NamedTypes
|
||||||
o.ContractSupportedStandards = conf.SupportedStandards
|
o.ContractSupportedStandards = conf.SupportedStandards
|
||||||
o.Permissions = make([]manifest.Permission, len(conf.Permissions))
|
o.Permissions = make([]manifest.Permission, len(conf.Permissions))
|
||||||
for i := range conf.Permissions {
|
for i := range conf.Permissions {
|
||||||
|
@ -705,9 +715,10 @@ type ProjectConfig struct {
|
||||||
SourceURL string
|
SourceURL string
|
||||||
SafeMethods []string
|
SafeMethods []string
|
||||||
SupportedStandards []string
|
SupportedStandards []string
|
||||||
Events []manifest.Event
|
Events []compiler.HybridEvent
|
||||||
Permissions []permission
|
Permissions []permission
|
||||||
Overloads map[string]string `yaml:"overloads,omitempty"`
|
Overloads map[string]string `yaml:"overloads,omitempty"`
|
||||||
|
NamedTypes map[string]binding.ExtendedType `yaml:"namedtypes,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func inspect(ctx *cli.Context) error {
|
func inspect(ctx *cli.Context) error {
|
||||||
|
|
105
docs/compiler.md
105
docs/compiler.md
|
@ -472,10 +472,113 @@ and structures. Notice that structured types returned by methods can't be Null
|
||||||
at the moment (see #2795).
|
at the moment (see #2795).
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./bin/neo-go contract compile -i contract.go --config contract.yml -o contract.nef --manifest manifest.json --bindings contract.bindings.yml
|
$ ./bin/neo-go contract compile -i contract.go --config contract.yml -o contract.nef --manifest manifest.json --bindings contract.bindings.yml --guess-eventtypes
|
||||||
$ ./bin/neo-go contract generate-rpcwrapper --manifest manifest.json --config contract.bindings.yml --out rpcwrapper.go --hash 0x1b4357bff5a01bdf2a6581247cf9ed1e24629176
|
$ ./bin/neo-go contract generate-rpcwrapper --manifest manifest.json --config contract.bindings.yml --out rpcwrapper.go --hash 0x1b4357bff5a01bdf2a6581247cf9ed1e24629176
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Contract-specific RPC-bindings generated by "generate-rpcwrapper" command include
|
||||||
|
structure wrappers for each event declared in the contract manifest as far as the
|
||||||
|
set of helpers that allow to retrieve emitted event from the application log or
|
||||||
|
from stackitem. By default, event wrappers builder use event structure that was
|
||||||
|
described in the manifest. Since the type data available in the manifest is
|
||||||
|
limited, in some cases the resulting generated event structure may use generic
|
||||||
|
go types. Go contracts can make use of additional type data from bindings
|
||||||
|
configuration file generated during compilation. Like for any other contract
|
||||||
|
types, this can cover arrays, maps and structures. To reach the maximum
|
||||||
|
resemblance between the emitted events and the generated event wrappers, we
|
||||||
|
recommend either to fill in the extended events type information in the contract
|
||||||
|
configuration file before the compilation or to use `--guess-eventtypes`
|
||||||
|
compilation option.
|
||||||
|
|
||||||
|
If using `--guess-eventtypes` compilation option, event parameter types will be
|
||||||
|
guessed from the arguments of `runtime.Notify` calls for each emitted event. If
|
||||||
|
multiple calls of `runtime.Notify` are found, then argument types will be checked
|
||||||
|
for matching (guessed types must be the same across the particular event usages).
|
||||||
|
After that, the extended types binding configuration will be generated according
|
||||||
|
to the emitted events parameter types. `--guess-eventtypes` compilation option
|
||||||
|
is able to recognize those events that has a constant name known at a compilation
|
||||||
|
time and do not include variadic arguments usage. Thus, use this option if your
|
||||||
|
contract suites these requirements. Otherwise, we recommend to manually specify
|
||||||
|
extended event parameter types information in the contract configuration file.
|
||||||
|
|
||||||
|
Extended event parameter type information can be provided manually via contract
|
||||||
|
configuration file under the `events` section. Each event parameter specified in
|
||||||
|
this section may be supplied with additional parameter type information specified
|
||||||
|
under `extendedtype` subsection. The extended type information (`ExtendedType`)
|
||||||
|
has the following structure:
|
||||||
|
|
||||||
|
| Field | Type | Required | Meaning |
|
||||||
|
|-------------|---------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| `base` | Any valid [NEP-14 parameter type](https://github.com/neo-project/proposals/blob/master/nep-14.mediawiki#parametertype) except `Void`. | Always required. | The base type of a parameter, e.g. `Array` for go structures and any nested arrays, `Map` for nested maps, `Hash160` for 160-bits integers, etc. |
|
||||||
|
| `name` | `string` | Required for structures, omitted for arrays, interfaces and maps. | Name of a structure that will be used in the resulting RPC binding. |
|
||||||
|
| `interface` | `string` | Required for `InteropInterface`-based types, currently `iterator` only is supported. | Underlying value of the `InteropInterface`. |
|
||||||
|
| `key` | Any simple [NEP-14 parameter type](https://github.com/neo-project/proposals/blob/master/nep-14.mediawiki#parametertype). | Required for `Map`-based types. | Key type for maps. |
|
||||||
|
| `value` | `ExtendedType`. | Required for iterators, arrays and maps. | Value type of iterators, arrays and maps. |
|
||||||
|
| `fields` | Array of `FieldExtendedType`. | Required for structures. | Ordered type data for structure fields. |
|
||||||
|
|
||||||
|
The structure's field extended information (`FieldExtendedType`) has the following structure:
|
||||||
|
|
||||||
|
| Field | Type | Required | Meaning |
|
||||||
|
|------------------------|----------------|------------------|-----------------------------------------------------------------------------|
|
||||||
|
| `field` | `string` | Always required. | Name of the structure field that will be used in the resulting RPC binding. |
|
||||||
|
| Inlined `ExtendedType` | `ExtendedType` | Always required. | The extended type information about structure field. |
|
||||||
|
|
||||||
|
|
||||||
|
Any named structures used in the `ExtendedType` description must be manually
|
||||||
|
specified in the contract configuration file under top-level `namedtypes` section
|
||||||
|
in the form of `map[string]ExtendedType`, where the map key is a name of the
|
||||||
|
described named structure that matches the one provided in the `name` field of
|
||||||
|
the event parameter's extended type.
|
||||||
|
|
||||||
|
Here's the example of manually-created contract configuration file that uses
|
||||||
|
extended types for event parameters description:
|
||||||
|
|
||||||
|
```
|
||||||
|
name: "HelloWorld contract"
|
||||||
|
supportedstandards: []
|
||||||
|
events:
|
||||||
|
- name: Some simple notification
|
||||||
|
parameters:
|
||||||
|
- name: intP
|
||||||
|
type: Integer
|
||||||
|
- name: boolP
|
||||||
|
type: Boolean
|
||||||
|
- name: stringP
|
||||||
|
type: String
|
||||||
|
- name: Structure notification
|
||||||
|
parameters:
|
||||||
|
- name: structure parameter
|
||||||
|
type: Array
|
||||||
|
extendedtype:
|
||||||
|
base: Array
|
||||||
|
name: transferData
|
||||||
|
- name: Map of structures notification
|
||||||
|
parameters:
|
||||||
|
- name: map parameter
|
||||||
|
type: Map
|
||||||
|
extendedtype:
|
||||||
|
base: Map
|
||||||
|
key: Integer
|
||||||
|
value:
|
||||||
|
base: Array
|
||||||
|
name: transferData
|
||||||
|
- name: Iterator notification
|
||||||
|
parameters:
|
||||||
|
- name: data
|
||||||
|
type: InteropInterface
|
||||||
|
extendedtype:
|
||||||
|
base: InteropInterface
|
||||||
|
interface: iterator
|
||||||
|
namedtypes:
|
||||||
|
transferData:
|
||||||
|
base: Array
|
||||||
|
fields:
|
||||||
|
- field: IntField
|
||||||
|
base: Integer
|
||||||
|
- field: BoolField
|
||||||
|
base: Boolean
|
||||||
|
```
|
||||||
|
|
||||||
## Smart contract examples
|
## Smart contract examples
|
||||||
|
|
||||||
Some examples are provided in the [examples directory](../examples). For more
|
Some examples are provided in the [examples directory](../examples). For more
|
||||||
|
|
|
@ -76,6 +76,7 @@ func NewDeployTx(bc Ledger, name string, sender util.Uint160, r gio.Reader, conf
|
||||||
o.Name = conf.Name
|
o.Name = conf.Name
|
||||||
o.SourceURL = conf.SourceURL
|
o.SourceURL = conf.SourceURL
|
||||||
o.ContractEvents = conf.Events
|
o.ContractEvents = conf.Events
|
||||||
|
o.DeclaredNamedTypes = conf.NamedTypes
|
||||||
o.ContractSupportedStandards = conf.SupportedStandards
|
o.ContractSupportedStandards = conf.SupportedStandards
|
||||||
o.Permissions = make([]manifest.Permission, len(conf.Permissions))
|
o.Permissions = make([]manifest.Permission, len(conf.Permissions))
|
||||||
for i := range conf.Permissions {
|
for i := range conf.Permissions {
|
||||||
|
|
|
@ -52,14 +52,26 @@ type Options struct {
|
||||||
// This setting has effect only if manifest is emitted.
|
// This setting has effect only if manifest is emitted.
|
||||||
NoPermissionsCheck bool
|
NoPermissionsCheck bool
|
||||||
|
|
||||||
|
// GuessEventTypes specifies if types of runtime notifications need to be guessed
|
||||||
|
// from the usage context. These types are used for RPC binding generation only and
|
||||||
|
// can be defined for events with name known at the compilation time and without
|
||||||
|
// variadic args usages. If some type is specified via config file, then the config's
|
||||||
|
// one is preferable. Currently, event's parameter type is defined from the first
|
||||||
|
// occurrence of event call.
|
||||||
|
GuessEventTypes bool
|
||||||
|
|
||||||
// Name is a contract's name to be written to manifest.
|
// Name is a contract's name to be written to manifest.
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
// SourceURL is a contract's source URL to be written to manifest.
|
// SourceURL is a contract's source URL to be written to manifest.
|
||||||
SourceURL string
|
SourceURL string
|
||||||
|
|
||||||
// Runtime notifications.
|
// Runtime notifications declared in the contract configuration file.
|
||||||
ContractEvents []manifest.Event
|
ContractEvents []HybridEvent
|
||||||
|
|
||||||
|
// DeclaredNamedTypes is the set of named types that were declared in the
|
||||||
|
// contract configuration type and are the part of manifest events.
|
||||||
|
DeclaredNamedTypes map[string]binding.ExtendedType
|
||||||
|
|
||||||
// The list of standards supported by the contract.
|
// The list of standards supported by the contract.
|
||||||
ContractSupportedStandards []string
|
ContractSupportedStandards []string
|
||||||
|
@ -78,6 +90,23 @@ type Options struct {
|
||||||
BindingsFile string
|
BindingsFile string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HybridEvent represents the description of event emitted by the contract squashed
|
||||||
|
// with extended event's parameters description. We have it as a separate type for
|
||||||
|
// the user's convenience. It is applied for the smart contract configuration file
|
||||||
|
// only.
|
||||||
|
type HybridEvent struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Parameters []HybridParameter `json:"parameters"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// HybridParameter contains the manifest's event parameter description united with
|
||||||
|
// the extended type description for this parameter. It is applied for the smart
|
||||||
|
// contract configuration file only.
|
||||||
|
type HybridParameter struct {
|
||||||
|
manifest.Parameter `yaml:",inline"`
|
||||||
|
ExtendedType *binding.ExtendedType `yaml:"extendedtype,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type buildInfo struct {
|
type buildInfo struct {
|
||||||
config *packages.Config
|
config *packages.Config
|
||||||
program []*packages.Package
|
program []*packages.Package
|
||||||
|
@ -309,22 +338,46 @@ func CompileAndSave(src string, o *Options) ([]byte, error) {
|
||||||
if len(di.NamedTypes) > 0 {
|
if len(di.NamedTypes) > 0 {
|
||||||
cfg.NamedTypes = di.NamedTypes
|
cfg.NamedTypes = di.NamedTypes
|
||||||
}
|
}
|
||||||
|
for name, et := range o.DeclaredNamedTypes {
|
||||||
|
// TODO: handle name conflict
|
||||||
|
cfg.NamedTypes[name] = et
|
||||||
|
}
|
||||||
|
for _, e := range o.ContractEvents {
|
||||||
|
for _, p := range e.Parameters {
|
||||||
|
// TODO: proper imports handling during bindings generation (see utf8 example).
|
||||||
|
if p.ExtendedType != nil {
|
||||||
|
pName := e.Name + "." + p.Name
|
||||||
|
cfg.Types[pName] = *p.ExtendedType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if o.GuessEventTypes {
|
||||||
if len(di.EmittedEvents) > 0 {
|
if len(di.EmittedEvents) > 0 {
|
||||||
for eventName, eventUsages := range di.EmittedEvents {
|
for eventName, eventUsages := range di.EmittedEvents {
|
||||||
|
// Take into account the first usage only.
|
||||||
|
// TODO: extend it to the rest of invocations.
|
||||||
for typeName, extType := range eventUsages[0].ExtTypes {
|
for typeName, extType := range eventUsages[0].ExtTypes {
|
||||||
|
if _, ok := cfg.NamedTypes[typeName]; !ok {
|
||||||
cfg.NamedTypes[typeName] = extType
|
cfg.NamedTypes[typeName] = extType
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for _, p := range eventUsages[0].Params {
|
for _, p := range eventUsages[0].Params {
|
||||||
|
// TODO: prettify notification name in-place.
|
||||||
pname := eventName + "." + p.Name
|
pname := eventName + "." + p.Name
|
||||||
if p.RealType.TypeName != "" {
|
if p.RealType.TypeName != "" {
|
||||||
|
if _, ok := cfg.Overrides[pname]; !ok {
|
||||||
cfg.Overrides[pname] = p.RealType
|
cfg.Overrides[pname] = p.RealType
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if p.ExtendedType != nil {
|
if p.ExtendedType != nil {
|
||||||
|
if _, ok := cfg.Types[pname]; !ok {
|
||||||
cfg.Types[pname] = *p.ExtendedType
|
cfg.Types[pname] = *p.ExtendedType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
data, err := yaml.Marshal(&cfg)
|
data, err := yaml.Marshal(&cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't marshal bindings configuration: %w", err)
|
return nil, fmt.Errorf("can't marshal bindings configuration: %w", err)
|
||||||
|
|
|
@ -159,16 +159,16 @@ func TestEventWarnings(t *testing.T) {
|
||||||
})
|
})
|
||||||
t.Run("wrong parameter number", func(t *testing.T) {
|
t.Run("wrong parameter number", func(t *testing.T) {
|
||||||
_, err = compiler.CreateManifest(di, &compiler.Options{
|
_, err = compiler.CreateManifest(di, &compiler.Options{
|
||||||
ContractEvents: []manifest.Event{{Name: "Event"}},
|
ContractEvents: []compiler.HybridEvent{{Name: "Event"}},
|
||||||
Name: "payable",
|
Name: "payable",
|
||||||
})
|
})
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
})
|
})
|
||||||
t.Run("wrong parameter type", func(t *testing.T) {
|
t.Run("wrong parameter type", func(t *testing.T) {
|
||||||
_, err = compiler.CreateManifest(di, &compiler.Options{
|
_, err = compiler.CreateManifest(di, &compiler.Options{
|
||||||
ContractEvents: []manifest.Event{{
|
ContractEvents: []compiler.HybridEvent{{
|
||||||
Name: "Event",
|
Name: "Event",
|
||||||
Parameters: []manifest.Parameter{manifest.NewParameter("number", smartcontract.StringType)},
|
Parameters: []compiler.HybridParameter{{Parameter: manifest.NewParameter("number", smartcontract.StringType)}},
|
||||||
}},
|
}},
|
||||||
Name: "payable",
|
Name: "payable",
|
||||||
})
|
})
|
||||||
|
@ -176,9 +176,9 @@ func TestEventWarnings(t *testing.T) {
|
||||||
})
|
})
|
||||||
t.Run("any parameter type", func(t *testing.T) {
|
t.Run("any parameter type", func(t *testing.T) {
|
||||||
_, err = compiler.CreateManifest(di, &compiler.Options{
|
_, err = compiler.CreateManifest(di, &compiler.Options{
|
||||||
ContractEvents: []manifest.Event{{
|
ContractEvents: []compiler.HybridEvent{{
|
||||||
Name: "Event",
|
Name: "Event",
|
||||||
Parameters: []manifest.Parameter{manifest.NewParameter("number", smartcontract.AnyType)},
|
Parameters: []compiler.HybridParameter{{Parameter: manifest.NewParameter("number", smartcontract.AnyType)}},
|
||||||
}},
|
}},
|
||||||
Name: "payable",
|
Name: "payable",
|
||||||
})
|
})
|
||||||
|
@ -186,9 +186,9 @@ func TestEventWarnings(t *testing.T) {
|
||||||
})
|
})
|
||||||
t.Run("good", func(t *testing.T) {
|
t.Run("good", func(t *testing.T) {
|
||||||
_, err = compiler.CreateManifest(di, &compiler.Options{
|
_, err = compiler.CreateManifest(di, &compiler.Options{
|
||||||
ContractEvents: []manifest.Event{{
|
ContractEvents: []compiler.HybridEvent{{
|
||||||
Name: "Event",
|
Name: "Event",
|
||||||
Parameters: []manifest.Parameter{manifest.NewParameter("number", smartcontract.IntegerType)},
|
Parameters: []compiler.HybridParameter{{Parameter: manifest.NewParameter("number", smartcontract.IntegerType)}},
|
||||||
}},
|
}},
|
||||||
Name: "payable",
|
Name: "payable",
|
||||||
})
|
})
|
||||||
|
@ -224,7 +224,7 @@ func TestEventWarnings(t *testing.T) {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
_, err = compiler.CreateManifest(di, &compiler.Options{
|
_, err = compiler.CreateManifest(di, &compiler.Options{
|
||||||
ContractEvents: []manifest.Event{{Name: "Event"}},
|
ContractEvents: []compiler.HybridEvent{{Name: "Event"}},
|
||||||
Name: "eventTest",
|
Name: "eventTest",
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -242,9 +242,9 @@ func TestEventWarnings(t *testing.T) {
|
||||||
|
|
||||||
_, err = compiler.CreateManifest(di, &compiler.Options{
|
_, err = compiler.CreateManifest(di, &compiler.Options{
|
||||||
Name: "eventTest",
|
Name: "eventTest",
|
||||||
ContractEvents: []manifest.Event{{
|
ContractEvents: []compiler.HybridEvent{{
|
||||||
Name: "Event",
|
Name: "Event",
|
||||||
Parameters: []manifest.Parameter{manifest.NewParameter("number", smartcontract.IntegerType)},
|
Parameters: []compiler.HybridParameter{{Parameter: manifest.NewParameter("number", smartcontract.IntegerType)}},
|
||||||
}},
|
}},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -260,7 +260,7 @@ func TestNotifyInVerify(t *testing.T) {
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
src := fmt.Sprintf(srcTmpl, name)
|
src := fmt.Sprintf(srcTmpl, name)
|
||||||
_, _, err := compiler.CompileWithOptions("eventTest.go", strings.NewReader(src),
|
_, _, err := compiler.CompileWithOptions("eventTest.go", strings.NewReader(src),
|
||||||
&compiler.Options{ContractEvents: []manifest.Event{{Name: "Event"}}})
|
&compiler.Options{ContractEvents: []compiler.HybridEvent{{Name: "Event"}}})
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
t.Run("suppress", func(t *testing.T) {
|
t.Run("suppress", func(t *testing.T) {
|
||||||
|
|
|
@ -593,9 +593,20 @@ func (di *DebugInfo) ConvertToManifest(o *Options) (*manifest.Manifest, error) {
|
||||||
if o.ContractSupportedStandards != nil {
|
if o.ContractSupportedStandards != nil {
|
||||||
result.SupportedStandards = o.ContractSupportedStandards
|
result.SupportedStandards = o.ContractSupportedStandards
|
||||||
}
|
}
|
||||||
|
events := make([]manifest.Event, len(o.ContractEvents))
|
||||||
|
for i, e := range o.ContractEvents {
|
||||||
|
params := make([]manifest.Parameter, len(e.Parameters))
|
||||||
|
for j, p := range e.Parameters {
|
||||||
|
params[j] = p.Parameter
|
||||||
|
}
|
||||||
|
events[i] = manifest.Event{
|
||||||
|
Name: o.ContractEvents[i].Name,
|
||||||
|
Parameters: params,
|
||||||
|
}
|
||||||
|
}
|
||||||
result.ABI = manifest.ABI{
|
result.ABI = manifest.ABI{
|
||||||
Methods: methods,
|
Methods: methods,
|
||||||
Events: o.ContractEvents,
|
Events: events,
|
||||||
}
|
}
|
||||||
if result.ABI.Events == nil {
|
if result.ABI.Events == nil {
|
||||||
result.ABI.Events = make([]manifest.Event, 0)
|
result.ABI.Events = make([]manifest.Event, 0)
|
||||||
|
|
|
@ -542,13 +542,13 @@ func TestForcedNotifyArgumentsConversion(t *testing.T) {
|
||||||
if count != len(expectedVMParamTypes) {
|
if count != len(expectedVMParamTypes) {
|
||||||
t.Fatalf("parameters count mismatch: %d vs %d", count, len(expectedVMParamTypes))
|
t.Fatalf("parameters count mismatch: %d vs %d", count, len(expectedVMParamTypes))
|
||||||
}
|
}
|
||||||
scParams := make([]manifest.Parameter, len(targetSCParamTypes))
|
scParams := make([]compiler.HybridParameter, len(targetSCParamTypes))
|
||||||
vmParams := make([]stackitem.Item, len(expectedVMParamTypes))
|
vmParams := make([]stackitem.Item, len(expectedVMParamTypes))
|
||||||
for i := range scParams {
|
for i := range scParams {
|
||||||
scParams[i] = manifest.Parameter{
|
scParams[i] = compiler.HybridParameter{Parameter: manifest.Parameter{
|
||||||
Name: strconv.Itoa(i),
|
Name: strconv.Itoa(i),
|
||||||
Type: targetSCParamTypes[i],
|
Type: targetSCParamTypes[i],
|
||||||
}
|
}}
|
||||||
defaultValue := stackitem.NewBigInteger(big.NewInt(int64(i)))
|
defaultValue := stackitem.NewBigInteger(big.NewInt(int64(i)))
|
||||||
var (
|
var (
|
||||||
val stackitem.Item
|
val stackitem.Item
|
||||||
|
@ -564,7 +564,7 @@ func TestForcedNotifyArgumentsConversion(t *testing.T) {
|
||||||
}
|
}
|
||||||
ctr := neotest.CompileSource(t, e.CommitteeHash, strings.NewReader(src), &compiler.Options{
|
ctr := neotest.CompileSource(t, e.CommitteeHash, strings.NewReader(src), &compiler.Options{
|
||||||
Name: "Helper",
|
Name: "Helper",
|
||||||
ContractEvents: []manifest.Event{
|
ContractEvents: []compiler.HybridEvent{
|
||||||
{
|
{
|
||||||
Name: methodWithoutEllipsis,
|
Name: methodWithoutEllipsis,
|
||||||
Parameters: scParams,
|
Parameters: scParams,
|
||||||
|
|
|
@ -60,6 +60,7 @@ func CompileFile(t testing.TB, sender util.Uint160, srcPath string, configPath s
|
||||||
o := &compiler.Options{}
|
o := &compiler.Options{}
|
||||||
o.Name = conf.Name
|
o.Name = conf.Name
|
||||||
o.ContractEvents = conf.Events
|
o.ContractEvents = conf.Events
|
||||||
|
o.DeclaredNamedTypes = conf.NamedTypes
|
||||||
o.ContractSupportedStandards = conf.SupportedStandards
|
o.ContractSupportedStandards = conf.SupportedStandards
|
||||||
o.Permissions = make([]manifest.Permission, len(conf.Permissions))
|
o.Permissions = make([]manifest.Permission, len(conf.Permissions))
|
||||||
for i := range conf.Permissions {
|
for i := range conf.Permissions {
|
||||||
|
|
Loading…
Reference in a new issue