smartcontract: drop standard events before RPC binging generation

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
This commit is contained in:
Anna Shaleva 2023-05-21 15:08:29 +03:00
parent 2c36802e23
commit 41938ffa78
6 changed files with 157 additions and 285 deletions

View file

@ -2,25 +2,13 @@
package gastoken
import (
"errors"
"fmt"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep17"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"math/big"
)
// Hash contains contract hash.
var Hash = util.Uint160{0xcf, 0x76, 0xe2, 0x8b, 0xd0, 0x6, 0x2c, 0x4a, 0x47, 0x8e, 0xe3, 0x55, 0x61, 0x1, 0x13, 0x19, 0xf3, 0xcf, 0xa4, 0xd2}
// TransferEvent represents "Transfer" event emitted by the contract.
type TransferEvent struct {
From util.Uint160
To util.Uint160
Amount *big.Int
}
// Invoker is used by ContractReader to call various safe methods.
type Invoker interface {
nep17.Invoker
@ -56,87 +44,3 @@ func New(actor Actor) *Contract {
var nep17t = nep17.New(actor, Hash)
return &Contract{ContractReader{nep17t.TokenReader, actor}, nep17t.TokenWriter, actor}
}
// TransferEventsFromApplicationLog retrieves a set of all emitted events
// with "Transfer" name from the provided ApplicationLog.
func TransferEventsFromApplicationLog(log *result.ApplicationLog) ([]*TransferEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*TransferEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "Transfer" {
continue
}
event := new(TransferEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize TransferEvent from stackitem (execution %d, event %d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided stackitem.Array to TransferEvent and
// returns an error if so.
func (e *TransferEvent) 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) != 3 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.From, 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 From: %w", err)
}
index++
e.To, 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 To: %w", err)
}
index++
e.Amount, err = arr[index].TryInteger()
if err != nil {
return fmt.Errorf("field Amount: %w", err)
}
return nil
}

View file

@ -18,14 +18,6 @@ import (
// Hash contains contract hash.
var Hash = util.Uint160{0xde, 0x46, 0x5f, 0x5d, 0x50, 0x57, 0xcf, 0x33, 0x28, 0x47, 0x94, 0xc5, 0xcf, 0xc2, 0xc, 0x69, 0x37, 0x1c, 0xac, 0x50}
// TransferEvent represents "Transfer" event emitted by the contract.
type TransferEvent struct {
From util.Uint160
To util.Uint160
Amount *big.Int
TokenId []byte
}
// SetAdminEvent represents "SetAdmin" event emitted by the contract.
type SetAdminEvent struct {
Name string
@ -345,96 +337,6 @@ func (c *Contract) DeleteRecordUnsigned(name string, typev *big.Int) (*transacti
return c.actor.MakeUnsignedCall(Hash, "deleteRecord", nil, name, typev)
}
// TransferEventsFromApplicationLog retrieves a set of all emitted events
// with "Transfer" name from the provided ApplicationLog.
func TransferEventsFromApplicationLog(log *result.ApplicationLog) ([]*TransferEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*TransferEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "Transfer" {
continue
}
event := new(TransferEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize TransferEvent from stackitem (execution %d, event %d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided stackitem.Array to TransferEvent and
// returns an error if so.
func (e *TransferEvent) 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) != 4 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.From, 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 From: %w", err)
}
index++
e.To, 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 To: %w", err)
}
index++
e.Amount, err = arr[index].TryInteger()
if err != nil {
return fmt.Errorf("field Amount: %w", err)
}
index++
e.TokenId, err = arr[index].TryBytes()
if err != nil {
return fmt.Errorf("field TokenId: %w", err)
}
return nil
}
// SetAdminEventsFromApplicationLog retrieves a set of all emitted events
// with "SetAdmin" name from the provided ApplicationLog.
func SetAdminEventsFromApplicationLog(log *result.ApplicationLog) ([]*SetAdminEvent, error) {

View file

@ -17,13 +17,6 @@ import (
// Hash contains contract hash.
var Hash = util.Uint160{0xa8, 0x1a, 0xa1, 0xf0, 0x4b, 0xf, 0xdc, 0x4a, 0xa2, 0xce, 0xd5, 0xbf, 0xc6, 0x22, 0xcf, 0xe8, 0x9, 0x7f, 0xa6, 0xa2}
// TransferEvent represents "Transfer" event emitted by the contract.
type TransferEvent struct {
From util.Uint160
To util.Uint160
Amount *big.Int
}
// OnMintEvent represents "OnMint" event emitted by the contract.
type OnMintEvent struct {
From util.Uint160
@ -249,90 +242,6 @@ func (c *Contract) UpdateCapUnsigned(newCap *big.Int) (*transaction.Transaction,
return c.actor.MakeUnsignedCall(Hash, "updateCap", nil, newCap)
}
// TransferEventsFromApplicationLog retrieves a set of all emitted events
// with "Transfer" name from the provided ApplicationLog.
func TransferEventsFromApplicationLog(log *result.ApplicationLog) ([]*TransferEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*TransferEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "Transfer" {
continue
}
event := new(TransferEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize TransferEvent from stackitem (execution %d, event %d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided stackitem.Array to TransferEvent and
// returns an error if so.
func (e *TransferEvent) 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) != 3 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.From, 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 From: %w", err)
}
index++
e.To, 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 To: %w", err)
}
index++
e.Amount, err = arr[index].TryInteger()
if err != nil {
return fmt.Errorf("field Amount: %w", err)
}
return nil
}
// OnMintEventsFromApplicationLog retrieves a set of all emitted events
// with "OnMint" name from the provided ApplicationLog.
func OnMintEventsFromApplicationLog(log *result.ApplicationLog) ([]*OnMintEvent, error) {

View file

@ -10,6 +10,7 @@ purposes, otherwise more specific types are recommended.
package nep11
import (
"errors"
"fmt"
"math/big"
"unicode/utf8"
@ -246,3 +247,71 @@ func UnwrapKnownProperties(m *stackitem.Map, err error) (map[string]string, erro
}
return res, nil
}
// TransferEventsFromApplicationLog retrieves all emitted TransferEvents from the
// provided [result.ApplicationLog].
func TransferEventsFromApplicationLog(log *result.ApplicationLog) ([]*TransferEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*TransferEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "Transfer" {
continue
}
event := new(TransferEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to decode event from stackitem (event #%d, execution #%d): %w", j, i, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to TransferEvent or returns an
// error if it's not possible to do to so.
func (e *TransferEvent) 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) != 4 {
return errors.New("wrong number of event parameters")
}
b, err := arr[0].TryBytes()
if err != nil {
return fmt.Errorf("invalid From: %w", err)
}
e.From, err = util.Uint160DecodeBytesBE(b)
if err != nil {
return fmt.Errorf("failed to decode From: %w", err)
}
b, err = arr[1].TryBytes()
if err != nil {
return fmt.Errorf("invalid To: %w", err)
}
e.To, err = util.Uint160DecodeBytesBE(b)
if err != nil {
return fmt.Errorf("failed to decode To: %w", err)
}
e.Amount, err = arr[2].TryInteger()
if err != nil {
return fmt.Errorf("field to decode Avount: %w", err)
}
e.ID, err = arr[3].TryBytes()
if err != nil {
return fmt.Errorf("failed to decode ID: %w", err)
}
return nil
}

View file

@ -8,12 +8,15 @@ package nep17
import (
"errors"
"fmt"
"math/big"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/neptoken"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)
// Invoker is used by TokenReader to call various safe methods.
@ -147,3 +150,66 @@ func (t *TokenWriter) MultiTransferUnsigned(params []TransferParameters) (*trans
}
return t.actor.MakeUnsignedRun(script, nil)
}
// TransferEventsFromApplicationLog retrieves all emitted TransferEvents from the
// provided [result.ApplicationLog].
func TransferEventsFromApplicationLog(log *result.ApplicationLog) ([]*TransferEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*TransferEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "Transfer" {
continue
}
event := new(TransferEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to decode event from stackitem (event #%d, execution #%d): %w", j, i, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to TransferEvent or returns an
// error if it's not possible to do to so.
func (e *TransferEvent) 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) != 3 {
return errors.New("wrong number of event parameters")
}
b, err := arr[0].TryBytes()
if err != nil {
return fmt.Errorf("invalid From: %w", err)
}
e.From, err = util.Uint160DecodeBytesBE(b)
if err != nil {
return fmt.Errorf("failed to decode From: %w", err)
}
b, err = arr[1].TryBytes()
if err != nil {
return fmt.Errorf("invalid To: %w", err)
}
e.To, err = util.Uint160DecodeBytesBE(b)
if err != nil {
return fmt.Errorf("failed to decode To: %w", err)
}
e.Amount, err = arr[2].TryInteger()
if err != nil {
return fmt.Errorf("field to decode Avount: %w", err)
}
return nil
}

View file

@ -396,12 +396,14 @@ func Generate(cfg binding.Config) error {
mfst.ABI.Methods = dropStdMethods(mfst.ABI.Methods, standard.Nep11NonDivisible)
ctr.IsNep11ND = true
}
mfst.ABI.Events = dropStdEvents(mfst.ABI.Events, standard.Nep11Base)
break // Can't be NEP-17 at the same time.
}
if std == manifest.NEP17StandardName && standard.ComplyABI(cfg.Manifest, standard.Nep17) == nil {
mfst.ABI.Methods = dropStdMethods(mfst.ABI.Methods, standard.Nep17)
imports["github.com/nspcc-dev/neo-go/pkg/rpcclient/nep17"] = struct{}{}
ctr.IsNep17 = true
mfst.ABI.Events = dropStdEvents(mfst.ABI.Events, standard.Nep17)
break // Can't be NEP-11 at the same time.
}
}
@ -445,6 +447,18 @@ func dropManifestMethods(meths []manifest.Method, manifested []manifest.Method)
return meths
}
func dropManifestEvents(events []manifest.Event, manifested []manifest.Event) []manifest.Event {
for _, e := range manifested {
for i := 0; i < len(events); i++ {
if events[i].Name == e.Name && len(events[i].Parameters) == len(e.Parameters) {
events = append(events[:i], events[i+1:]...)
i--
}
}
}
return events
}
func dropStdMethods(meths []manifest.Method, std *standard.Standard) []manifest.Method {
meths = dropManifestMethods(meths, std.Manifest.ABI.Methods)
if std.Optional != nil {
@ -456,6 +470,14 @@ func dropStdMethods(meths []manifest.Method, std *standard.Standard) []manifest.
return meths
}
func dropStdEvents(events []manifest.Event, std *standard.Standard) []manifest.Event {
events = dropManifestEvents(events, std.Manifest.ABI.Events)
if std.Base != nil {
return dropStdEvents(events, std.Base)
}
return events
}
func extendedTypeToGo(et binding.ExtendedType, named map[string]binding.ExtendedType) (string, string) {
switch et.Base {
case smartcontract.AnyType: