github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/execution/evm/abi/event_spec.go (about)

     1  package abi
     2  
     3  import (
     4  	"encoding/json"
     5  	"reflect"
     6  
     7  	"github.com/hyperledger/burrow/event/query"
     8  	"github.com/tmthrgd/go-hex"
     9  	"golang.org/x/crypto/sha3"
    10  )
    11  
    12  // Argument is a decoded function parameter, return or event field
    13  type Argument struct {
    14  	Name        string
    15  	EVM         EVMType
    16  	IsArray     bool
    17  	Indexed     bool
    18  	Hashed      bool
    19  	ArrayLength uint64
    20  }
    21  
    22  type argumentJSON struct {
    23  	Name       string
    24  	Type       string
    25  	Components []argumentJSON
    26  	Indexed    bool
    27  }
    28  
    29  // EventIDSize is the length of the event selector
    30  const EventIDSize = 32
    31  
    32  type EventSpec struct {
    33  	ID        EventID
    34  	Inputs    []Argument
    35  	Name      string
    36  	Anonymous bool
    37  }
    38  
    39  func (e *EventSpec) Get(key string) (interface{}, bool) {
    40  	return query.GetReflect(reflect.ValueOf(e), key)
    41  }
    42  
    43  func (e *EventSpec) UnmarshalJSON(data []byte) error {
    44  	s := new(specJSON)
    45  	err := json.Unmarshal(data, s)
    46  	if err != nil {
    47  		return err
    48  	}
    49  	return e.unmarshalSpec(s)
    50  }
    51  
    52  func (e *EventSpec) unmarshalSpec(s *specJSON) error {
    53  	inputs, err := readArgSpec(s.Inputs)
    54  	if err != nil {
    55  		return err
    56  	}
    57  	// Get signature before we deal with hashed types
    58  	sig := Signature(s.Name, inputs)
    59  	for i := range inputs {
    60  		if inputs[i].Indexed && inputs[i].EVM.Dynamic() {
    61  			// For Dynamic types, the hash is stored in stead
    62  			inputs[i].EVM = EVMBytes{M: 32}
    63  			inputs[i].Hashed = true
    64  		}
    65  	}
    66  	e.Name = s.Name
    67  	e.ID = GetEventID(sig)
    68  	e.Inputs = inputs
    69  	e.Anonymous = s.Anonymous
    70  	return nil
    71  }
    72  
    73  type EventID [EventIDSize]byte
    74  
    75  func GetEventID(signature string) (id EventID) {
    76  	hash := sha3.NewLegacyKeccak256()
    77  	hash.Write([]byte(signature))
    78  	copy(id[:], hash.Sum(nil))
    79  	return
    80  }
    81  
    82  func (e *EventSpec) String() string {
    83  	str := e.Name + argsToSignature(e.Inputs, true)
    84  	if e.Anonymous {
    85  		str += " anonymous"
    86  	}
    87  
    88  	return str
    89  }
    90  
    91  func (id EventID) String() string {
    92  	return hex.EncodeUpperToString(id[:])
    93  }
    94  
    95  func (id EventID) Bytes() []byte {
    96  	return id[:]
    97  }