diff --git a/address.go b/address.go index 8672497..96c6050 100644 --- a/address.go +++ b/address.go @@ -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[:] -} diff --git a/internal_test.go b/internal_test.go index 7462da6..d471c30 100644 --- a/internal_test.go +++ b/internal_test.go @@ -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[:], + }, } }