Files
kisstron/tron/address.go
T
2026-09-19 18:26:07 +03:00

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)
}