github.com/digdeepmining/go-atheios@v1.5.13-0.20180902133602-d5687a2e6f43/accounts/abi/abi.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package abi 18 19 import ( 20 "encoding/json" 21 "fmt" 22 "io" 23 "math/big" 24 "reflect" 25 "strings" 26 27 "github.com/atheioschain/go-atheios/common" 28 ) 29 30 // The ABI holds information about a contract's context and available 31 // invokable methods. It will allow you to type check function calls and 32 // packs data accordingly. 33 type ABI struct { 34 Constructor Method 35 Methods map[string]Method 36 Events map[string]Event 37 } 38 39 // JSON returns a parsed ABI interface and error if it failed. 40 func JSON(reader io.Reader) (ABI, error) { 41 dec := json.NewDecoder(reader) 42 43 var abi ABI 44 if err := dec.Decode(&abi); err != nil { 45 return ABI{}, err 46 } 47 48 return abi, nil 49 } 50 51 // Pack the given method name to conform the ABI. Method call's data 52 // will consist of method_id, args0, arg1, ... argN. Method id consists 53 // of 4 bytes and arguments are all 32 bytes. 54 // Method ids are created from the first 4 bytes of the hash of the 55 // methods string signature. (signature = baz(uint32,string32)) 56 func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) { 57 // Fetch the ABI of the requested method 58 var method Method 59 60 if name == "" { 61 method = abi.Constructor 62 } else { 63 m, exist := abi.Methods[name] 64 if !exist { 65 return nil, fmt.Errorf("method '%s' not found", name) 66 } 67 method = m 68 } 69 arguments, err := method.pack(method, args...) 70 if err != nil { 71 return nil, err 72 } 73 // Pack up the method ID too if not a constructor and return 74 if name == "" { 75 return arguments, nil 76 } 77 return append(method.Id(), arguments...), nil 78 } 79 80 // toGoSliceType parses the input and casts it to the proper slice defined by the ABI 81 // argument in T. 82 func toGoSlice(i int, t Argument, output []byte) (interface{}, error) { 83 index := i * 32 84 // The slice must, at very least be large enough for the index+32 which is exactly the size required 85 // for the [offset in output, size of offset]. 86 if index+32 > len(output) { 87 return nil, fmt.Errorf("abi: cannot marshal in to go slice: insufficient size output %d require %d", len(output), index+32) 88 } 89 elem := t.Type.Elem 90 91 // first we need to create a slice of the type 92 var refSlice reflect.Value 93 switch elem.T { 94 case IntTy, UintTy, BoolTy: 95 // create a new reference slice matching the element type 96 switch t.Type.Kind { 97 case reflect.Bool: 98 refSlice = reflect.ValueOf([]bool(nil)) 99 case reflect.Uint8: 100 refSlice = reflect.ValueOf([]uint8(nil)) 101 case reflect.Uint16: 102 refSlice = reflect.ValueOf([]uint16(nil)) 103 case reflect.Uint32: 104 refSlice = reflect.ValueOf([]uint32(nil)) 105 case reflect.Uint64: 106 refSlice = reflect.ValueOf([]uint64(nil)) 107 case reflect.Int8: 108 refSlice = reflect.ValueOf([]int8(nil)) 109 case reflect.Int16: 110 refSlice = reflect.ValueOf([]int16(nil)) 111 case reflect.Int32: 112 refSlice = reflect.ValueOf([]int32(nil)) 113 case reflect.Int64: 114 refSlice = reflect.ValueOf([]int64(nil)) 115 default: 116 refSlice = reflect.ValueOf([]*big.Int(nil)) 117 } 118 case AddressTy: // address must be of slice Address 119 refSlice = reflect.ValueOf([]common.Address(nil)) 120 case HashTy: // hash must be of slice hash 121 refSlice = reflect.ValueOf([]common.Hash(nil)) 122 case FixedBytesTy: 123 refSlice = reflect.ValueOf([][]byte(nil)) 124 default: // no other types are supported 125 return nil, fmt.Errorf("abi: unsupported slice type %v", elem.T) 126 } 127 128 var slice []byte 129 var size int 130 var offset int 131 if t.Type.IsSlice { 132 133 // get the offset which determines the start of this array ... 134 offset = int(common.BytesToBig(output[index : index+32]).Uint64()) 135 if offset+32 > len(output) { 136 return nil, fmt.Errorf("abi: cannot marshal in to go slice: offset %d would go over slice boundary (len=%d)", len(output), offset+32) 137 } 138 139 slice = output[offset:] 140 // ... starting with the size of the array in elements ... 141 size = int(common.BytesToBig(slice[:32]).Uint64()) 142 slice = slice[32:] 143 // ... and make sure that we've at the very least the amount of bytes 144 // available in the buffer. 145 if size*32 > len(slice) { 146 return nil, fmt.Errorf("abi: cannot marshal in to go slice: insufficient size output %d require %d", len(output), offset+32+size*32) 147 } 148 149 // reslice to match the required size 150 slice = slice[:(size * 32)] 151 } else if t.Type.IsArray { 152 //get the number of elements in the array 153 size = t.Type.SliceSize 154 155 //check to make sure array size matches up 156 if index+32*size > len(output) { 157 return nil, fmt.Errorf("abi: cannot marshal in to go array: offset %d would go over slice boundary (len=%d)", len(output), index+32*size) 158 } 159 //slice is there for a fixed amount of times 160 slice = output[index : index+size*32] 161 } 162 163 for i := 0; i < size; i++ { 164 var ( 165 inter interface{} // interface type 166 returnOutput = slice[i*32 : i*32+32] // the return output 167 ) 168 169 // set inter to the correct type (cast) 170 switch elem.T { 171 case IntTy, UintTy: 172 bigNum := common.BytesToBig(returnOutput) 173 switch t.Type.Kind { 174 case reflect.Uint8: 175 inter = uint8(bigNum.Uint64()) 176 case reflect.Uint16: 177 inter = uint16(bigNum.Uint64()) 178 case reflect.Uint32: 179 inter = uint32(bigNum.Uint64()) 180 case reflect.Uint64: 181 inter = bigNum.Uint64() 182 case reflect.Int8: 183 inter = int8(bigNum.Int64()) 184 case reflect.Int16: 185 inter = int16(bigNum.Int64()) 186 case reflect.Int32: 187 inter = int32(bigNum.Int64()) 188 case reflect.Int64: 189 inter = bigNum.Int64() 190 default: 191 inter = common.BytesToBig(returnOutput) 192 } 193 case BoolTy: 194 inter = common.BytesToBig(returnOutput).Uint64() > 0 195 case AddressTy: 196 inter = common.BytesToAddress(returnOutput) 197 case HashTy: 198 inter = common.BytesToHash(returnOutput) 199 case FixedBytesTy: 200 inter = returnOutput 201 } 202 // append the item to our reflect slice 203 refSlice = reflect.Append(refSlice, reflect.ValueOf(inter)) 204 } 205 206 // return the interface 207 return refSlice.Interface(), nil 208 } 209 210 // toGoType parses the input and casts it to the proper type defined by the ABI 211 // argument in T. 212 func toGoType(i int, t Argument, output []byte) (interface{}, error) { 213 // we need to treat slices differently 214 if (t.Type.IsSlice || t.Type.IsArray) && t.Type.T != BytesTy && t.Type.T != StringTy && t.Type.T != FixedBytesTy && t.Type.T != FunctionTy { 215 return toGoSlice(i, t, output) 216 } 217 218 index := i * 32 219 if index+32 > len(output) { 220 return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), index+32) 221 } 222 223 // Parse the given index output and check whether we need to read 224 // a different offset and length based on the type (i.e. string, bytes) 225 var returnOutput []byte 226 switch t.Type.T { 227 case StringTy, BytesTy: // variable arrays are written at the end of the return bytes 228 // parse offset from which we should start reading 229 offset := int(common.BytesToBig(output[index : index+32]).Uint64()) 230 if offset+32 > len(output) { 231 return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), offset+32) 232 } 233 // parse the size up until we should be reading 234 size := int(common.BytesToBig(output[offset : offset+32]).Uint64()) 235 if offset+32+size > len(output) { 236 return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), offset+32+size) 237 } 238 239 // get the bytes for this return value 240 returnOutput = output[offset+32 : offset+32+size] 241 default: 242 returnOutput = output[index : index+32] 243 } 244 245 // convert the bytes to whatever is specified by the ABI. 246 switch t.Type.T { 247 case IntTy, UintTy: 248 bigNum := common.BytesToBig(returnOutput) 249 250 // If the type is a integer convert to the integer type 251 // specified by the ABI. 252 switch t.Type.Kind { 253 case reflect.Uint8: 254 return uint8(bigNum.Uint64()), nil 255 case reflect.Uint16: 256 return uint16(bigNum.Uint64()), nil 257 case reflect.Uint32: 258 return uint32(bigNum.Uint64()), nil 259 case reflect.Uint64: 260 return uint64(bigNum.Uint64()), nil 261 case reflect.Int8: 262 return int8(bigNum.Int64()), nil 263 case reflect.Int16: 264 return int16(bigNum.Int64()), nil 265 case reflect.Int32: 266 return int32(bigNum.Int64()), nil 267 case reflect.Int64: 268 return int64(bigNum.Int64()), nil 269 case reflect.Ptr: 270 return bigNum, nil 271 } 272 case BoolTy: 273 return common.BytesToBig(returnOutput).Uint64() > 0, nil 274 case AddressTy: 275 return common.BytesToAddress(returnOutput), nil 276 case HashTy: 277 return common.BytesToHash(returnOutput), nil 278 case BytesTy, FixedBytesTy, FunctionTy: 279 return returnOutput, nil 280 case StringTy: 281 return string(returnOutput), nil 282 } 283 return nil, fmt.Errorf("abi: unknown type %v", t.Type.T) 284 } 285 286 // these variable are used to determine certain types during type assertion for 287 // assignment. 288 var ( 289 r_interSlice = reflect.TypeOf([]interface{}{}) 290 r_hash = reflect.TypeOf(common.Hash{}) 291 r_bytes = reflect.TypeOf([]byte{}) 292 r_byte = reflect.TypeOf(byte(0)) 293 ) 294 295 // Unpack output in v according to the abi specification 296 func (abi ABI) Unpack(v interface{}, name string, output []byte) error { 297 var method = abi.Methods[name] 298 299 if len(output) == 0 { 300 return fmt.Errorf("abi: unmarshalling empty output") 301 } 302 303 // make sure the passed value is a pointer 304 valueOf := reflect.ValueOf(v) 305 if reflect.Ptr != valueOf.Kind() { 306 return fmt.Errorf("abi: Unpack(non-pointer %T)", v) 307 } 308 309 var ( 310 value = valueOf.Elem() 311 typ = value.Type() 312 ) 313 314 if len(method.Outputs) > 1 { 315 switch value.Kind() { 316 // struct will match named return values to the struct's field 317 // names 318 case reflect.Struct: 319 for i := 0; i < len(method.Outputs); i++ { 320 marshalledValue, err := toGoType(i, method.Outputs[i], output) 321 if err != nil { 322 return err 323 } 324 reflectValue := reflect.ValueOf(marshalledValue) 325 326 for j := 0; j < typ.NumField(); j++ { 327 field := typ.Field(j) 328 // TODO read tags: `abi:"fieldName"` 329 if field.Name == strings.ToUpper(method.Outputs[i].Name[:1])+method.Outputs[i].Name[1:] { 330 if err := set(value.Field(j), reflectValue, method.Outputs[i]); err != nil { 331 return err 332 } 333 } 334 } 335 } 336 case reflect.Slice: 337 if !value.Type().AssignableTo(r_interSlice) { 338 return fmt.Errorf("abi: cannot marshal tuple in to slice %T (only []interface{} is supported)", v) 339 } 340 341 // if the slice already contains values, set those instead of the interface slice itself. 342 if value.Len() > 0 { 343 if len(method.Outputs) > value.Len() { 344 return fmt.Errorf("abi: cannot marshal in to slices of unequal size (require: %v, got: %v)", len(method.Outputs), value.Len()) 345 } 346 347 for i := 0; i < len(method.Outputs); i++ { 348 marshalledValue, err := toGoType(i, method.Outputs[i], output) 349 if err != nil { 350 return err 351 } 352 reflectValue := reflect.ValueOf(marshalledValue) 353 if err := set(value.Index(i).Elem(), reflectValue, method.Outputs[i]); err != nil { 354 return err 355 } 356 } 357 return nil 358 } 359 360 // create a new slice and start appending the unmarshalled 361 // values to the new interface slice. 362 z := reflect.MakeSlice(typ, 0, len(method.Outputs)) 363 for i := 0; i < len(method.Outputs); i++ { 364 marshalledValue, err := toGoType(i, method.Outputs[i], output) 365 if err != nil { 366 return err 367 } 368 z = reflect.Append(z, reflect.ValueOf(marshalledValue)) 369 } 370 value.Set(z) 371 default: 372 return fmt.Errorf("abi: cannot unmarshal tuple in to %v", typ) 373 } 374 375 } else { 376 marshalledValue, err := toGoType(0, method.Outputs[0], output) 377 if err != nil { 378 return err 379 } 380 if err := set(value, reflect.ValueOf(marshalledValue), method.Outputs[0]); err != nil { 381 return err 382 } 383 } 384 385 return nil 386 } 387 388 func (abi *ABI) UnmarshalJSON(data []byte) error { 389 var fields []struct { 390 Type string 391 Name string 392 Constant bool 393 Indexed bool 394 Anonymous bool 395 Inputs []Argument 396 Outputs []Argument 397 } 398 399 if err := json.Unmarshal(data, &fields); err != nil { 400 return err 401 } 402 403 abi.Methods = make(map[string]Method) 404 abi.Events = make(map[string]Event) 405 for _, field := range fields { 406 switch field.Type { 407 case "constructor": 408 abi.Constructor = Method{ 409 Inputs: field.Inputs, 410 } 411 // empty defaults to function according to the abi spec 412 case "function", "": 413 abi.Methods[field.Name] = Method{ 414 Name: field.Name, 415 Const: field.Constant, 416 Inputs: field.Inputs, 417 Outputs: field.Outputs, 418 } 419 case "event": 420 abi.Events[field.Name] = Event{ 421 Name: field.Name, 422 Anonymous: field.Anonymous, 423 Inputs: field.Inputs, 424 } 425 } 426 } 427 428 return nil 429 }