github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/execution/evm/abi/primitives.go (about) 1 package abi 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "math/big" 7 "reflect" 8 "strings" 9 "unsafe" // just for Sizeof 10 11 "github.com/hyperledger/burrow/crypto" 12 ) 13 14 // EVM Solidity calls and return values are packed into 15 // pieces of 32 bytes, including a bool (wasting 255 out of 256 bits) 16 const ElementSize = 32 17 18 type EVMType interface { 19 GetSignature() string 20 getGoType() interface{} 21 pack(v interface{}) ([]byte, error) 22 unpack(data []byte, offset int, v interface{}) (int, error) 23 Dynamic() bool 24 ImplicitCast(o EVMType) bool 25 } 26 27 var _ EVMType = (*EVMBool)(nil) 28 29 type EVMBool struct { 30 } 31 32 func (e EVMBool) String() string { 33 return "EVMBool" 34 } 35 36 func (e EVMBool) GetSignature() string { 37 return "bool" 38 } 39 40 func (e EVMBool) getGoType() interface{} { 41 return new(bool) 42 } 43 44 func (e EVMBool) pack(v interface{}) ([]byte, error) { 45 var b bool 46 arg := reflect.ValueOf(v) 47 if arg.Kind() == reflect.String { 48 val := arg.String() 49 if strings.EqualFold(val, "true") || val == "1" { 50 b = true 51 } else if strings.EqualFold(val, "false") || val == "0" { 52 b = false 53 } else { 54 return nil, fmt.Errorf("%s is not a valid value for EVM Bool type", val) 55 } 56 } else if arg.Kind() == reflect.Bool { 57 b = arg.Bool() 58 } else { 59 return nil, fmt.Errorf("%s cannot be converted to EVM Bool type", arg.Kind().String()) 60 } 61 res := make([]byte, ElementSize) 62 if b { 63 res[ElementSize-1] = 1 64 } 65 return res, nil 66 } 67 68 func (e EVMBool) unpack(data []byte, offset int, v interface{}) (int, error) { 69 if len(data)-offset < 32 { 70 return 0, fmt.Errorf("%v: not enough data", e) 71 } 72 data = data[offset:] 73 switch v := v.(type) { 74 case *string: 75 if data[ElementSize-1] == 1 { 76 *v = "true" 77 } else if data[ElementSize-1] == 0 { 78 *v = "false" 79 } else { 80 return 0, fmt.Errorf("unexpected value for EVM bool") 81 } 82 case *int8: 83 *v = int8(data[ElementSize-1]) 84 case *int16: 85 *v = int16(data[ElementSize-1]) 86 case *int32: 87 *v = int32(data[ElementSize-1]) 88 case *int64: 89 *v = int64(data[ElementSize-1]) 90 case *int: 91 *v = int(data[ElementSize-1]) 92 case *uint8: 93 *v = uint8(data[ElementSize-1]) 94 case *uint16: 95 *v = uint16(data[ElementSize-1]) 96 case *uint32: 97 *v = uint32(data[ElementSize-1]) 98 case *uint64: 99 *v = uint64(data[ElementSize-1]) 100 case *uint: 101 *v = uint(data[ElementSize-1]) 102 case *bool: 103 *v = data[ElementSize-1] == 1 104 default: 105 return 0, fmt.Errorf("cannot set type %s for EVM bool", reflect.ValueOf(v).Kind().String()) 106 } 107 return 32, nil 108 } 109 110 func (e EVMBool) Dynamic() bool { 111 return false 112 } 113 114 func (e EVMBool) ImplicitCast(o EVMType) bool { 115 return false 116 } 117 118 var _ EVMType = (*EVMUint)(nil) 119 120 type EVMUint struct { 121 M uint64 122 } 123 124 func (e EVMUint) GetSignature() string { 125 return fmt.Sprintf("uint%d", e.M) 126 } 127 128 func (e EVMUint) getGoType() interface{} { 129 switch e.M { 130 case 8: 131 return new(uint8) 132 case 16: 133 return new(uint16) 134 case 32: 135 return new(uint32) 136 case 64: 137 return new(uint64) 138 default: 139 return new(big.Int) 140 } 141 } 142 143 func (e EVMUint) pack(v interface{}) ([]byte, error) { 144 n := new(big.Int) 145 146 arg := reflect.ValueOf(v) 147 switch arg.Kind() { 148 case reflect.String: 149 _, ok := n.SetString(arg.String(), 0) 150 if !ok { 151 return nil, fmt.Errorf("Failed to parse `%s", arg.String()) 152 } 153 if n.Sign() < 0 { 154 return nil, fmt.Errorf("negative value not allowed for uint%d", e.M) 155 } 156 case reflect.Uint8: 157 fallthrough 158 case reflect.Uint16: 159 fallthrough 160 case reflect.Uint32: 161 fallthrough 162 case reflect.Uint64: 163 fallthrough 164 case reflect.Uint: 165 n.SetUint64(arg.Uint()) 166 case reflect.Int8: 167 fallthrough 168 case reflect.Int16: 169 fallthrough 170 case reflect.Int32: 171 fallthrough 172 case reflect.Int64: 173 fallthrough 174 case reflect.Int: 175 x := arg.Int() 176 if x < 0 { 177 return nil, fmt.Errorf("negative value not allowed for uint%d", e.M) 178 } 179 n.SetInt64(x) 180 default: 181 t := reflect.TypeOf(new(uint64)) 182 if reflect.TypeOf(v).ConvertibleTo(t) { 183 n.SetUint64(reflect.ValueOf(v).Convert(t).Uint()) 184 } else { 185 return nil, fmt.Errorf("cannot convert type %s to uint%d", arg.Kind().String(), e.M) 186 } 187 } 188 189 b := n.Bytes() 190 if uint64(len(b)) > e.M { 191 return nil, fmt.Errorf("value too large for int%d", e.M) 192 } 193 return pad(b, ElementSize, true), nil 194 } 195 196 func (e EVMUint) unpack(data []byte, offset int, v interface{}) (int, error) { 197 if len(data)-offset < ElementSize { 198 return 0, fmt.Errorf("%v: not enough data", e) 199 } 200 201 data = data[offset:] 202 empty := 0 203 for empty = 0; empty < ElementSize; empty++ { 204 if data[empty] != 0 { 205 break 206 } 207 } 208 209 length := ElementSize - empty 210 211 switch v := v.(type) { 212 case *string: 213 b := new(big.Int) 214 b.SetBytes(data[empty:ElementSize]) 215 *v = b.String() 216 case *big.Int: 217 b := new(big.Int) 218 *v = *b.SetBytes(data[0:ElementSize]) 219 case *uint64: 220 maxLen := int(unsafe.Sizeof(*v)) 221 if length > maxLen { 222 return 0, fmt.Errorf("value too large for uint64") 223 } 224 *v = binary.BigEndian.Uint64(data[ElementSize-maxLen : ElementSize]) 225 case *uint32: 226 maxLen := int(unsafe.Sizeof(*v)) 227 if length > maxLen { 228 return 0, fmt.Errorf("value too large for uint64") 229 } 230 *v = binary.BigEndian.Uint32(data[ElementSize-maxLen : ElementSize]) 231 case *uint16: 232 maxLen := int(unsafe.Sizeof(*v)) 233 if length > maxLen { 234 return 0, fmt.Errorf("value too large for uint16") 235 } 236 *v = binary.BigEndian.Uint16(data[ElementSize-maxLen : ElementSize]) 237 case *uint8: 238 maxLen := 1 239 if length > maxLen { 240 return 0, fmt.Errorf("value too large for uint8") 241 } 242 *v = uint8(data[31]) 243 case *int64: 244 maxLen := int(unsafe.Sizeof(*v)) 245 if length > maxLen || (data[ElementSize-maxLen]&0x80) != 0 { 246 return 0, fmt.Errorf("value too large for int64") 247 } 248 *v = int64(binary.BigEndian.Uint64(data[ElementSize-maxLen : ElementSize])) 249 case *int32: 250 maxLen := int(unsafe.Sizeof(*v)) 251 if length > maxLen || (data[ElementSize-maxLen]&0x80) != 0 { 252 return 0, fmt.Errorf("value too large for int32") 253 } 254 *v = int32(binary.BigEndian.Uint32(data[ElementSize-maxLen : ElementSize])) 255 case *int16: 256 maxLen := int(unsafe.Sizeof(*v)) 257 if length > maxLen || (data[ElementSize-maxLen]&0x80) != 0 { 258 return 0, fmt.Errorf("value too large for int16") 259 } 260 *v = int16(binary.BigEndian.Uint16(data[ElementSize-maxLen : ElementSize])) 261 case *int8: 262 maxLen := 1 263 if length > maxLen || (data[ElementSize-maxLen]&0x80) != 0 { 264 return 0, fmt.Errorf("value too large for int8") 265 } 266 *v = int8(data[ElementSize-1]) 267 default: 268 return 0, fmt.Errorf("unable to convert %s to %s", e.GetSignature(), reflect.ValueOf(v).Kind().String()) 269 } 270 271 return 32, nil 272 } 273 274 func (e EVMUint) Dynamic() bool { 275 return false 276 } 277 278 func (e EVMUint) String() string { 279 return fmt.Sprintf("EVMUInt{%v}", e.M) 280 } 281 282 var _ EVMType = (*EVMInt)(nil) 283 284 type EVMInt struct { 285 M uint64 286 } 287 288 func (e EVMInt) String() string { 289 return fmt.Sprintf("EVMInt{%v}", e.M) 290 } 291 292 func (e EVMInt) getGoType() interface{} { 293 switch e.M { 294 case 8: 295 return new(int8) 296 case 16: 297 return new(int16) 298 case 32: 299 return new(int32) 300 case 64: 301 return new(int64) 302 default: 303 return new(big.Int) 304 } 305 } 306 307 func (e EVMInt) ImplicitCast(o EVMType) bool { 308 i, ok := o.(EVMInt) 309 return ok && i.M >= e.M 310 } 311 312 func (e EVMInt) GetSignature() string { 313 return fmt.Sprintf("int%d", e.M) 314 } 315 316 func (e EVMInt) pack(v interface{}) ([]byte, error) { 317 n := new(big.Int) 318 319 switch arg := v.(type) { 320 case *big.Int: 321 n.Set(arg) 322 case string: 323 _, ok := n.SetString(arg, 0) 324 if !ok { 325 return nil, fmt.Errorf("failed to parse `%s", arg) 326 } 327 case uint: 328 n.SetUint64(uint64(arg)) 329 case uint8: 330 n.SetUint64(uint64(arg)) 331 case uint16: 332 n.SetUint64(uint64(arg)) 333 case uint32: 334 n.SetUint64(uint64(arg)) 335 case uint64: 336 n.SetUint64(arg) 337 case int: 338 n.SetInt64(int64(arg)) 339 case int8: 340 n.SetInt64(int64(arg)) 341 case int16: 342 n.SetInt64(int64(arg)) 343 case int32: 344 n.SetInt64(int64(arg)) 345 case int64: 346 n.SetInt64(arg) 347 default: 348 t := reflect.TypeOf(new(int64)) 349 if reflect.TypeOf(v).ConvertibleTo(t) { 350 n.SetInt64(reflect.ValueOf(v).Convert(t).Int()) 351 } else { 352 return nil, fmt.Errorf("cannot convert type %v to int%d", v, e.M) 353 } 354 } 355 356 b := n.Bytes() 357 if uint64(len(b)) > e.M { 358 return nil, fmt.Errorf("value too large for int%d", e.M) 359 } 360 res := pad(b, ElementSize, true) 361 if (res[0] & 0x80) != 0 { 362 return nil, fmt.Errorf("value too large for int%d", e.M) 363 } 364 if n.Sign() < 0 { 365 // One's complement; i.e. 0xffff is -1, not 0. 366 n.Add(n, big.NewInt(1)) 367 b := n.Bytes() 368 res = pad(b, ElementSize, true) 369 for i := 0; i < len(res); i++ { 370 res[i] = ^res[i] 371 } 372 } 373 return res, nil 374 } 375 376 func (e EVMInt) unpack(data []byte, offset int, v interface{}) (int, error) { 377 if len(data)-offset < ElementSize { 378 return 0, fmt.Errorf("%v: not enough data", e) 379 } 380 381 data = data[offset:] 382 sign := (data[0] & 0x80) != 0 383 384 empty := 0 385 for empty = 0; empty < ElementSize; empty++ { 386 if (sign && data[empty] != 255) || (!sign && data[empty] != 0) { 387 break 388 } 389 } 390 391 length := ElementSize - empty 392 inv := make([]byte, ElementSize) 393 for i := 0; i < ElementSize; i++ { 394 if sign { 395 inv[i] = ^data[i] 396 } else { 397 inv[i] = data[i] 398 } 399 } 400 401 switch v := v.(type) { 402 case **big.Int: 403 b := new(big.Int).SetBytes(inv[empty:ElementSize]) 404 if sign { 405 *v = b.Sub(big.NewInt(-1), b) 406 } else { 407 *v = b 408 } 409 case *string: 410 b := new(big.Int) 411 b.SetBytes(inv[empty:ElementSize]) 412 if sign { 413 *v = b.Sub(big.NewInt(-1), b).String() 414 } else { 415 *v = b.String() 416 } 417 case *big.Int: 418 b := new(big.Int) 419 b.SetBytes(inv[0:ElementSize]) 420 if sign { 421 *v = *b.Sub(big.NewInt(-1), b) 422 } else { 423 *v = *b 424 } 425 case *uint64: 426 if sign { 427 return 0, fmt.Errorf("cannot convert negative EVM int to %T", *v) 428 } 429 maxLen := int(unsafe.Sizeof(*v)) 430 if length > maxLen { 431 return 0, fmt.Errorf("value too large for %T", *v) 432 } 433 *v = binary.BigEndian.Uint64(data[ElementSize-maxLen : ElementSize]) 434 case *uint32: 435 if sign { 436 return 0, fmt.Errorf("cannot convert negative EVM int to %T", *v) 437 } 438 maxLen := int(unsafe.Sizeof(*v)) 439 if length > maxLen { 440 return 0, fmt.Errorf("value too large for %T", *v) 441 } 442 *v = binary.BigEndian.Uint32(data[ElementSize-maxLen : ElementSize]) 443 case *uint16: 444 if sign { 445 return 0, fmt.Errorf("cannot convert negative EVM int to %T", *v) 446 } 447 maxLen := int(unsafe.Sizeof(*v)) 448 if length > maxLen { 449 return 0, fmt.Errorf("value too large for %T", *v) 450 } 451 *v = binary.BigEndian.Uint16(data[ElementSize-maxLen : ElementSize]) 452 case *uint8: 453 if sign { 454 return 0, fmt.Errorf("cannot convert negative EVM int to %T", *v) 455 } 456 if length > 1 { 457 return 0, fmt.Errorf("value too large for %T", *v) 458 } 459 *v = data[ElementSize-1] 460 case *int64: 461 maxLen := int(unsafe.Sizeof(*v)) 462 if length > maxLen || (inv[ElementSize-maxLen]&0x80) != 0 { 463 return 0, fmt.Errorf("value too large for %T", *v) 464 } 465 *v = int64(binary.BigEndian.Uint64(data[ElementSize-maxLen : ElementSize])) 466 case *int32: 467 maxLen := int(unsafe.Sizeof(*v)) 468 if length > maxLen || (inv[ElementSize-maxLen]&0x80) != 0 { 469 return 0, fmt.Errorf("value too large for %T", *v) 470 } 471 *v = int32(binary.BigEndian.Uint32(data[ElementSize-maxLen : ElementSize])) 472 case *int16: 473 maxLen := int(unsafe.Sizeof(*v)) 474 if length > maxLen || (inv[ElementSize-maxLen]&0x80) != 0 { 475 return 0, fmt.Errorf("value too large for %T", *v) 476 } 477 *v = int16(binary.BigEndian.Uint16(data[ElementSize-maxLen : ElementSize])) 478 case *int8: 479 if length > 1 || (inv[ElementSize-1]&0x80) != 0 { 480 return 0, fmt.Errorf("value too large for %T", *v) 481 } 482 *v = int8(data[ElementSize-1]) 483 default: 484 return 0, fmt.Errorf("unable to convert %s to %T", e.GetSignature(), v) 485 } 486 487 return ElementSize, nil 488 } 489 490 func (e EVMInt) Dynamic() bool { 491 return false 492 } 493 494 func (e EVMUint) ImplicitCast(o EVMType) bool { 495 u, ok := o.(EVMUint) 496 return ok && u.M >= e.M 497 } 498 499 var _ EVMType = (*EVMAddress)(nil) 500 501 type EVMAddress struct { 502 } 503 504 func (e EVMAddress) String() string { 505 return "EVMAddress" 506 } 507 508 func (e EVMAddress) getGoType() interface{} { 509 return new(crypto.Address) 510 } 511 512 func (e EVMAddress) GetSignature() string { 513 return "address" 514 } 515 516 func (e EVMAddress) pack(v interface{}) ([]byte, error) { 517 var bs []byte 518 switch a := v.(type) { 519 case crypto.Address: 520 bs = a[:] 521 case *crypto.Address: 522 bs = (*a)[:] 523 case string: 524 address, err := crypto.AddressFromHexString(a) 525 if err != nil { 526 return nil, fmt.Errorf("could not convert '%s' to address: %v", a, err) 527 } 528 bs = address[:] 529 case []byte: 530 address, err := crypto.AddressFromBytes(a) 531 if err != nil { 532 return nil, fmt.Errorf("could not convert byte 0x%X to address: %v", a, err) 533 } 534 bs = address[:] 535 default: 536 return nil, fmt.Errorf("cannot map from %s to EVM address", reflect.ValueOf(v).Kind().String()) 537 } 538 return pad(bs, ElementSize, true), nil 539 } 540 541 func (e EVMAddress) unpack(data []byte, offset int, v interface{}) (int, error) { 542 if len(data)-offset < ElementSize { 543 return 0, fmt.Errorf("%v: not enough data", e) 544 } 545 addr, err := crypto.AddressFromBytes(data[offset+ElementSize-crypto.AddressLength : offset+ElementSize]) 546 if err != nil { 547 return 0, err 548 } 549 switch v := v.(type) { 550 case *string: 551 *v = addr.String() 552 case *crypto.Address: 553 *v = addr 554 case *([]byte): 555 *v = data[offset+ElementSize-crypto.AddressLength : offset+ElementSize] 556 default: 557 return 0, fmt.Errorf("cannot map EVM address to %s", reflect.ValueOf(v).Kind().String()) 558 } 559 560 return ElementSize, nil 561 } 562 563 func (e EVMAddress) Dynamic() bool { 564 return false 565 } 566 567 func (e EVMAddress) ImplicitCast(o EVMType) bool { 568 return false 569 } 570 571 var _ EVMType = (*EVMBytes)(nil) 572 573 type EVMBytes struct { 574 M uint64 575 } 576 577 func (e EVMBytes) String() string { 578 if e.M == 0 { 579 return "EVMBytes" 580 } 581 return fmt.Sprintf("EVMBytes[%v]", e.M) 582 } 583 584 func (e EVMBytes) getGoType() interface{} { 585 v := make([]byte, e.M) 586 return &v 587 } 588 589 func (e EVMBytes) pack(v interface{}) ([]byte, error) { 590 b, ok := v.([]byte) 591 if !ok { 592 s, ok := v.(string) 593 if ok { 594 b = []byte(s) 595 } else { 596 return nil, fmt.Errorf("cannot map from %s to EVM bytes", reflect.ValueOf(v).Kind().String()) 597 } 598 } 599 600 if e.M > 0 { 601 if uint64(len(b)) > e.M { 602 return nil, fmt.Errorf("[%d]byte to long for %s", len(b), e.GetSignature()) 603 } 604 return pad(b, ElementSize, false), nil 605 } else { 606 length := EVMUint{M: 256} 607 p, err := length.pack(len(b)) 608 if err != nil { 609 return nil, err 610 } 611 for i := 0; i < len(b); i += ElementSize { 612 a := b[i:] 613 if len(a) == 0 { 614 break 615 } 616 p = append(p, pad(a, ElementSize, false)...) 617 } 618 619 return p, nil 620 } 621 } 622 623 func (e EVMBytes) unpack(data []byte, offset int, v interface{}) (int, error) { 624 if len(data)-offset < ElementSize { 625 return 0, fmt.Errorf("%v: not enough data", e) 626 } 627 if e.M == 0 { 628 s := EVMString{} 629 630 return s.unpack(data, offset, v) 631 } 632 633 v2 := reflect.ValueOf(v).Elem() 634 switch v2.Type().Kind() { 635 case reflect.String: 636 start := 0 637 end := int(e.M) 638 639 for start < ElementSize-1 && data[offset+start] == 0 && start < end { 640 start++ 641 } 642 for end > start && data[offset+end-1] == 0 { 643 end-- 644 } 645 v2.SetString(string(data[offset+start : offset+end])) 646 case reflect.Array: 647 fallthrough 648 case reflect.Slice: 649 v2.SetBytes(data[offset : offset+int(e.M)]) 650 default: 651 return 0, fmt.Errorf("cannot map EVM %s to %v", e.GetSignature(), reflect.ValueOf(v).Kind()) 652 } 653 654 return ElementSize, nil 655 } 656 657 func (e EVMBytes) Dynamic() bool { 658 return e.M == 0 659 } 660 661 func (e EVMBytes) GetSignature() string { 662 if e.M > 0 { 663 return fmt.Sprintf("bytes%d", e.M) 664 } else { 665 return "bytes" 666 } 667 } 668 669 func (e EVMBytes) ImplicitCast(o EVMType) bool { 670 return false 671 } 672 673 var _ EVMType = (*EVMString)(nil) 674 675 type EVMString struct { 676 } 677 678 func (e EVMString) String() string { 679 return "EVMString" 680 } 681 682 func (e EVMString) GetSignature() string { 683 return "string" 684 } 685 686 func (e EVMString) getGoType() interface{} { 687 return new(string) 688 } 689 690 func (e EVMString) pack(v interface{}) ([]byte, error) { 691 b := EVMBytes{M: 0} 692 693 return b.pack(v) 694 } 695 696 func (e EVMString) unpack(data []byte, offset int, v interface{}) (int, error) { 697 lenType := EVMInt{M: 64} 698 var length int64 699 l, err := lenType.unpack(data, offset, &length) 700 if err != nil { 701 return 0, fmt.Errorf("could not unpack string length prefix: %v", err) 702 } 703 offset += l 704 705 switch v := v.(type) { 706 case *string: 707 *v = string(data[offset : offset+int(length)]) 708 case *[]byte: 709 *v = data[offset : offset+int(length)] 710 default: 711 return 0, fmt.Errorf("cannot map EVM string to %s", reflect.ValueOf(v).Kind().String()) 712 } 713 714 return ElementSize, nil 715 } 716 717 func (e EVMString) Dynamic() bool { 718 return true 719 } 720 721 func (e EVMString) ImplicitCast(o EVMType) bool { 722 return false 723 } 724 725 var _ EVMType = (*EVMFixed)(nil) 726 727 type EVMFixed struct { 728 N, M uint64 729 signed bool 730 } 731 732 func (e EVMFixed) getGoType() interface{} { 733 // This is not right, obviously 734 return new(big.Float) 735 } 736 737 func (e EVMFixed) GetSignature() string { 738 if e.signed { 739 return fmt.Sprintf("fixed%dx%d", e.M, e.N) 740 } else { 741 return fmt.Sprintf("ufixed%dx%d", e.M, e.N) 742 } 743 } 744 745 func (e EVMFixed) pack(v interface{}) ([]byte, error) { 746 // The ABI spec does not describe how this should be packed; go-ethereum abi does not implement this 747 // need to dig in solidity to find out how this is packed 748 return nil, fmt.Errorf("packing of %s not implemented, patches welcome", e.GetSignature()) 749 } 750 751 func (e EVMFixed) unpack(data []byte, offset int, v interface{}) (int, error) { 752 // The ABI spec does not describe how this should be packed; go-ethereum abi does not implement this 753 // need to dig in solidity to find out how this is packed 754 return 0, fmt.Errorf("unpacking of %s not implemented, patches welcome", e.GetSignature()) 755 } 756 757 func (e EVMFixed) Dynamic() bool { 758 return false 759 } 760 761 func (e EVMFixed) ImplicitCast(o EVMType) bool { 762 return false 763 } 764 765 // quick helper padding 766 func pad(input []byte, size int, left bool) []byte { 767 if len(input) >= size { 768 return input[:size] 769 } 770 padded := make([]byte, size) 771 if left { 772 copy(padded[size-len(input):], input) 773 } else { 774 copy(padded, input) 775 } 776 return padded 777 }