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:
parent
43b172ec93
commit
4a0c04f989
2 changed files with 98 additions and 123 deletions
197
address.go
197
address.go
|
@ -506,25 +506,88 @@ func (a *AddressPubKey) PubKey() *btcec.PublicKey {
|
||||||
return a.pubKey
|
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
|
// AddressWitnessPubKeyHash is an Address for a pay-to-witness-pubkey-hash
|
||||||
// (P2WPKH) output. See BIP 173 for further details regarding native segregated
|
// (P2WPKH) output. See BIP 173 for further details regarding native segregated
|
||||||
// witness address encoding:
|
// witness address encoding:
|
||||||
// https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
|
// https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
|
||||||
type AddressWitnessPubKeyHash struct {
|
type AddressWitnessPubKeyHash struct {
|
||||||
hrp string
|
AddressSegWit
|
||||||
witnessVersion byte
|
|
||||||
witnessProgram [20]byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAddressWitnessPubKeyHash returns a new AddressWitnessPubKeyHash.
|
// 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)
|
return newAddressWitnessPubKeyHash(net.Bech32HRPSegwit, witnessProg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newAddressWitnessPubKeyHash is an internal helper function to create an
|
// newAddressWitnessPubKeyHash is an internal helper function to create an
|
||||||
// AddressWitnessPubKeyHash with a known human-readable part, rather than
|
// AddressWitnessPubKeyHash with a known human-readable part, rather than
|
||||||
// looking it up through its parameters.
|
// 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
|
// Check for valid program length for witness version 0, which is 20
|
||||||
// for P2WPKH.
|
// for P2WPKH.
|
||||||
if len(witnessProg) != 20 {
|
if len(witnessProg) != 20 {
|
||||||
|
@ -533,68 +596,22 @@ func newAddressWitnessPubKeyHash(hrp string, witnessProg []byte) (*AddressWitnes
|
||||||
}
|
}
|
||||||
|
|
||||||
addr := &AddressWitnessPubKeyHash{
|
addr := &AddressWitnessPubKeyHash{
|
||||||
|
AddressSegWit{
|
||||||
hrp: strings.ToLower(hrp),
|
hrp: strings.ToLower(hrp),
|
||||||
witnessVersion: 0x00,
|
witnessVersion: 0x00,
|
||||||
|
witnessProgram: witnessProg,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
copy(addr.witnessProgram[:], witnessProg)
|
|
||||||
|
|
||||||
return addr, nil
|
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
|
// Hash160 returns the witness program of the AddressWitnessPubKeyHash as a
|
||||||
// byte array.
|
// byte array.
|
||||||
func (a *AddressWitnessPubKeyHash) Hash160() *[20]byte {
|
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
|
// AddressWitnessScriptHash is an Address for a pay-to-witness-script-hash
|
||||||
|
@ -602,20 +619,22 @@ func (a *AddressWitnessPubKeyHash) Hash160() *[20]byte {
|
||||||
// witness address encoding:
|
// witness address encoding:
|
||||||
// https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
|
// https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
|
||||||
type AddressWitnessScriptHash struct {
|
type AddressWitnessScriptHash struct {
|
||||||
hrp string
|
AddressSegWit
|
||||||
witnessVersion byte
|
|
||||||
witnessProgram [32]byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAddressWitnessScriptHash returns a new AddressWitnessPubKeyHash.
|
// 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)
|
return newAddressWitnessScriptHash(net.Bech32HRPSegwit, witnessProg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newAddressWitnessScriptHash is an internal helper function to create an
|
// newAddressWitnessScriptHash is an internal helper function to create an
|
||||||
// AddressWitnessScriptHash with a known human-readable part, rather than
|
// AddressWitnessScriptHash with a known human-readable part, rather than
|
||||||
// looking it up through its parameters.
|
// 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
|
// Check for valid program length for witness version 0, which is 32
|
||||||
// for P2WSH.
|
// for P2WSH.
|
||||||
if len(witnessProg) != 32 {
|
if len(witnessProg) != 32 {
|
||||||
|
@ -624,60 +643,12 @@ func newAddressWitnessScriptHash(hrp string, witnessProg []byte) (*AddressWitnes
|
||||||
}
|
}
|
||||||
|
|
||||||
addr := &AddressWitnessScriptHash{
|
addr := &AddressWitnessScriptHash{
|
||||||
|
AddressSegWit{
|
||||||
hrp: strings.ToLower(hrp),
|
hrp: strings.ToLower(hrp),
|
||||||
witnessVersion: 0x00,
|
witnessVersion: 0x00,
|
||||||
|
witnessProgram: witnessProg,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
copy(addr.witnessProgram[:], witnessProg)
|
|
||||||
|
|
||||||
return addr, nil
|
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[:]
|
|
||||||
}
|
|
||||||
|
|
|
@ -59,9 +59,11 @@ func TstAddressWitnessPubKeyHash(version byte, program [20]byte,
|
||||||
hrp string) *AddressWitnessPubKeyHash {
|
hrp string) *AddressWitnessPubKeyHash {
|
||||||
|
|
||||||
return &AddressWitnessPubKeyHash{
|
return &AddressWitnessPubKeyHash{
|
||||||
|
AddressSegWit{
|
||||||
hrp: hrp,
|
hrp: hrp,
|
||||||
witnessVersion: version,
|
witnessVersion: version,
|
||||||
witnessProgram: program,
|
witnessProgram: program[:],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,9 +73,11 @@ func TstAddressWitnessScriptHash(version byte, program [32]byte,
|
||||||
hrp string) *AddressWitnessScriptHash {
|
hrp string) *AddressWitnessScriptHash {
|
||||||
|
|
||||||
return &AddressWitnessScriptHash{
|
return &AddressWitnessScriptHash{
|
||||||
|
AddressSegWit{
|
||||||
hrp: hrp,
|
hrp: hrp,
|
||||||
witnessVersion: version,
|
witnessVersion: version,
|
||||||
witnessProgram: program,
|
witnessProgram: program[:],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue