github.com/Finschia/finschia-sdk@v0.48.1/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 "sync" 11 12 "github.com/hashicorp/golang-lru/simplelru" 13 yaml "gopkg.in/yaml.v2" 14 15 cryptotypes "github.com/Finschia/finschia-sdk/crypto/types" 16 "github.com/Finschia/finschia-sdk/internal/conv" 17 "github.com/Finschia/finschia-sdk/types/address" 18 "github.com/Finschia/finschia-sdk/types/bech32" 19 sdkerrors "github.com/Finschia/finschia-sdk/types/errors" 20 ) 21 22 const ( 23 // Constants defined here are the defaults value for address. 24 // You can use the specific values for your project. 25 // Add the follow lines to the `main()` of your server. 26 // 27 // config := sdk.GetConfig() 28 // config.SetBech32PrefixForAccount(yourBech32PrefixAccAddr, yourBech32PrefixAccPub) 29 // config.SetBech32PrefixForValidator(yourBech32PrefixValAddr, yourBech32PrefixValPub) 30 // config.SetBech32PrefixForConsensusNode(yourBech32PrefixConsAddr, yourBech32PrefixConsPub) 31 // config.SetPurpose(yourPurpose) 32 // config.SetCoinType(yourCoinType) 33 // config.Seal() 34 35 // Bech32MainPrefix defines the main SDK Bech32 prefix of an account's address 36 Bech32MainPrefix = "link" 37 38 // Purpose is the LINK purpose as defined in SLIP44 (https://github.com/satoshilabs/slips/blob/master/slip-0044.md) 39 Purpose = 44 40 41 // CoinType is the LINK coin type as defined in SLIP44 (https://github.com/satoshilabs/slips/blob/master/slip-0044.md) 42 CoinType = 438 43 44 // FullFundraiserPath is the parts of the BIP44 HD path that are fixed by 45 // what we used during the LINK fundraiser. 46 FullFundraiserPath = "m/44'/438'/0'/0/0" 47 48 // PrefixAccount is the prefix for account keys 49 PrefixAccount = "acc" 50 // PrefixValidator is the prefix for validator keys 51 PrefixValidator = "val" 52 // PrefixConsensus is the prefix for consensus keys 53 PrefixConsensus = "cons" 54 // PrefixPublic is the prefix for public keys 55 PrefixPublic = "pub" 56 // PrefixOperator is the prefix for operator keys 57 PrefixOperator = "oper" 58 59 // PrefixAddress is the prefix for addresses 60 PrefixAddress = "addr" 61 62 // Bech32PrefixAccAddr defines the Bech32 prefix of an account's address 63 Bech32PrefixAccAddr = Bech32MainPrefix 64 // Bech32PrefixAccPub defines the Bech32 prefix of an account's public key 65 Bech32PrefixAccPub = Bech32MainPrefix + PrefixPublic 66 // Bech32PrefixValAddr defines the Bech32 prefix of a validator's operator address 67 Bech32PrefixValAddr = Bech32MainPrefix + PrefixValidator + PrefixOperator 68 // Bech32PrefixValPub defines the Bech32 prefix of a validator's operator public key 69 Bech32PrefixValPub = Bech32MainPrefix + PrefixValidator + PrefixOperator + PrefixPublic 70 // Bech32PrefixConsAddr defines the Bech32 prefix of a consensus node address 71 Bech32PrefixConsAddr = Bech32MainPrefix + PrefixValidator + PrefixConsensus 72 // Bech32PrefixConsPub defines the Bech32 prefix of a consensus node public key 73 Bech32PrefixConsPub = Bech32MainPrefix + PrefixValidator + PrefixConsensus + PrefixPublic 74 ) 75 76 // cache variables 77 var ( 78 // AccAddress.String() is expensive and if unoptimized dominantly showed up in profiles, 79 // yet has no mechanisms to trivially cache the result given that AccAddress is a []byte type. 80 accAddrMu sync.Mutex 81 accAddrCache *simplelru.LRU 82 consAddrMu sync.Mutex 83 consAddrCache *simplelru.LRU 84 valAddrMu sync.Mutex 85 valAddrCache *simplelru.LRU 86 ) 87 88 func init() { 89 var err error 90 // in total the cache size is 61k entries. Key is 32 bytes and value is around 50-70 bytes. 91 // That will make around 92 * 61k * 2 (LRU) bytes ~ 11 MB 92 if accAddrCache, err = simplelru.NewLRU(60000, nil); err != nil { 93 panic(err) 94 } 95 if consAddrCache, err = simplelru.NewLRU(500, nil); err != nil { 96 panic(err) 97 } 98 if valAddrCache, err = simplelru.NewLRU(500, nil); err != nil { 99 panic(err) 100 } 101 } 102 103 // Address is a common interface for different types of addresses used by the SDK 104 type Address interface { 105 Equals(Address) bool 106 Empty() bool 107 Marshal() ([]byte, error) 108 MarshalJSON() ([]byte, error) 109 Bytes() []byte 110 String() string 111 Format(s fmt.State, verb rune) 112 } 113 114 // Ensure that different address types implement the interface 115 var _ Address = AccAddress{} 116 117 var ( 118 _ Address = ValAddress{} 119 _ Address = ConsAddress{} 120 ) 121 122 var ( 123 _ yaml.Marshaler = AccAddress{} 124 _ yaml.Marshaler = ValAddress{} 125 _ yaml.Marshaler = ConsAddress{} 126 ) 127 128 // ---------------------------------------------------------------------------- 129 // account 130 // ---------------------------------------------------------------------------- 131 132 // AccAddress a wrapper around bytes meant to represent an account address. 133 // When marshaled to a string or JSON, it uses Bech32. 134 type AccAddress []byte 135 136 // AccAddressFromHex creates an AccAddress from a hex string. 137 func AccAddressFromHex(address string) (addr AccAddress, err error) { 138 bz, err := addressBytesFromHexString(address) 139 return AccAddress(bz), err 140 } 141 142 // VerifyAddressFormat verifies that the provided bytes form a valid address 143 // according to the default address rules or a custom address verifier set by 144 // GetConfig().SetAddressVerifier() 145 func VerifyAddressFormat(bz []byte) error { 146 verifier := GetConfig().GetAddressVerifier() 147 if verifier != nil { 148 return verifier(bz) 149 } 150 151 if len(bz) == 0 { 152 return sdkerrors.Wrap(sdkerrors.ErrUnknownAddress, "addresses cannot be empty") 153 } 154 155 if len(bz) > address.MaxAddrLen { 156 return sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "address max length is %d, got %d", address.MaxAddrLen, len(bz)) 157 } 158 159 return nil 160 } 161 162 // MustAccAddressFromBech32 calls AccAddressFromBech32 and panics on error. 163 func MustAccAddressFromBech32(address string) AccAddress { 164 addr, err := AccAddressFromBech32(address) 165 if err != nil { 166 panic(err) 167 } 168 169 return addr 170 } 171 172 // AccAddressFromBech32 creates an AccAddress from a Bech32 string. 173 func AccAddressFromBech32(address string) (addr AccAddress, err error) { 174 if len(strings.TrimSpace(address)) == 0 { 175 return AccAddress{}, errors.New("empty address string is not allowed") 176 } 177 178 bech32PrefixAccAddr := GetConfig().GetBech32AccountAddrPrefix() 179 180 bz, err := GetFromBech32(address, bech32PrefixAccAddr) 181 if err != nil { 182 return nil, err 183 } 184 185 err = VerifyAddressFormat(bz) 186 if err != nil { 187 return nil, err 188 } 189 190 return AccAddress(bz), nil 191 } 192 193 // Returns boolean for whether two AccAddresses are Equal 194 func (aa AccAddress) Equals(aa2 Address) bool { 195 if aa.Empty() && aa2.Empty() { 196 return true 197 } 198 199 return bytes.Equal(aa.Bytes(), aa2.Bytes()) 200 } 201 202 // Returns boolean for whether an AccAddress is empty 203 func (aa AccAddress) Empty() bool { 204 return len(aa) == 0 205 } 206 207 // Marshal returns the raw address bytes. It is needed for protobuf 208 // compatibility. 209 func (aa AccAddress) Marshal() ([]byte, error) { 210 return aa, nil 211 } 212 213 // Unmarshal sets the address to the given data. It is needed for protobuf 214 // compatibility. 215 func (aa *AccAddress) Unmarshal(data []byte) error { 216 *aa = data 217 return nil 218 } 219 220 // MarshalJSON marshals to JSON using Bech32. 221 func (aa AccAddress) MarshalJSON() ([]byte, error) { 222 return json.Marshal(aa.String()) 223 } 224 225 // MarshalYAML marshals to YAML using Bech32. 226 func (aa AccAddress) MarshalYAML() (interface{}, error) { 227 return aa.String(), nil 228 } 229 230 // UnmarshalJSON unmarshals from JSON assuming Bech32 encoding. 231 func (aa *AccAddress) UnmarshalJSON(data []byte) error { 232 var s string 233 err := json.Unmarshal(data, &s) 234 if err != nil { 235 return err 236 } 237 if s == "" { 238 *aa = AccAddress{} 239 return nil 240 } 241 242 aa2, err := AccAddressFromBech32(s) 243 if err != nil { 244 return err 245 } 246 247 *aa = aa2 248 return nil 249 } 250 251 // UnmarshalYAML unmarshals from JSON assuming Bech32 encoding. 252 func (aa *AccAddress) UnmarshalYAML(data []byte) error { 253 var s string 254 err := yaml.Unmarshal(data, &s) 255 if err != nil { 256 return err 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 key := conv.UnsafeBytesToStr(aa) 284 accAddrMu.Lock() 285 defer accAddrMu.Unlock() 286 addr, ok := accAddrCache.Get(key) 287 if ok { 288 return addr.(string) 289 } 290 return cacheBech32Addr(GetConfig().GetBech32AccountAddrPrefix(), aa, accAddrCache, key) 291 } 292 293 // Format implements the fmt.Formatter interface. 294 // nolint: errcheck 295 func (aa AccAddress) Format(s fmt.State, verb rune) { 296 switch verb { 297 case 's': 298 s.Write([]byte(aa.String())) 299 case 'p': 300 s.Write([]byte(fmt.Sprintf("%p", aa))) 301 default: 302 s.Write([]byte(fmt.Sprintf("%X", []byte(aa)))) 303 } 304 } 305 306 // ---------------------------------------------------------------------------- 307 // validator operator 308 // ---------------------------------------------------------------------------- 309 310 // ValAddress defines a wrapper around bytes meant to present a validator's 311 // operator. When marshaled to a string or JSON, it uses Bech32. 312 type ValAddress []byte 313 314 // ValAddressFromHex creates a ValAddress from a hex string. 315 func ValAddressFromHex(address string) (addr ValAddress, err error) { 316 bz, err := addressBytesFromHexString(address) 317 return ValAddress(bz), err 318 } 319 320 // ValAddressFromBech32 creates a ValAddress from a Bech32 string. 321 func ValAddressFromBech32(address string) (addr ValAddress, err error) { 322 if len(strings.TrimSpace(address)) == 0 { 323 return ValAddress{}, errors.New("empty address string is not allowed") 324 } 325 326 bech32PrefixValAddr := GetConfig().GetBech32ValidatorAddrPrefix() 327 328 bz, err := GetFromBech32(address, bech32PrefixValAddr) 329 if err != nil { 330 return nil, err 331 } 332 333 err = VerifyAddressFormat(bz) 334 if err != nil { 335 return nil, err 336 } 337 338 return ValAddress(bz), nil 339 } 340 341 // Returns boolean for whether two ValAddresses are Equal 342 func (va ValAddress) Equals(va2 Address) bool { 343 if va.Empty() && va2.Empty() { 344 return true 345 } 346 347 return bytes.Equal(va.Bytes(), va2.Bytes()) 348 } 349 350 // Returns boolean for whether an AccAddress is empty 351 func (va ValAddress) Empty() bool { 352 return len(va) == 0 353 } 354 355 // Marshal returns the raw address bytes. It is needed for protobuf 356 // compatibility. 357 func (va ValAddress) Marshal() ([]byte, error) { 358 return va, nil 359 } 360 361 // Unmarshal sets the address to the given data. It is needed for protobuf 362 // compatibility. 363 func (va *ValAddress) Unmarshal(data []byte) error { 364 *va = data 365 return nil 366 } 367 368 // MarshalJSON marshals to JSON using Bech32. 369 func (va ValAddress) MarshalJSON() ([]byte, error) { 370 return json.Marshal(va.String()) 371 } 372 373 // MarshalYAML marshals to YAML using Bech32. 374 func (va ValAddress) MarshalYAML() (interface{}, error) { 375 return va.String(), nil 376 } 377 378 // UnmarshalJSON unmarshals from JSON assuming Bech32 encoding. 379 func (va *ValAddress) UnmarshalJSON(data []byte) error { 380 var s string 381 382 err := json.Unmarshal(data, &s) 383 if err != nil { 384 return err 385 } 386 if s == "" { 387 *va = ValAddress{} 388 return nil 389 } 390 391 va2, err := ValAddressFromBech32(s) 392 if err != nil { 393 return err 394 } 395 396 *va = va2 397 return nil 398 } 399 400 // UnmarshalYAML unmarshals from YAML assuming Bech32 encoding. 401 func (va *ValAddress) UnmarshalYAML(data []byte) error { 402 var s string 403 404 err := yaml.Unmarshal(data, &s) 405 if err != nil { 406 return err 407 } 408 if s == "" { 409 *va = ValAddress{} 410 return nil 411 } 412 413 va2, err := ValAddressFromBech32(s) 414 if err != nil { 415 return err 416 } 417 418 *va = va2 419 return nil 420 } 421 422 // Bytes returns the raw address bytes. 423 func (va ValAddress) Bytes() []byte { 424 return va 425 } 426 427 // String implements the Stringer interface. 428 func (va ValAddress) String() string { 429 if va.Empty() { 430 return "" 431 } 432 433 key := conv.UnsafeBytesToStr(va) 434 valAddrMu.Lock() 435 defer valAddrMu.Unlock() 436 addr, ok := valAddrCache.Get(key) 437 if ok { 438 return addr.(string) 439 } 440 return cacheBech32Addr(GetConfig().GetBech32ValidatorAddrPrefix(), va, valAddrCache, key) 441 } 442 443 // Format implements the fmt.Formatter interface. 444 // nolint: errcheck 445 func (va ValAddress) Format(s fmt.State, verb rune) { 446 switch verb { 447 case 's': 448 s.Write([]byte(va.String())) 449 case 'p': 450 s.Write([]byte(fmt.Sprintf("%p", va))) 451 default: 452 s.Write([]byte(fmt.Sprintf("%X", []byte(va)))) 453 } 454 } 455 456 // ---------------------------------------------------------------------------- 457 // consensus node 458 // ---------------------------------------------------------------------------- 459 460 // ConsAddress defines a wrapper around bytes meant to present a consensus node. 461 // When marshaled to a string or JSON, it uses Bech32. 462 type ConsAddress []byte 463 464 // ConsAddressFromHex creates a ConsAddress from a hex string. 465 func ConsAddressFromHex(address string) (addr ConsAddress, err error) { 466 bz, err := addressBytesFromHexString(address) 467 return ConsAddress(bz), err 468 } 469 470 // ConsAddressFromBech32 creates a ConsAddress from a Bech32 string. 471 func ConsAddressFromBech32(address string) (addr ConsAddress, err error) { 472 if len(strings.TrimSpace(address)) == 0 { 473 return ConsAddress{}, errors.New("empty address string is not allowed") 474 } 475 476 bech32PrefixConsAddr := GetConfig().GetBech32ConsensusAddrPrefix() 477 478 bz, err := GetFromBech32(address, bech32PrefixConsAddr) 479 if err != nil { 480 return nil, err 481 } 482 483 err = VerifyAddressFormat(bz) 484 if err != nil { 485 return nil, err 486 } 487 488 return ConsAddress(bz), nil 489 } 490 491 // get ConsAddress from pubkey 492 func GetConsAddress(pubkey cryptotypes.PubKey) ConsAddress { 493 return ConsAddress(pubkey.Address()) 494 } 495 496 // Returns boolean for whether two ConsAddress are Equal 497 func (ca ConsAddress) Equals(ca2 Address) bool { 498 if ca.Empty() && ca2.Empty() { 499 return true 500 } 501 502 return bytes.Equal(ca.Bytes(), ca2.Bytes()) 503 } 504 505 // Returns boolean for whether an ConsAddress is empty 506 func (ca ConsAddress) Empty() bool { 507 return len(ca) == 0 508 } 509 510 // Marshal returns the raw address bytes. It is needed for protobuf 511 // compatibility. 512 func (ca ConsAddress) Marshal() ([]byte, error) { 513 return ca, nil 514 } 515 516 // Unmarshal sets the address to the given data. It is needed for protobuf 517 // compatibility. 518 func (ca *ConsAddress) Unmarshal(data []byte) error { 519 *ca = data 520 return nil 521 } 522 523 // MarshalJSON marshals to JSON using Bech32. 524 func (ca ConsAddress) MarshalJSON() ([]byte, error) { 525 return json.Marshal(ca.String()) 526 } 527 528 // MarshalYAML marshals to YAML using Bech32. 529 func (ca ConsAddress) MarshalYAML() (interface{}, error) { 530 return ca.String(), nil 531 } 532 533 // UnmarshalJSON unmarshals from JSON assuming Bech32 encoding. 534 func (ca *ConsAddress) UnmarshalJSON(data []byte) error { 535 var s string 536 537 err := json.Unmarshal(data, &s) 538 if err != nil { 539 return err 540 } 541 if s == "" { 542 *ca = ConsAddress{} 543 return nil 544 } 545 546 ca2, err := ConsAddressFromBech32(s) 547 if err != nil { 548 return err 549 } 550 551 *ca = ca2 552 return nil 553 } 554 555 // UnmarshalYAML unmarshals from YAML assuming Bech32 encoding. 556 func (ca *ConsAddress) UnmarshalYAML(data []byte) error { 557 var s string 558 559 err := yaml.Unmarshal(data, &s) 560 if err != nil { 561 return err 562 } 563 if s == "" { 564 *ca = ConsAddress{} 565 return nil 566 } 567 568 ca2, err := ConsAddressFromBech32(s) 569 if err != nil { 570 return err 571 } 572 573 *ca = ca2 574 return nil 575 } 576 577 // Bytes returns the raw address bytes. 578 func (ca ConsAddress) Bytes() []byte { 579 return ca 580 } 581 582 // String implements the Stringer interface. 583 func (ca ConsAddress) String() string { 584 if ca.Empty() { 585 return "" 586 } 587 588 key := conv.UnsafeBytesToStr(ca) 589 consAddrMu.Lock() 590 defer consAddrMu.Unlock() 591 addr, ok := consAddrCache.Get(key) 592 if ok { 593 return addr.(string) 594 } 595 return cacheBech32Addr(GetConfig().GetBech32ConsensusAddrPrefix(), ca, consAddrCache, key) 596 } 597 598 // Bech32ifyAddressBytes returns a bech32 representation of address bytes. 599 // Returns an empty sting if the byte slice is 0-length. Returns an error if the bech32 conversion 600 // fails or the prefix is empty. 601 func Bech32ifyAddressBytes(prefix string, bs []byte) (string, error) { 602 if len(bs) == 0 { 603 return "", nil 604 } 605 if len(prefix) == 0 { 606 return "", errors.New("prefix cannot be empty") 607 } 608 return bech32.ConvertAndEncode(prefix, bs) 609 } 610 611 // MustBech32ifyAddressBytes returns a bech32 representation of address bytes. 612 // Returns an empty sting if the byte slice is 0-length. It panics if the bech32 conversion 613 // fails or the prefix is empty. 614 func MustBech32ifyAddressBytes(prefix string, bs []byte) string { 615 s, err := Bech32ifyAddressBytes(prefix, bs) 616 if err != nil { 617 panic(err) 618 } 619 return s 620 } 621 622 // Format implements the fmt.Formatter interface. 623 // nolint: errcheck 624 func (ca ConsAddress) Format(s fmt.State, verb rune) { 625 switch verb { 626 case 's': 627 s.Write([]byte(ca.String())) 628 case 'p': 629 s.Write([]byte(fmt.Sprintf("%p", ca))) 630 default: 631 s.Write([]byte(fmt.Sprintf("%X", []byte(ca)))) 632 } 633 } 634 635 // ---------------------------------------------------------------------------- 636 // auxiliary 637 // ---------------------------------------------------------------------------- 638 639 var errBech32EmptyAddress = errors.New("decoding Bech32 address failed: must provide a non empty address") 640 641 // GetFromBech32 decodes a bytestring from a Bech32 encoded string. 642 func GetFromBech32(bech32str, prefix string) ([]byte, error) { 643 if len(bech32str) == 0 { 644 return nil, errBech32EmptyAddress 645 } 646 647 hrp, bz, err := bech32.DecodeAndConvert(bech32str) 648 if err != nil { 649 return nil, err 650 } 651 652 if hrp != prefix { 653 return nil, fmt.Errorf("invalid Bech32 prefix; expected %s, got %s", prefix, hrp) 654 } 655 656 return bz, nil 657 } 658 659 func addressBytesFromHexString(address string) ([]byte, error) { 660 if len(address) == 0 { 661 return nil, errors.New("decoding Bech32 address failed: must provide an address") 662 } 663 664 return hex.DecodeString(address) 665 } 666 667 // cacheBech32Addr is not concurrency safe. Concurrent access to cache causes race condition. 668 func cacheBech32Addr(prefix string, addr []byte, cache *simplelru.LRU, cacheKey string) string { 669 bech32Addr, err := bech32.ConvertAndEncode(prefix, addr) 670 if err != nil { 671 panic(err) 672 } 673 cache.Add(cacheKey, bech32Addr) 674 return bech32Addr 675 }