github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/types/address.go (about) 1 package types 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "encoding/json" 7 "errors" 8 "fmt" 9 "strings" 10 11 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto" 12 tmamino "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/encoding/amino" 13 yaml "gopkg.in/yaml.v2" 14 15 "github.com/fibonacci-chain/fbc/libs/tendermint/libs/bech32" 16 ) 17 18 const ( 19 // Constants defined here are the defaults value for address. 20 // You can use the specific values for your project. 21 // Add the follow lines to the `main()` of your server. 22 // 23 // config := sdk.GetConfig() 24 // config.SetBech32PrefixForAccount(yourBech32PrefixAccAddr, yourBech32PrefixAccPub) 25 // config.SetBech32PrefixForValidator(yourBech32PrefixValAddr, yourBech32PrefixValPub) 26 // config.SetBech32PrefixForConsensusNode(yourBech32PrefixConsAddr, yourBech32PrefixConsPub) 27 // config.SetCoinType(yourCoinType) 28 // config.SetFullFundraiserPath(yourFullFundraiserPath) 29 // config.Seal() 30 31 // AddrLen defines a valid address length 32 AddrLen = 20 33 // WasmContractAddrLen defines a valid wasm contract address length 34 WasmContractAddrLen = 32 35 // Bech32MainPrefix defines the main SDK Bech32 prefix of an account's address 36 Bech32MainPrefix = "cosmos" 37 38 // CoinType is the ATOM coin type as defined in SLIP44 (https://github.com/satoshilabs/slips/blob/master/slip-0044.md) 39 CoinType = 118 40 41 // FullFundraiserPath is the parts of the BIP44 HD path that are fixed by 42 // what we used during the ATOM fundraiser. 43 FullFundraiserPath = "m/44'/118'/0'/0/0" 44 45 // PrefixAccount is the prefix for account keys 46 PrefixAccount = "acc" 47 // PrefixValidator is the prefix for validator keys 48 PrefixValidator = "val" 49 // PrefixConsensus is the prefix for consensus keys 50 PrefixConsensus = "cons" 51 // PrefixPublic is the prefix for public keys 52 PrefixPublic = "pub" 53 // PrefixOperator is the prefix for operator keys 54 PrefixOperator = "oper" 55 56 // PrefixAddress is the prefix for addresses 57 PrefixAddress = "addr" 58 59 // Bech32PrefixAccAddr defines the Bech32 prefix of an account's address 60 Bech32PrefixAccAddr = Bech32MainPrefix 61 // Bech32PrefixAccPub defines the Bech32 prefix of an account's public key 62 Bech32PrefixAccPub = Bech32MainPrefix + PrefixPublic 63 // Bech32PrefixValAddr defines the Bech32 prefix of a validator's operator address 64 Bech32PrefixValAddr = Bech32MainPrefix + PrefixValidator + PrefixOperator 65 // Bech32PrefixValPub defines the Bech32 prefix of a validator's operator public key 66 Bech32PrefixValPub = Bech32MainPrefix + PrefixValidator + PrefixOperator + PrefixPublic 67 // Bech32PrefixConsAddr defines the Bech32 prefix of a consensus node address 68 Bech32PrefixConsAddr = Bech32MainPrefix + PrefixValidator + PrefixConsensus 69 // Bech32PrefixConsPub defines the Bech32 prefix of a consensus node public key 70 Bech32PrefixConsPub = Bech32MainPrefix + PrefixValidator + PrefixConsensus + PrefixPublic 71 ) 72 73 // Address is a common interface for different types of addresses used by the SDK 74 type Address interface { 75 Equals(Address) bool 76 Empty() bool 77 Marshal() ([]byte, error) 78 MarshalJSON() ([]byte, error) 79 Bytes() []byte 80 String() string 81 Format(s fmt.State, verb rune) 82 } 83 84 // Ensure that different address types implement the interface 85 var _ Address = AccAddress{} 86 var _ Address = ValAddress{} 87 var _ Address = ConsAddress{} 88 89 var _ yaml.Marshaler = AccAddress{} 90 var _ yaml.Marshaler = ValAddress{} 91 var _ yaml.Marshaler = ConsAddress{} 92 93 // ---------------------------------------------------------------------------- 94 // account 95 // ---------------------------------------------------------------------------- 96 97 // AccAddress a wrapper around bytes meant to represent an account address. 98 // When marshaled to a string or JSON, it uses Bech32. 99 type AccAddress []byte 100 101 func IsWasmAddress(acc AccAddress) bool { 102 return len(acc) == WasmContractAddrLen 103 } 104 105 func IsETHAddress(addr string) bool { 106 return strings.HasPrefix(addr, "0x") 107 } 108 109 func IsFBCAddress(addr string) bool { 110 return strings.HasPrefix(addr, GetConfig().GetBech32AccountAddrPrefix()) 111 } 112 113 // AccAddressFromHex creates an AccAddress from a hex string. 114 func AccAddressFromHex(address string) (addr AccAddress, err error) { 115 if len(address) == 0 { 116 return addr, errors.New("decoding Bech32 address failed: must provide an address") 117 } 118 119 bz, err := hex.DecodeString(address) 120 if err != nil { 121 return nil, err 122 } 123 124 return AccAddress(bz), nil 125 } 126 127 // VerifyAddressFormat verifies that the provided bytes form a valid address 128 // according to the default address rules or a custom address verifier set by 129 // GetConfig().SetAddressVerifier() 130 func VerifyAddressFormat(bz []byte) error { 131 verifier := GetConfig().GetAddressVerifier() 132 if verifier != nil { 133 return verifier(bz) 134 } 135 if len(bz) != AddrLen && len(bz) != WasmContractAddrLen { 136 return errors.New("incorrect address length") 137 } 138 return nil 139 } 140 141 // MustAccAddressFromBech32 calls AccAddressFromBech32 and panics on error. 142 func MustAccAddressFromBech32(address string) AccAddress { 143 addr, err := AccAddressFromBech32(address) 144 if err != nil { 145 panic(err) 146 } 147 148 return addr 149 } 150 151 // AccAddressFromBech32 creates an AccAddress from a Bech32 string. 152 func AccAddressFromBech32(address string) (AccAddress, error) { 153 return AccAddressFromBech32ByPrefix(address, GetConfig().GetBech32AccountAddrPrefix()) 154 } 155 156 // AccAddressFromBech32ByPrefix create an AccAddress from a Bech32 string by address prefix 157 func AccAddressFromBech32ByPrefix(address string, bech32PrefixAccAddr string) (addr AccAddress, err error) { 158 if len(strings.TrimSpace(address)) == 0 { 159 return nil, errors.New("empty address string is not allowed") 160 } 161 162 if !strings.HasPrefix(address, bech32PrefixAccAddr) { 163 // strip 0x prefix if exists 164 addrStr := strings.TrimPrefix(address, "0x") 165 addr, err = AccAddressFromHex(addrStr) 166 if err != nil { 167 return addr, err 168 } 169 return addr, VerifyAddressFormat(addr) 170 } 171 172 //decodes a bytestring from a Bech32 encoded string 173 bz, err := GetFromBech32(address, bech32PrefixAccAddr) 174 if err != nil { 175 return nil, err 176 } 177 178 err = VerifyAddressFormat(bz) 179 if err != nil { 180 return nil, err 181 } 182 183 return AccAddress(bz), nil 184 } 185 186 // Returns boolean for whether two AccAddresses are Equal 187 func (aa AccAddress) Equals(aa2 Address) bool { 188 if aa.Empty() && aa2.Empty() { 189 return true 190 } 191 192 return bytes.Equal(aa.Bytes(), aa2.Bytes()) 193 } 194 195 // Returns boolean for whether an AccAddress is empty 196 func (aa AccAddress) Empty() bool { 197 if aa == nil { 198 return true 199 } 200 201 aa2 := AccAddress{} 202 return bytes.Equal(aa.Bytes(), aa2.Bytes()) 203 } 204 205 // Marshal returns the raw address bytes. It is needed for protobuf 206 // compatibility. 207 func (aa AccAddress) Marshal() ([]byte, error) { 208 return aa, nil 209 } 210 211 // Unmarshal sets the address to the given data. It is needed for protobuf 212 // compatibility. 213 func (aa *AccAddress) Unmarshal(data []byte) error { 214 *aa = data 215 return nil 216 } 217 218 // MarshalJSON marshals to JSON using Bech32. 219 func (aa AccAddress) MarshalJSON() ([]byte, error) { 220 return json.Marshal(aa.String()) 221 } 222 223 // MarshalYAML marshals to YAML using Bech32. 224 func (aa AccAddress) MarshalYAML() (interface{}, error) { 225 return aa.String(), nil 226 } 227 228 // UnmarshalJSON unmarshals from JSON assuming Bech32 encoding. 229 func (aa *AccAddress) UnmarshalJSON(data []byte) error { 230 var s string 231 err := json.Unmarshal(data, &s) 232 if err != nil { 233 return err 234 } 235 236 if s == "" { 237 *aa = AccAddress{} 238 return nil 239 } 240 241 aa2, err := AccAddressFromBech32(s) 242 if err != nil { 243 return err 244 } 245 246 *aa = aa2 247 return nil 248 } 249 250 // UnmarshalYAML unmarshals from JSON assuming Bech32 encoding. 251 func (aa *AccAddress) UnmarshalYAML(data []byte) error { 252 var s string 253 err := yaml.Unmarshal(data, &s) 254 if err != nil { 255 return err 256 } 257 258 if s == "" { 259 *aa = AccAddress{} 260 return nil 261 } 262 263 aa2, err := AccAddressFromBech32(s) 264 if err != nil { 265 return err 266 } 267 268 *aa = aa2 269 return nil 270 } 271 272 // Bytes returns the raw address bytes. 273 func (aa AccAddress) Bytes() []byte { 274 return aa 275 } 276 277 // String implements the Stringer interface. 278 func (aa AccAddress) String() string { 279 if aa.Empty() { 280 return "" 281 } 282 283 return aa.Bech32StringOptimized(GetConfig().GetBech32AccountAddrPrefix()) 284 } 285 286 // Bech32String convert account address to bech32 address. 287 func (aa AccAddress) Bech32String(bech32PrefixAccAddr string) string { 288 bech32Addr, err := bech32.ConvertAndEncode(bech32PrefixAccAddr, aa.Bytes()) 289 if err != nil { 290 panic(err) 291 } 292 293 return bech32Addr 294 } 295 296 // Format implements the fmt.Formatter interface. 297 // nolint: errcheck 298 func (aa AccAddress) Format(s fmt.State, verb rune) { 299 switch verb { 300 case 's': 301 s.Write([]byte(aa.String())) 302 case 'p': 303 s.Write([]byte(fmt.Sprintf("%p", aa))) 304 default: 305 s.Write([]byte(fmt.Sprintf("%X", []byte(aa)))) 306 } 307 } 308 309 // ---------------------------------------------------------------------------- 310 // validator operator 311 // ---------------------------------------------------------------------------- 312 313 // ValAddress defines a wrapper around bytes meant to present a validator's 314 // operator. When marshaled to a string or JSON, it uses Bech32. 315 type ValAddress []byte 316 317 // ValAddressFromHex creates a ValAddress from a hex string. 318 func ValAddressFromHex(address string) (addr ValAddress, err error) { 319 if len(address) == 0 { 320 return addr, errors.New("decoding Bech32 address failed: must provide an address") 321 } 322 323 bz, err := hex.DecodeString(address) 324 if err != nil { 325 return nil, err 326 } 327 328 return ValAddress(bz), nil 329 } 330 331 // ValAddressFromBech32 creates a ValAddress from a Bech32 string. 332 func ValAddressFromBech32(address string) (addr ValAddress, err error) { 333 if len(strings.TrimSpace(address)) == 0 { 334 return nil, errors.New("empty address string is not allowed") 335 } 336 337 bech32PrefixValAddr := GetConfig().GetBech32ValidatorAddrPrefix() 338 339 bz, err := GetFromBech32(address, bech32PrefixValAddr) 340 if err != nil { 341 return nil, err 342 } 343 344 err = VerifyAddressFormat(bz) 345 if err != nil { 346 return nil, err 347 } 348 349 return ValAddress(bz), nil 350 } 351 352 // Returns boolean for whether two ValAddresses are Equal 353 func (va ValAddress) Equals(va2 Address) bool { 354 if va.Empty() && va2.Empty() { 355 return true 356 } 357 358 return bytes.Equal(va.Bytes(), va2.Bytes()) 359 } 360 361 // Returns boolean for whether an AccAddress is empty 362 func (va ValAddress) Empty() bool { 363 if va == nil { 364 return true 365 } 366 367 va2 := ValAddress{} 368 return bytes.Equal(va.Bytes(), va2.Bytes()) 369 } 370 371 // Marshal returns the raw address bytes. It is needed for protobuf 372 // compatibility. 373 func (va ValAddress) Marshal() ([]byte, error) { 374 return va, nil 375 } 376 377 // Unmarshal sets the address to the given data. It is needed for protobuf 378 // compatibility. 379 func (va *ValAddress) Unmarshal(data []byte) error { 380 *va = data 381 return nil 382 } 383 384 // MarshalJSON marshals to JSON using Bech32. 385 func (va ValAddress) MarshalJSON() ([]byte, error) { 386 return json.Marshal(va.String()) 387 } 388 389 // MarshalYAML marshals to YAML using Bech32. 390 func (va ValAddress) MarshalYAML() (interface{}, error) { 391 return va.String(), nil 392 } 393 394 // UnmarshalJSON unmarshals from JSON assuming Bech32 encoding. 395 func (va *ValAddress) UnmarshalJSON(data []byte) error { 396 var s string 397 398 err := json.Unmarshal(data, &s) 399 if err != nil { 400 return err 401 } 402 403 if s == "" { 404 *va = ValAddress{} 405 return nil 406 } 407 408 va2, err := ValAddressFromBech32(s) 409 if err != nil { 410 return err 411 } 412 413 *va = va2 414 return nil 415 } 416 417 // UnmarshalYAML unmarshals from YAML assuming Bech32 encoding. 418 func (va *ValAddress) UnmarshalYAML(data []byte) error { 419 var s string 420 421 err := yaml.Unmarshal(data, &s) 422 if err != nil { 423 return err 424 } 425 426 if s == "" { 427 *va = ValAddress{} 428 return nil 429 } 430 va2, err := ValAddressFromBech32(s) 431 if err != nil { 432 return err 433 } 434 435 *va = va2 436 return nil 437 } 438 439 // Bytes returns the raw address bytes. 440 func (va ValAddress) Bytes() []byte { 441 return va 442 } 443 444 // String implements the Stringer interface. 445 func (va ValAddress) String() string { 446 if va.Empty() { 447 return "" 448 } 449 450 bech32PrefixValAddr := GetConfig().GetBech32ValidatorAddrPrefix() 451 452 bech32Addr, err := bech32.ConvertAndEncode(bech32PrefixValAddr, va.Bytes()) 453 if err != nil { 454 panic(err) 455 } 456 457 return bech32Addr 458 } 459 460 // Format implements the fmt.Formatter interface. 461 // nolint: errcheck 462 func (va ValAddress) Format(s fmt.State, verb rune) { 463 switch verb { 464 case 's': 465 s.Write([]byte(va.String())) 466 case 'p': 467 s.Write([]byte(fmt.Sprintf("%p", va))) 468 default: 469 s.Write([]byte(fmt.Sprintf("%X", []byte(va)))) 470 } 471 } 472 473 // ---------------------------------------------------------------------------- 474 // consensus node 475 // ---------------------------------------------------------------------------- 476 477 // ConsAddress defines a wrapper around bytes meant to present a consensus node. 478 // When marshaled to a string or JSON, it uses Bech32. 479 type ConsAddress []byte 480 481 // ConsAddressFromHex creates a ConsAddress from a hex string. 482 func ConsAddressFromHex(address string) (addr ConsAddress, err error) { 483 if len(address) == 0 { 484 return addr, errors.New("decoding Bech32 address failed: must provide an address") 485 } 486 487 bz, err := hex.DecodeString(address) 488 if err != nil { 489 return nil, err 490 } 491 492 return ConsAddress(bz), nil 493 } 494 495 // ConsAddressFromBech32 creates a ConsAddress from a Bech32 string. 496 func ConsAddressFromBech32(address string) (addr ConsAddress, err error) { 497 if len(strings.TrimSpace(address)) == 0 { 498 return ConsAddress{}, errors.New("empty address string is not allowed") 499 } 500 501 bech32PrefixConsAddr := GetConfig().GetBech32ConsensusAddrPrefix() 502 503 bz, err := GetFromBech32(address, bech32PrefixConsAddr) 504 if err != nil { 505 return nil, err 506 } 507 508 err = VerifyAddressFormat(bz) 509 if err != nil { 510 return nil, err 511 } 512 513 return ConsAddress(bz), nil 514 } 515 516 // get ConsAddress from pubkey 517 func GetConsAddress(pubkey crypto.PubKey) ConsAddress { 518 return ConsAddress(pubkey.Address()) 519 } 520 521 // Returns boolean for whether two ConsAddress are Equal 522 func (ca ConsAddress) Equals(ca2 Address) bool { 523 if ca.Empty() && ca2.Empty() { 524 return true 525 } 526 527 return bytes.Equal(ca.Bytes(), ca2.Bytes()) 528 } 529 530 // Returns boolean for whether an ConsAddress is empty 531 func (ca ConsAddress) Empty() bool { 532 if ca == nil { 533 return true 534 } 535 536 ca2 := ConsAddress{} 537 return bytes.Equal(ca.Bytes(), ca2.Bytes()) 538 } 539 540 // Marshal returns the raw address bytes. It is needed for protobuf 541 // compatibility. 542 func (ca ConsAddress) Marshal() ([]byte, error) { 543 return ca, nil 544 } 545 546 // Unmarshal sets the address to the given data. It is needed for protobuf 547 // compatibility. 548 func (ca *ConsAddress) Unmarshal(data []byte) error { 549 *ca = data 550 return nil 551 } 552 553 // MarshalJSON marshals to JSON using Bech32. 554 func (ca ConsAddress) MarshalJSON() ([]byte, error) { 555 return json.Marshal(ca.String()) 556 } 557 558 // MarshalYAML marshals to YAML using Bech32. 559 func (ca ConsAddress) MarshalYAML() (interface{}, error) { 560 return ca.String(), nil 561 } 562 563 // UnmarshalJSON unmarshals from JSON assuming Bech32 encoding. 564 func (ca *ConsAddress) UnmarshalJSON(data []byte) error { 565 var s string 566 567 err := json.Unmarshal(data, &s) 568 if err != nil { 569 return err 570 } 571 572 if s == "" { 573 *ca = ConsAddress{} 574 return nil 575 } 576 577 ca2, err := ConsAddressFromBech32(s) 578 if err != nil { 579 return err 580 } 581 582 *ca = ca2 583 return nil 584 } 585 586 // UnmarshalYAML unmarshals from YAML assuming Bech32 encoding. 587 func (ca *ConsAddress) UnmarshalYAML(data []byte) error { 588 var s string 589 590 err := yaml.Unmarshal(data, &s) 591 if err != nil { 592 return err 593 } 594 595 if s == "" { 596 *ca = ConsAddress{} 597 return nil 598 } 599 600 ca2, err := ConsAddressFromBech32(s) 601 if err != nil { 602 return err 603 } 604 605 *ca = ca2 606 return nil 607 } 608 609 // Bytes returns the raw address bytes. 610 func (ca ConsAddress) Bytes() []byte { 611 return ca 612 } 613 614 // String implements the Stringer interface. 615 func (ca ConsAddress) String() string { 616 if ca.Empty() { 617 return "" 618 } 619 620 bech32PrefixConsAddr := GetConfig().GetBech32ConsensusAddrPrefix() 621 622 bech32Addr, err := bech32.ConvertAndEncode(bech32PrefixConsAddr, ca.Bytes()) 623 if err != nil { 624 panic(err) 625 } 626 627 return bech32Addr 628 } 629 630 // Format implements the fmt.Formatter interface. 631 // nolint: errcheck 632 func (ca ConsAddress) Format(s fmt.State, verb rune) { 633 switch verb { 634 case 's': 635 s.Write([]byte(ca.String())) 636 case 'p': 637 s.Write([]byte(fmt.Sprintf("%p", ca))) 638 default: 639 s.Write([]byte(fmt.Sprintf("%X", []byte(ca)))) 640 } 641 } 642 643 // ---------------------------------------------------------------------------- 644 // auxiliary 645 // ---------------------------------------------------------------------------- 646 647 // Bech32PubKeyType defines a string type alias for a Bech32 public key type. 648 type Bech32PubKeyType string 649 650 // Bech32 conversion constants 651 const ( 652 Bech32PubKeyTypeAccPub Bech32PubKeyType = "accpub" 653 Bech32PubKeyTypeValPub Bech32PubKeyType = "valpub" 654 Bech32PubKeyTypeConsPub Bech32PubKeyType = "conspub" 655 ) 656 657 // Bech32ifyPubKey returns a Bech32 encoded string containing the appropriate 658 // prefix based on the key type provided for a given PublicKey. 659 func Bech32ifyPubKey(pkt Bech32PubKeyType, pubkey crypto.PubKey) (string, error) { 660 var bech32Prefix string 661 662 switch pkt { 663 case Bech32PubKeyTypeAccPub: 664 bech32Prefix = GetConfig().GetBech32AccountPubPrefix() 665 666 case Bech32PubKeyTypeValPub: 667 bech32Prefix = GetConfig().GetBech32ValidatorPubPrefix() 668 669 case Bech32PubKeyTypeConsPub: 670 bech32Prefix = GetConfig().GetBech32ConsensusPubPrefix() 671 672 } 673 674 return bech32.ConvertAndEncode(bech32Prefix, pubkey.Bytes()) 675 } 676 677 // MustBech32ifyPubKey calls Bech32ifyPubKey except it panics on error. 678 func MustBech32ifyPubKey(pkt Bech32PubKeyType, pubkey crypto.PubKey) string { 679 res, err := Bech32ifyPubKey(pkt, pubkey) 680 if err != nil { 681 panic(err) 682 } 683 684 return res 685 } 686 687 // GetPubKeyFromBech32 returns a PublicKey from a bech32-encoded PublicKey with 688 // a given key type. 689 func GetPubKeyFromBech32(pkt Bech32PubKeyType, pubkeyStr string) (crypto.PubKey, error) { 690 var bech32Prefix string 691 692 switch pkt { 693 case Bech32PubKeyTypeAccPub: 694 bech32Prefix = GetConfig().GetBech32AccountPubPrefix() 695 696 case Bech32PubKeyTypeValPub: 697 bech32Prefix = GetConfig().GetBech32ValidatorPubPrefix() 698 699 case Bech32PubKeyTypeConsPub: 700 bech32Prefix = GetConfig().GetBech32ConsensusPubPrefix() 701 702 } 703 704 bz, err := GetFromBech32(pubkeyStr, bech32Prefix) 705 if err != nil { 706 return nil, err 707 } 708 709 pk, err := tmamino.PubKeyFromBytes(bz) 710 if err != nil { 711 return nil, err 712 } 713 714 return pk, nil 715 } 716 717 // MustGetPubKeyFromBech32 calls GetPubKeyFromBech32 except it panics on error. 718 func MustGetPubKeyFromBech32(pkt Bech32PubKeyType, pubkeyStr string) crypto.PubKey { 719 res, err := GetPubKeyFromBech32(pkt, pubkeyStr) 720 if err != nil { 721 panic(err) 722 } 723 724 return res 725 } 726 727 // GetFromBech32 decodes a bytestring from a Bech32 encoded string. 728 func GetFromBech32(bech32str, prefix string) ([]byte, error) { 729 if len(bech32str) == 0 { 730 return nil, errors.New("decoding Bech32 address failed: must provide an address") 731 } 732 733 hrp, bz, err := bech32.DecodeAndConvert(bech32str) 734 if err != nil { 735 return nil, err 736 } 737 738 if hrp != prefix { 739 return nil, fmt.Errorf("invalid Bech32 prefix; expected %s, got %s", prefix, hrp) 740 } 741 742 return bz, nil 743 }