122 lines
3.1 KiB
Go
122 lines
3.1 KiB
Go
package tron
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/hex"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
"code.luxferre.top/luxferre/kisstron/base58"
|
||
|
|
)
|
||
|
|
|
||
|
|
// ToBase58CheckAddress converts an address given in any accepted format
|
||
|
|
// (base58check, 41-prefixed hex, or 0x-prefixed hex) to its base58check
|
||
|
|
// representation, verifying the checksum. The argument may be a string or a
|
||
|
|
// byte slice.
|
||
|
|
func ToBase58CheckAddress(raw any) (string, error) {
|
||
|
|
switch v := raw.(type) {
|
||
|
|
case string:
|
||
|
|
return strToBase58Check(v)
|
||
|
|
case []byte:
|
||
|
|
return bytesToBase58Check(v)
|
||
|
|
}
|
||
|
|
return "", ErrBadAddress
|
||
|
|
}
|
||
|
|
|
||
|
|
func strToBase58Check(s string) (string, error) {
|
||
|
|
if len(s) == 0 {
|
||
|
|
return "", ErrBadAddress
|
||
|
|
}
|
||
|
|
if s[0] == 'T' && len(s) == 34 {
|
||
|
|
if !base58.IsValid(s) {
|
||
|
|
return "", ErrBadAddress
|
||
|
|
}
|
||
|
|
return s, nil
|
||
|
|
}
|
||
|
|
if len(s) == 42 {
|
||
|
|
if strings.HasPrefix(s, "0x") {
|
||
|
|
b, err := hex.DecodeString(s[2:])
|
||
|
|
if err != nil || len(b) != 20 {
|
||
|
|
return "", ErrBadAddress
|
||
|
|
}
|
||
|
|
return base58.CheckEncode(append([]byte{0x41}, b...)), nil
|
||
|
|
}
|
||
|
|
b, err := hex.DecodeString(s)
|
||
|
|
if err != nil || len(b) != 21 {
|
||
|
|
return "", ErrBadAddress
|
||
|
|
}
|
||
|
|
return base58.CheckEncode(b), nil
|
||
|
|
}
|
||
|
|
if strings.HasPrefix(s, "0x") && len(s) == 44 {
|
||
|
|
b, err := hex.DecodeString(s[2:])
|
||
|
|
if err != nil || len(b) != 21 {
|
||
|
|
return "", ErrBadAddress
|
||
|
|
}
|
||
|
|
return base58.CheckEncode(b), nil
|
||
|
|
}
|
||
|
|
return "", ErrBadAddress
|
||
|
|
}
|
||
|
|
|
||
|
|
func bytesToBase58Check(b []byte) (string, error) {
|
||
|
|
switch {
|
||
|
|
case len(b) == 21 && b[0] == 0x41:
|
||
|
|
return base58.CheckEncode(b), nil
|
||
|
|
case len(b) == 20:
|
||
|
|
return base58.CheckEncode(append([]byte{0x41}, b...)), nil
|
||
|
|
default:
|
||
|
|
return strToBase58Check(string(b))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ToHexAddress converts an address to its 41-prefixed hex representation.
|
||
|
|
func ToHexAddress(raw any) (string, error) {
|
||
|
|
addr, err := ToBase58CheckAddress(raw)
|
||
|
|
if err != nil {
|
||
|
|
return "", err
|
||
|
|
}
|
||
|
|
b, err := base58.CheckDecode(addr)
|
||
|
|
if err != nil {
|
||
|
|
return "", ErrBadAddress
|
||
|
|
}
|
||
|
|
return hex.EncodeToString(b), nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// ToRawAddress returns the 21-byte raw form of an address.
|
||
|
|
func ToRawAddress(raw any) ([]byte, error) {
|
||
|
|
addr, err := ToBase58CheckAddress(raw)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
return base58.CheckDecode(addr)
|
||
|
|
}
|
||
|
|
|
||
|
|
// ToTvmAddress returns the 20-byte TVM (Ethereum-style) form of an address.
|
||
|
|
func ToTvmAddress(raw any) ([]byte, error) {
|
||
|
|
b, err := ToRawAddress(raw)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
return b[1:], nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// IsBase58CheckAddress reports whether value is a valid base58check address.
|
||
|
|
func IsBase58CheckAddress(value string) bool {
|
||
|
|
if len(value) == 0 || value[0] != 'T' {
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
b, err := base58.CheckDecode(value)
|
||
|
|
return err == nil && len(b) == 21
|
||
|
|
}
|
||
|
|
|
||
|
|
// IsHexAddress reports whether value is a valid 41-prefixed hex address.
|
||
|
|
func IsHexAddress(value string) bool {
|
||
|
|
if !strings.HasPrefix(value, "41") {
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
b, err := hex.DecodeString(value)
|
||
|
|
return err == nil && len(b) == 21
|
||
|
|
}
|
||
|
|
|
||
|
|
// IsAddress reports whether value is any accepted TRON address format.
|
||
|
|
func IsAddress(value string) bool {
|
||
|
|
return IsBase58CheckAddress(value) || IsHexAddress(value)
|
||
|
|
}
|