gotron/pkg/address/address.go

135 lines
2.5 KiB
Go
Raw Permalink Normal View History

2024-11-13 22:49:54 +00:00
package address
import (
2024-12-28 20:25:50 +00:00
"bytes"
2024-11-13 22:49:54 +00:00
"crypto/ecdsa"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/mr-tron/base58"
"strings"
)
type Address [21]byte
func (a *Address) UnmarshalJSON(bytes []byte) error {
s := ""
if err := json.Unmarshal(bytes, &s); err != nil {
return fmt.Errorf("unmarshal string: %w", err)
}
addr, err := NewFromBase58(s)
if err != nil {
return fmt.Errorf("parse address: %w", err)
}
*a = addr
return nil
}
func (a Address) String() string {
return a.Base58()
}
func (a Address) Bytes() []byte {
return a[:]
}
func (a Address) Hex() string {
return hex.EncodeToString(a[:])
}
func (a Address) Base58() string {
var tmp []byte
tmp = append(tmp, a[:]...)
hash := SHA256(SHA256(tmp))
checksum := hash[:4]
tmp = append(tmp, checksum...)
return base58.Encode(tmp)
}
func (a Address) ETH() common.Address {
return common.BytesToAddress(a[1:])
}
func NewFromETH(eth common.Address) Address {
return Address(append([]byte{65}, eth.Bytes()...))
}
func NewFromBytes(b []byte) (Address, error) {
if len(b) != 21 {
return Address{}, fmt.Errorf("tron address is not 21 bytes but %d", len(b))
}
return *(*[21]byte)(b), nil
}
func NewFromHex(s string) (Address, error) {
addrBytes, err := hex.DecodeString(s)
if err != nil {
return Address{}, err
}
return *(*[21]byte)(addrBytes), nil
}
func NewFromBase58(s string) (Address, error) {
2024-12-28 20:25:50 +00:00
b, err := base58.Decode(s)
2024-11-13 22:49:54 +00:00
if err != nil {
return Address{}, err
}
2024-12-28 20:25:50 +00:00
if len(b) != 25 {
return Address{}, fmt.Errorf("tron address is not 25 bytes but %d", len(b))
2024-11-13 22:49:54 +00:00
}
2024-12-28 20:25:50 +00:00
hash := SHA256(SHA256(b[:21]))
checksum := hash[:4]
if !bytes.Equal(checksum, b[21:]) {
return Address{}, fmt.Errorf("invalid checksum")
}
return *(*[21]byte)(b[:21]), nil
2024-11-13 22:49:54 +00:00
}
func NewFromString(s string) (Address, error) {
if strings.HasPrefix(s, "T") {
return NewFromBase58(s)
}
if strings.HasPrefix(s, "41") {
return NewFromHex(s)
}
return [21]byte{}, fmt.Errorf("%s is not a Tron address", s)
}
func NewFromKey(k *ecdsa.PrivateKey) Address {
return NewFromETH(crypto.PubkeyToAddress(k.PublicKey))
}
func NewFromKeyBytes(k []byte) (Address, error) {
key, err := crypto.ToECDSA(k)
if err != nil {
return Address{}, err
}
return NewFromKey(key), nil
}
func NewFromKeyHex(k string) (Address, error) {
keyBytes, err := hex.DecodeString(k)
if err != nil {
return Address{}, err
}
return NewFromKeyBytes(keyBytes)
}
func SHA256(s []byte) []byte {
h := sha256.New()
h.Write(s)
bs := h.Sum(nil)
return bs
}