mirror of
https://github.com/aljazceru/ark.git
synced 2025-12-17 12:14:21 +01:00
New address encoding (#356)
* [common] rework address encoding * new address encoding * replace offchain address by vtxo output key in DB * merge migrations files into init one * fix txbuilder fixtures * fix transaction events
This commit is contained in:
@@ -3,63 +3,68 @@ package common
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||
"github.com/btcsuite/btcd/btcutil/bech32"
|
||||
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
||||
)
|
||||
|
||||
func EncodeAddress(
|
||||
hrp string, userKey, aspKey *secp256k1.PublicKey,
|
||||
) (addr string, err error) {
|
||||
if userKey == nil {
|
||||
err = fmt.Errorf("missing public key")
|
||||
return
|
||||
// Address represents an Ark address with HRP, ASP public key, and VTXO Taproot public key
|
||||
type Address struct {
|
||||
HRP string
|
||||
Asp *secp256k1.PublicKey
|
||||
VtxoTapKey *secp256k1.PublicKey
|
||||
}
|
||||
|
||||
// Encode converts the address to its bech32m string representation
|
||||
func (a *Address) Encode() (string, error) {
|
||||
if a.Asp == nil {
|
||||
return "", fmt.Errorf("missing asp public key")
|
||||
}
|
||||
if aspKey == nil {
|
||||
err = fmt.Errorf("missing asp public key")
|
||||
return
|
||||
}
|
||||
if hrp != Liquid.Addr && hrp != LiquidTestNet.Addr {
|
||||
err = fmt.Errorf("invalid prefix")
|
||||
return
|
||||
if a.VtxoTapKey == nil {
|
||||
return "", fmt.Errorf("missing vtxo tap public key")
|
||||
}
|
||||
|
||||
combinedKey := append(
|
||||
aspKey.SerializeCompressed(), userKey.SerializeCompressed()...,
|
||||
schnorr.SerializePubKey(a.Asp), schnorr.SerializePubKey(a.VtxoTapKey)...,
|
||||
)
|
||||
grp, err := bech32.ConvertBits(combinedKey, 8, 5, true)
|
||||
if err != nil {
|
||||
return
|
||||
return "", err
|
||||
}
|
||||
addr, err = bech32.EncodeM(hrp, grp)
|
||||
return
|
||||
return bech32.EncodeM(a.HRP, grp)
|
||||
}
|
||||
|
||||
func DecodeAddress(
|
||||
addr string,
|
||||
) (hrp string, userKey, aspKey *secp256k1.PublicKey, err error) {
|
||||
// DecodeAddress parses a bech32m encoded address string and returns an Address object
|
||||
func DecodeAddress(addr string) (*Address, error) {
|
||||
if len(addr) == 0 {
|
||||
return nil, fmt.Errorf("address is empty")
|
||||
}
|
||||
|
||||
prefix, buf, err := bech32.DecodeNoLimit(addr)
|
||||
if err != nil {
|
||||
return
|
||||
return nil, err
|
||||
}
|
||||
if prefix != Liquid.Addr && prefix != LiquidTestNet.Addr && prefix != LiquidRegTest.Addr {
|
||||
err = fmt.Errorf("invalid prefix")
|
||||
return
|
||||
return nil, fmt.Errorf("invalid prefix")
|
||||
}
|
||||
grp, err := bech32.ConvertBits(buf, 5, 8, false)
|
||||
if err != nil {
|
||||
return
|
||||
return nil, err
|
||||
}
|
||||
aKey, err := secp256k1.ParsePubKey(grp[:33])
|
||||
|
||||
aKey, err := schnorr.ParsePubKey(grp[:32])
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to parse public key: %s", err)
|
||||
return
|
||||
return nil, fmt.Errorf("failed to parse public key: %s", err)
|
||||
}
|
||||
uKey, err := secp256k1.ParsePubKey(grp[33:])
|
||||
|
||||
vtxoKey, err := schnorr.ParsePubKey(grp[32:])
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to parse asp public key: %s", err)
|
||||
return
|
||||
return nil, fmt.Errorf("failed to parse asp public key: %s", err)
|
||||
}
|
||||
hrp = prefix
|
||||
userKey = uKey
|
||||
aspKey = aKey
|
||||
return
|
||||
|
||||
return &Address{
|
||||
HRP: prefix,
|
||||
Asp: aKey,
|
||||
VtxoTapKey: vtxoKey,
|
||||
}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user