@@ -80,36 +80,56 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) {
8080 return append (method .ID , arguments ... ), nil
8181}
8282
83- // Unpack output in v according to the abi specification.
84- func (abi ABI ) Unpack (v interface {}, name string , data []byte ) (err error ) {
83+ func (abi ABI ) getArguments (name string , data []byte ) (Arguments , error ) {
8584 // since there can't be naming collisions with contracts and events,
8685 // we need to decide whether we're calling a method or an event
86+ var args Arguments
8787 if method , ok := abi .Methods [name ]; ok {
8888 if len (data )% 32 != 0 {
89- return fmt .Errorf ("abi: improperly formatted output: %s - Bytes: [%+v]" , string (data ), data )
89+ return nil , fmt .Errorf ("abi: improperly formatted output: %s - Bytes: [%+v]" , string (data ), data )
9090 }
91- return method .Outputs . Unpack ( v , data )
91+ args = method .Outputs
9292 }
9393 if event , ok := abi .Events [name ]; ok {
94- return event .Inputs . Unpack ( v , data )
94+ args = event .Inputs
9595 }
96- return fmt .Errorf ("abi: could not locate named method or event" )
96+ if args == nil {
97+ return nil , errors .New ("abi: could not locate named method or event" )
98+ }
99+ return args , nil
100+ }
101+
102+ // Unpack unpacks the output according to the abi specification.
103+ func (abi ABI ) Unpack (name string , data []byte ) ([]interface {}, error ) {
104+ args , err := abi .getArguments (name , data )
105+ if err != nil {
106+ return nil , err
107+ }
108+ return args .Unpack (data )
109+ }
110+
111+ // UnpackIntoInterface unpacks the output in v according to the abi specification.
112+ // It performs an additional copy. Please only use, if you want to unpack into a
113+ // structure that does not strictly conform to the abi structure (e.g. has additional arguments)
114+ func (abi ABI ) UnpackIntoInterface (v interface {}, name string , data []byte ) error {
115+ args , err := abi .getArguments (name , data )
116+ if err != nil {
117+ return err
118+ }
119+ unpacked , err := args .Unpack (data )
120+ if err != nil {
121+ return err
122+ }
123+ return args .Copy (v , unpacked )
97124}
98125
99126// UnpackIntoMap unpacks a log into the provided map[string]interface{}.
100127func (abi ABI ) UnpackIntoMap (v map [string ]interface {}, name string , data []byte ) (err error ) {
101- // since there can't be naming collisions with contracts and events,
102- // we need to decide whether we're calling a method or an event
103- if method , ok := abi .Methods [name ]; ok {
104- if len (data )% 32 != 0 {
105- return fmt .Errorf ("abi: improperly formatted output" )
106- }
107- return method .Outputs .UnpackIntoMap (v , data )
108- }
109- if event , ok := abi .Events [name ]; ok {
110- return event .Inputs .UnpackIntoMap (v , data )
128+ args , err := abi .getArguments (name , data )
129+ if err != nil {
130+ return err
111131 }
112- return fmt . Errorf ( "abi: could not locate named method or event" )
132+ return args . UnpackIntoMap ( v , data )
113133}
114134
115135// UnmarshalJSON implements json.Unmarshaler interface.
@@ -250,10 +270,10 @@ func UnpackRevert(data []byte) (string, error) {
250270 if ! bytes .Equal (data [:4 ], revertSelector ) {
251271 return "" , errors .New ("invalid data for unpacking" )
252272 }
253- var reason string
254273 typ , _ := NewType ("string" , "" , nil )
255- if err := (Arguments {{Type : typ }}).Unpack (& reason , data [4 :]); err != nil {
274+ unpacked , err := (Arguments {{Type : typ }}).Unpack (data [4 :])
275+ if err != nil {
256276 return "" , err
257277 }
258- return reason , nil
278+ return unpacked [ 0 ].( string ) , nil
259279}
0 commit comments