address: refactor common code into AddressSegWit

To avoid a lot of code duplication, we extract the common parts of the
AddressWitnessPubKeyHash and AddressWitnessScriptHash types into a
common base type called AddressSegWit.
This commit is contained in:
Oliver Gugger 2021-09-27 13:40:05 +02:00
parent 43b172ec93
commit 4a0c04f989
No known key found for this signature in database
GPG key ID: 8E4256593F177720
2 changed files with 98 additions and 123 deletions

View file

@ -506,25 +506,88 @@ func (a *AddressPubKey) PubKey() *btcec.PublicKey {
return a.pubKey
}
// AddressSegWit is the base address type for all SegWit addresses.
type AddressSegWit struct {
hrp string
witnessVersion byte
witnessProgram []byte
}
// EncodeAddress returns the bech32 (or bech32m for SegWit v1) string encoding
// of an AddressSegWit.
//
// NOTE: This method is part of the Address interface.
func (a *AddressSegWit) EncodeAddress() string {
str, err := encodeSegWitAddress(
a.hrp, a.witnessVersion, a.witnessProgram[:],
)
if err != nil {
return ""
}
return str
}
// ScriptAddress returns the witness program for this address.
//
// NOTE: This method is part of the Address interface.
func (a *AddressSegWit) ScriptAddress() []byte {
return a.witnessProgram[:]
}
// IsForNet returns whether the AddressSegWit is associated with the passed
// bitcoin network.
//
// NOTE: This method is part of the Address interface.
func (a *AddressSegWit) IsForNet(net *chaincfg.Params) bool {
return a.hrp == net.Bech32HRPSegwit
}
// String returns a human-readable string for the AddressWitnessPubKeyHash.
// This is equivalent to calling EncodeAddress, but is provided so the type
// can be used as a fmt.Stringer.
//
// NOTE: This method is part of the Address interface.
func (a *AddressSegWit) String() string {
return a.EncodeAddress()
}
// Hrp returns the human-readable part of the bech32 (or bech32m for SegWit v1)
// encoded AddressSegWit.
func (a *AddressSegWit) Hrp() string {
return a.hrp
}
// WitnessVersion returns the witness version of the AddressSegWit.
func (a *AddressSegWit) WitnessVersion() byte {
return a.witnessVersion
}
// WitnessProgram returns the witness program of the AddressSegWit.
func (a *AddressSegWit) WitnessProgram() []byte {
return a.witnessProgram[:]
}
// AddressWitnessPubKeyHash is an Address for a pay-to-witness-pubkey-hash
// (P2WPKH) output. See BIP 173 for further details regarding native segregated
// witness address encoding:
// https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
type AddressWitnessPubKeyHash struct {
hrp string
witnessVersion byte
witnessProgram [20]byte
AddressSegWit
}
// NewAddressWitnessPubKeyHash returns a new AddressWitnessPubKeyHash.
func NewAddressWitnessPubKeyHash(witnessProg []byte, net *chaincfg.Params) (*AddressWitnessPubKeyHash, error) {
func NewAddressWitnessPubKeyHash(witnessProg []byte,
net *chaincfg.Params) (*AddressWitnessPubKeyHash, error) {
return newAddressWitnessPubKeyHash(net.Bech32HRPSegwit, witnessProg)
}
// newAddressWitnessPubKeyHash is an internal helper function to create an
// AddressWitnessPubKeyHash with a known human-readable part, rather than
// looking it up through its parameters.
func newAddressWitnessPubKeyHash(hrp string, witnessProg []byte) (*AddressWitnessPubKeyHash, error) {
func newAddressWitnessPubKeyHash(hrp string,
witnessProg []byte) (*AddressWitnessPubKeyHash, error) {
// Check for valid program length for witness version 0, which is 20
// for P2WPKH.
if len(witnessProg) != 20 {
@ -533,68 +596,22 @@ func newAddressWitnessPubKeyHash(hrp string, witnessProg []byte) (*AddressWitnes
}
addr := &AddressWitnessPubKeyHash{
hrp: strings.ToLower(hrp),
witnessVersion: 0x00,
AddressSegWit{
hrp: strings.ToLower(hrp),
witnessVersion: 0x00,
witnessProgram: witnessProg,
},
}
copy(addr.witnessProgram[:], witnessProg)
return addr, nil
}
// EncodeAddress returns the bech32 string encoding of an
// AddressWitnessPubKeyHash.
// Part of the Address interface.
func (a *AddressWitnessPubKeyHash) EncodeAddress() string {
str, err := encodeSegWitAddress(a.hrp, a.witnessVersion,
a.witnessProgram[:])
if err != nil {
return ""
}
return str
}
// ScriptAddress returns the witness program for this address.
// Part of the Address interface.
func (a *AddressWitnessPubKeyHash) ScriptAddress() []byte {
return a.witnessProgram[:]
}
// IsForNet returns whether or not the AddressWitnessPubKeyHash is associated
// with the passed bitcoin network.
// Part of the Address interface.
func (a *AddressWitnessPubKeyHash) IsForNet(net *chaincfg.Params) bool {
return a.hrp == net.Bech32HRPSegwit
}
// String returns a human-readable string for the AddressWitnessPubKeyHash.
// This is equivalent to calling EncodeAddress, but is provided so the type
// can be used as a fmt.Stringer.
// Part of the Address interface.
func (a *AddressWitnessPubKeyHash) String() string {
return a.EncodeAddress()
}
// Hrp returns the human-readable part of the bech32 encoded
// AddressWitnessPubKeyHash.
func (a *AddressWitnessPubKeyHash) Hrp() string {
return a.hrp
}
// WitnessVersion returns the witness version of the AddressWitnessPubKeyHash.
func (a *AddressWitnessPubKeyHash) WitnessVersion() byte {
return a.witnessVersion
}
// WitnessProgram returns the witness program of the AddressWitnessPubKeyHash.
func (a *AddressWitnessPubKeyHash) WitnessProgram() []byte {
return a.witnessProgram[:]
}
// Hash160 returns the witness program of the AddressWitnessPubKeyHash as a
// byte array.
func (a *AddressWitnessPubKeyHash) Hash160() *[20]byte {
return &a.witnessProgram
var pubKeyHashWitnessProgram [20]byte
copy(pubKeyHashWitnessProgram[:], a.witnessProgram)
return &pubKeyHashWitnessProgram
}
// AddressWitnessScriptHash is an Address for a pay-to-witness-script-hash
@ -602,20 +619,22 @@ func (a *AddressWitnessPubKeyHash) Hash160() *[20]byte {
// witness address encoding:
// https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
type AddressWitnessScriptHash struct {
hrp string
witnessVersion byte
witnessProgram [32]byte
AddressSegWit
}
// NewAddressWitnessScriptHash returns a new AddressWitnessPubKeyHash.
func NewAddressWitnessScriptHash(witnessProg []byte, net *chaincfg.Params) (*AddressWitnessScriptHash, error) {
func NewAddressWitnessScriptHash(witnessProg []byte,
net *chaincfg.Params) (*AddressWitnessScriptHash, error) {
return newAddressWitnessScriptHash(net.Bech32HRPSegwit, witnessProg)
}
// newAddressWitnessScriptHash is an internal helper function to create an
// AddressWitnessScriptHash with a known human-readable part, rather than
// looking it up through its parameters.
func newAddressWitnessScriptHash(hrp string, witnessProg []byte) (*AddressWitnessScriptHash, error) {
func newAddressWitnessScriptHash(hrp string,
witnessProg []byte) (*AddressWitnessScriptHash, error) {
// Check for valid program length for witness version 0, which is 32
// for P2WSH.
if len(witnessProg) != 32 {
@ -624,60 +643,12 @@ func newAddressWitnessScriptHash(hrp string, witnessProg []byte) (*AddressWitnes
}
addr := &AddressWitnessScriptHash{
hrp: strings.ToLower(hrp),
witnessVersion: 0x00,
AddressSegWit{
hrp: strings.ToLower(hrp),
witnessVersion: 0x00,
witnessProgram: witnessProg,
},
}
copy(addr.witnessProgram[:], witnessProg)
return addr, nil
}
// EncodeAddress returns the bech32 string encoding of an
// AddressWitnessScriptHash.
// Part of the Address interface.
func (a *AddressWitnessScriptHash) EncodeAddress() string {
str, err := encodeSegWitAddress(a.hrp, a.witnessVersion,
a.witnessProgram[:])
if err != nil {
return ""
}
return str
}
// ScriptAddress returns the witness program for this address.
// Part of the Address interface.
func (a *AddressWitnessScriptHash) ScriptAddress() []byte {
return a.witnessProgram[:]
}
// IsForNet returns whether or not the AddressWitnessScriptHash is associated
// with the passed bitcoin network.
// Part of the Address interface.
func (a *AddressWitnessScriptHash) IsForNet(net *chaincfg.Params) bool {
return a.hrp == net.Bech32HRPSegwit
}
// String returns a human-readable string for the AddressWitnessScriptHash.
// This is equivalent to calling EncodeAddress, but is provided so the type
// can be used as a fmt.Stringer.
// Part of the Address interface.
func (a *AddressWitnessScriptHash) String() string {
return a.EncodeAddress()
}
// Hrp returns the human-readable part of the bech32 encoded
// AddressWitnessScriptHash.
func (a *AddressWitnessScriptHash) Hrp() string {
return a.hrp
}
// WitnessVersion returns the witness version of the AddressWitnessScriptHash.
func (a *AddressWitnessScriptHash) WitnessVersion() byte {
return a.witnessVersion
}
// WitnessProgram returns the witness program of the AddressWitnessScriptHash.
func (a *AddressWitnessScriptHash) WitnessProgram() []byte {
return a.witnessProgram[:]
}

View file

@ -59,9 +59,11 @@ func TstAddressWitnessPubKeyHash(version byte, program [20]byte,
hrp string) *AddressWitnessPubKeyHash {
return &AddressWitnessPubKeyHash{
hrp: hrp,
witnessVersion: version,
witnessProgram: program,
AddressSegWit{
hrp: hrp,
witnessVersion: version,
witnessProgram: program[:],
},
}
}
@ -71,9 +73,11 @@ func TstAddressWitnessScriptHash(version byte, program [32]byte,
hrp string) *AddressWitnessScriptHash {
return &AddressWitnessScriptHash{
hrp: hrp,
witnessVersion: version,
witnessProgram: program,
AddressSegWit{
hrp: hrp,
witnessVersion: version,
witnessProgram: program[:],
},
}
}