@@ -32,7 +32,8 @@ type ContractEvent interface {
3232 ContractEventName () string
3333}
3434
35- // FilterEvents returns an EventIterator instance for filtering historical events based on the event id and a block range.
35+ // FilterEvents filters a historical block range for instances of emission of a
36+ // specific event type from a specified contract. It returns an error if... (TODO: enumerate error scenarios)
3637func FilterEvents [Ev ContractEvent ](c * BoundContract , opts * FilterOpts , unpack func (* types.Log ) (* Ev , error ), topics ... []any ) (* EventIterator [Ev ], error ) {
3738 var e Ev
3839 logs , sub , err := c .FilterLogs (opts , e .ContractEventName (), topics ... )
@@ -42,10 +43,11 @@ func FilterEvents[Ev ContractEvent](c *BoundContract, opts *FilterOpts, unpack f
4243 return & EventIterator [Ev ]{unpack : unpack , logs : logs , sub : sub }, nil
4344}
4445
45- // WatchEvents causes logs emitted with a given event id from a specified
46- // contract to be intercepted, unpacked, and forwarded to sink. If
47- // unpack returns an error, the returned subscription is closed with the
48- // error.
46+ // WatchEvents creates an event subscription to notify when logs of the specified event type are emitted from the given contract.
47+ // Received logs are unpacked and forwarded to sink. If topics are specified, only events are forwarded which match the
48+ // topics.
49+ //
50+ // WatchEvents returns a subscription or an error if ... (TODO: enumerate error scenarios)
4951func WatchEvents [Ev ContractEvent ](c * BoundContract , opts * WatchOpts , unpack func (* types.Log ) (* Ev , error ), sink chan <- * Ev , topics ... []any ) (event.Subscription , error ) {
5052 var e Ev
5153 logs , sub , err := c .WatchLogs (opts , e .ContractEventName (), topics ... )
@@ -79,86 +81,81 @@ func WatchEvents[Ev ContractEvent](c *BoundContract, opts *WatchOpts, unpack fun
7981 }), nil
8082}
8183
82- // EventIterator is returned from FilterLogs and is used to iterate over the raw
83- // logs and unpacked data for events.
84+ // EventIterator is an object for iterating over the results of a event log filter call.
8485type EventIterator [T any ] struct {
85- event * T // event containing the contract specifics and raw log
86-
87- unpack func (* types.Log ) (* T , error ) // Unpack function for the event
88-
89- logs <- chan types.Log // Log channel receiving the found contract events
90- sub ethereum.Subscription // Subscription for solc_errors, completion and termination
91- done bool // Whether the subscription completed delivering logs
92- fail error // Occurred error to stop iteration
86+ current * T
87+ unpack func (* types.Log ) (* T , error )
88+ logs <- chan types.Log
89+ sub ethereum.Subscription
90+ fail error // error to hold reason for iteration failure
91+ closed bool // true if Close has been called
9392}
9493
9594// Value returns the current value of the iterator, or nil if there isn't one.
9695func (it * EventIterator [T ]) Value () * T {
97- return it .event
96+ return it .current
9897}
9998
100- // Next advances the iterator to the subsequent event, returning whether there
101- // are any more events found. In case of a retrieval or parsing error, false is
102- // returned and Error() can be queried for the exact failure.
103- func (it * EventIterator [T ]) Next () bool {
104- // If the iterator failed, stop iterating
105- if it .fail != nil {
106- return false
99+ // Next advances the iterator to the subsequent event (if there is one),
100+ // returning true if the iterator advanced.
101+ //
102+ // If the attempt to convert the raw log object to an instance of T using the
103+ // unpack function provided via FilterEvents returns an error: that error is returned and subsequent calls to Next will
104+ // not advance the iterator.
105+ func (it * EventIterator [T ]) Next () (advanced bool , err error ) {
106+ // If the iterator failed with an error, don't proceed
107+ if it .fail != nil || it .closed {
108+ return false , it .fail
107109 }
108- // If the iterator completed, deliver directly whatever's available
109- if it .done {
110+ // if the iterator is still active, block until a log is received or the
111+ // underlying subscription terminates.
112+ select {
113+ case log := <- it .logs :
114+ res , err := it .unpack (& log )
115+ if err != nil {
116+ it .fail = err
117+ return false , it .fail
118+ }
119+ it .current = res
120+ return true , it .fail
121+ case <- it .sub .Err ():
122+ // regardless of how the subscription ends, still be able to iterate
123+ // over any unread logs.
110124 select {
111125 case log := <- it .logs :
112126 res , err := it .unpack (& log )
113127 if err != nil {
114128 it .fail = err
115- return false
129+ return false , it . fail
116130 }
117- it .event = res
118- return true
119-
131+ it .current = res
132+ return true , it .fail
120133 default :
121- return false
134+ return false , it . fail
122135 }
123136 }
124- // Iterator still in progress, wait for either a data or an error event
125- select {
126- case log := <- it .logs :
127- res , err := it .unpack (& log )
128- if err != nil {
129- it .fail = err
130- return false
131- }
132- it .event = res
133- return true
134-
135- case err := <- it .sub .Err ():
136- it .done = true
137- it .fail = err
138- return it .Next ()
139- }
140137}
141138
142- // Error returns any retrieval or parsing error occurred during filtering .
139+ // Error returns an error if iteration has failed .
143140func (it * EventIterator [T ]) Error () error {
144141 return it .fail
145142}
146143
147- // Close terminates the iteration process, releasing any pending underlying
148- // resources .
144+ // Close releases any pending underlying resources. Any subsequent calls to
145+ // Next will not advance the iterator, but the current value remains accessible .
149146func (it * EventIterator [T ]) Close () error {
147+ it .closed = true
150148 it .sub .Unsubscribe ()
151149 return nil
152150}
153151
154- // Call performs an eth_call on the given bound contract instance, using the provided
155- // ABI-encoded input.
152+ // Call performs an eth_call to a contract with optional call data.
156153//
157154// To call a function that doesn't return any output, pass nil as the unpack function.
158155// This can be useful if you just want to check that the function doesn't revert.
159- func Call [T any ](c * BoundContract , opts * CallOpts , packedInput []byte , unpack func ([]byte ) (T , error )) (T , error ) {
156+ func Call [T any ](c * BoundContract , opts * CallOpts , calldata []byte , unpack func ([]byte ) (T , error )) (T , error ) {
160157 var defaultResult T
161- packedOutput , err := c .CallRaw (opts , packedInput )
158+ packedOutput , err := c .CallRaw (opts , calldata )
162159 if err != nil {
163160 return defaultResult , err
164161 }
@@ -175,19 +172,19 @@ func Call[T any](c *BoundContract, opts *CallOpts, packedInput []byte, unpack fu
175172 return res , err
176173}
177174
178- // Transact initiates a transaction with the given raw calldata as the input.
179- func Transact (c * BoundContract , opt * TransactOpts , packedInput []byte ) (* types.Transaction , error ) {
175+ // Transact creates and submits a transaction to a contract with optional input data .
176+ func Transact (c * BoundContract , opt * TransactOpts , data []byte ) (* types.Transaction , error ) {
180177 addr := c .address
181- return c .transact (opt , & addr , packedInput )
178+ return c .transact (opt , & addr , data )
182179}
183180
184- // DeployContract deploys a contract onto the Ethereum blockchain and binds the
185- // deployment address with a Go wrapper . It expects its parameters to be abi-encoded
186- // bytes .
187- func DeployContract (opts * TransactOpts , bytecode []byte , backend ContractBackend , packedParams []byte ) (common.Address , * types.Transaction , error ) {
181+ // DeployContract creates and submits a deployment transaction based on the deployer bytecode and
182+ // optional ABI-encoded constructor input . It returns the address and creation transaction of the
183+ // pending contract, or an error if the creation failed .
184+ func DeployContract (opts * TransactOpts , bytecode []byte , backend ContractBackend , constructorInput []byte ) (common.Address , * types.Transaction , error ) {
188185 c := NewBoundContract (common.Address {}, abi.ABI {}, backend , backend , backend )
189186
190- tx , err := c .RawCreationTransact (opts , append (bytecode , packedParams ... ))
187+ tx , err := c .RawCreationTransact (opts , append (bytecode , constructorInput ... ))
191188 if err != nil {
192189 return common.Address {}, nil , err
193190 }
0 commit comments