Update Address and WIF APIs to use btcnet.
This change removes all occurances of btcwire.BitcoinNet from exported APIs, replacing each with *btcnet.Params. This simplifies the logic for verifying string encodings of addresses and WIF private keys which use leading identifier numbers to differentiate between address types and the network they are intended for. It also allows the use of this package for non-standard networks (not mainnet, regtest, or testnet3) and future proofs it for the possible addition of future testnet networks. To update across this change, replace each btcwire.BitcoinNet parameter with the associated *btcnet.Params. For the standard networks, these changes are: btcwire.MainNet -> &btcnet.MainNetParams btcwire.TestNet -> &btcnet.RegressionNetParams btcwire.TestNet3 -> &btcnet.TestNet3Params ok @davecgh
This commit is contained in:
parent
bff18e5a93
commit
5bcc7790a0
6 changed files with 183 additions and 361 deletions
281
address.go
281
address.go
|
@ -10,78 +10,43 @@ import (
|
|||
"encoding/hex"
|
||||
"errors"
|
||||
"github.com/conformal/btcec"
|
||||
"github.com/conformal/btcnet"
|
||||
"github.com/conformal/btcwire"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrUnknownNet describes an error where the Bitcoin network is
|
||||
// not recognized.
|
||||
ErrUnknownNet = errors.New("unrecognized bitcoin network")
|
||||
|
||||
// ErrMalformedAddress describes an error where an address is improperly
|
||||
// formatted, either due to an incorrect length of the hashed pubkey or
|
||||
// a non-matching checksum.
|
||||
ErrMalformedAddress = errors.New("malformed address")
|
||||
|
||||
// ErrChecksumMismatch describes an error where decoding failed due
|
||||
// to a bad checksum.
|
||||
ErrChecksumMismatch = errors.New("checksum mismatch")
|
||||
|
||||
// ErrUnknownIdentifier describes an error where decoding failed due
|
||||
// to an unknown magic byte identifier.
|
||||
ErrUnknownIdentifier = errors.New("unknown identifier byte")
|
||||
// ErrUnknownAddressType describes an error where an address can not
|
||||
// decoded as a specific address type due to the string encoding
|
||||
// begining with an identifier byte unknown to any standard or
|
||||
// registered (via btcnet.Register) network.
|
||||
ErrUnknownAddressType = errors.New("unknown address type")
|
||||
|
||||
// ErrAddressCollision describes an error where an address can not
|
||||
// be uniquely determined as either a pay-to-pubkey-hash or
|
||||
// pay-to-script-hash address since the leading identifier is used for
|
||||
// describing both address kinds, but for different networks. Rather
|
||||
// than assuming or defaulting to one or the other, this error is
|
||||
// returned and the caller must decide how to decode the address.
|
||||
ErrAddressCollision = errors.New("address collision")
|
||||
)
|
||||
|
||||
// Constants used to specify which network a payment address belongs
|
||||
// to. Mainnet address cannot be used on the Testnet, and vice versa.
|
||||
const (
|
||||
// MainNetAddr is the address identifier for MainNet
|
||||
MainNetAddr = 0x00
|
||||
|
||||
// TestNetAddr is the address identifier for TestNet
|
||||
TestNetAddr = 0x6f
|
||||
|
||||
// MainNetScriptHash is the script hash identifier for MainNet
|
||||
MainNetScriptHash = 0x05
|
||||
|
||||
// TestNetScriptHash is the script hash identifier for TestNet
|
||||
TestNetScriptHash = 0xc4
|
||||
)
|
||||
|
||||
// checkBitcoinNet returns an error if the bitcoin network is not supported.
|
||||
func checkBitcoinNet(net btcwire.BitcoinNet) error {
|
||||
// Check for a valid bitcoin network.
|
||||
switch net {
|
||||
case btcwire.MainNet:
|
||||
fallthrough
|
||||
case btcwire.TestNet:
|
||||
fallthrough
|
||||
case btcwire.TestNet3:
|
||||
return nil
|
||||
default:
|
||||
return ErrUnknownNet
|
||||
}
|
||||
}
|
||||
|
||||
// encodeAddress returns a human-readable payment address given a ripemd160 hash
|
||||
// and netid which encodes the bitcoin network and address type. It is used
|
||||
// and netID which encodes the bitcoin network and address type. It is used
|
||||
// in both pay-to-pubkey-hash (P2PKH) and pay-to-script-hash (P2SH) address
|
||||
// encoding.
|
||||
func encodeAddress(hash160 []byte, netID byte) string {
|
||||
tosum := make([]byte, ripemd160.Size+1)
|
||||
tosum[0] = netID
|
||||
copy(tosum[1:], hash160)
|
||||
cksum := btcwire.DoubleSha256(tosum)
|
||||
|
||||
// Address before base58 encoding is 1 byte for netID, ripemd160 hash
|
||||
// size, plus 4 bytes of checksum (total 25).
|
||||
b := make([]byte, ripemd160.Size+5, ripemd160.Size+5)
|
||||
b[0] = netID
|
||||
copy(b[1:], hash160)
|
||||
copy(b[ripemd160.Size+1:], cksum[:4])
|
||||
|
||||
// Format is 1 byte for a network and address class (i.e. P2PKH vs
|
||||
// P2SH), 20 bytes for a RIPEMD160 hash, and 4 bytes of checksum.
|
||||
b := make([]byte, 0, 1+ripemd160.Size+4)
|
||||
b = append(b, netID)
|
||||
b = append(b, hash160...)
|
||||
cksum := btcwire.DoubleSha256(b)[:4]
|
||||
b = append(b, cksum...)
|
||||
return Base58Encode(b)
|
||||
|
||||
}
|
||||
|
||||
// Address is an interface type for any type of destination a transaction
|
||||
|
@ -99,7 +64,7 @@ type Address interface {
|
|||
|
||||
// IsForNet returns whether or not the address is associated with the
|
||||
// passed bitcoin network.
|
||||
IsForNet(btcwire.BitcoinNet) bool
|
||||
IsForNet(*btcnet.Params) bool
|
||||
}
|
||||
|
||||
// DecodeAddress decodes the string encoding of an address and returns
|
||||
|
@ -108,7 +73,7 @@ type Address interface {
|
|||
// The bitcoin network the address is associated with is extracted if possible.
|
||||
// When the address does not encode the network, such as in the case of a raw
|
||||
// public key, the address will be associated with the passed defaultNet.
|
||||
func DecodeAddress(addr string, defaultNet btcwire.BitcoinNet) (Address, error) {
|
||||
func DecodeAddress(addr string, defaultNet *btcnet.Params) (Address, error) {
|
||||
// Serialized public keys are either 65 bytes (130 hex chars) if
|
||||
// uncompressed/hybrid or 33 bytes (66 hex chars) if compressed.
|
||||
if len(addr) == 130 || len(addr) == 66 {
|
||||
|
@ -123,28 +88,6 @@ func DecodeAddress(addr string, defaultNet btcwire.BitcoinNet) (Address, error)
|
|||
decoded := Base58Decode(addr)
|
||||
switch len(decoded) {
|
||||
case 1 + ripemd160.Size + 4: // P2PKH or P2SH
|
||||
// Parse the network and hash type (pubkey hash vs script
|
||||
// hash) from the first byte.
|
||||
net := btcwire.MainNet
|
||||
isscript := false
|
||||
switch decoded[0] {
|
||||
case MainNetAddr:
|
||||
// Use defaults.
|
||||
|
||||
case TestNetAddr:
|
||||
net = btcwire.TestNet3
|
||||
|
||||
case MainNetScriptHash:
|
||||
isscript = true
|
||||
|
||||
case TestNetScriptHash:
|
||||
isscript = true
|
||||
net = btcwire.TestNet3
|
||||
|
||||
default:
|
||||
return nil, ErrUnknownIdentifier
|
||||
}
|
||||
|
||||
// Verify hash checksum. Checksum is calculated as the first
|
||||
// four bytes of double SHA256 of the network byte and hash.
|
||||
tosum := decoded[:ripemd160.Size+1]
|
||||
|
@ -153,13 +96,19 @@ func DecodeAddress(addr string, defaultNet btcwire.BitcoinNet) (Address, error)
|
|||
return nil, ErrChecksumMismatch
|
||||
}
|
||||
|
||||
// Return concrete type.
|
||||
if isscript {
|
||||
return NewAddressScriptHashFromHash(
|
||||
decoded[1:ripemd160.Size+1], net)
|
||||
netID := decoded[0]
|
||||
isP2PKH := btcnet.IsPubKeyHashAddrID(netID)
|
||||
isP2SH := btcnet.IsScriptHashAddrID(netID)
|
||||
switch hash160 := decoded[1 : ripemd160.Size+1]; {
|
||||
case isP2PKH && isP2SH:
|
||||
return nil, ErrAddressCollision
|
||||
case isP2PKH:
|
||||
return newAddressPubKeyHash(hash160, netID)
|
||||
case isP2SH:
|
||||
return newAddressScriptHashFromHash(hash160, netID)
|
||||
default:
|
||||
return nil, ErrUnknownAddressType
|
||||
}
|
||||
return NewAddressPubKeyHash(decoded[1:ripemd160.Size+1],
|
||||
net)
|
||||
|
||||
default:
|
||||
return nil, errors.New("decoded address is of unknown size")
|
||||
|
@ -175,30 +124,21 @@ type AddressPubKeyHash struct {
|
|||
|
||||
// NewAddressPubKeyHash returns a new AddressPubKeyHash. pkHash must
|
||||
// be 20 bytes.
|
||||
func NewAddressPubKeyHash(pkHash []byte, net btcwire.BitcoinNet) (*AddressPubKeyHash, error) {
|
||||
func NewAddressPubKeyHash(pkHash []byte, net *btcnet.Params) (*AddressPubKeyHash, error) {
|
||||
return newAddressPubKeyHash(pkHash, net.PubKeyHashAddrID)
|
||||
}
|
||||
|
||||
// newAddressPubKeyHash is the internal API to create a pubkey hash address
|
||||
// with a known leading identifier byte for a network, rather than looking
|
||||
// it up through its parameters. This is useful when creating a new address
|
||||
// structure from a string encoding where the identifer byte is already
|
||||
// known.
|
||||
func newAddressPubKeyHash(pkHash []byte, netID byte) (*AddressPubKeyHash, error) {
|
||||
// Check for a valid pubkey hash length.
|
||||
if len(pkHash) != ripemd160.Size {
|
||||
return nil, errors.New("pkHash must be 20 bytes")
|
||||
}
|
||||
|
||||
// Check for a valid bitcoin network.
|
||||
if err := checkBitcoinNet(net); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Choose the appropriate network ID for the address based on the
|
||||
// network.
|
||||
var netID byte
|
||||
switch net {
|
||||
case btcwire.MainNet:
|
||||
netID = MainNetAddr
|
||||
|
||||
case btcwire.TestNet:
|
||||
fallthrough
|
||||
case btcwire.TestNet3:
|
||||
netID = TestNetAddr
|
||||
}
|
||||
|
||||
addr := &AddressPubKeyHash{netID: netID}
|
||||
copy(addr.hash[:], pkHash)
|
||||
return addr, nil
|
||||
|
@ -218,18 +158,8 @@ func (a *AddressPubKeyHash) ScriptAddress() []byte {
|
|||
|
||||
// IsForNet returns whether or not the pay-to-pubkey-hash address is associated
|
||||
// with the passed bitcoin network.
|
||||
func (a *AddressPubKeyHash) IsForNet(net btcwire.BitcoinNet) bool {
|
||||
switch net {
|
||||
case btcwire.MainNet:
|
||||
return a.netID == MainNetAddr
|
||||
|
||||
case btcwire.TestNet:
|
||||
fallthrough
|
||||
case btcwire.TestNet3:
|
||||
return a.netID == TestNetAddr
|
||||
}
|
||||
|
||||
return false
|
||||
func (a *AddressPubKeyHash) IsForNet(net *btcnet.Params) bool {
|
||||
return a.netID == net.PubKeyHashAddrID
|
||||
}
|
||||
|
||||
// String returns a human-readable string for the pay-to-pubkey-hash address.
|
||||
|
@ -253,41 +183,29 @@ type AddressScriptHash struct {
|
|||
netID byte
|
||||
}
|
||||
|
||||
// NewAddressScriptHash returns a new AddressScriptHash. net must be
|
||||
// btcwire.MainNet or btcwire.TestNet3.
|
||||
func NewAddressScriptHash(serializedScript []byte, net btcwire.BitcoinNet) (*AddressScriptHash, error) {
|
||||
// Create hash of serialized script.
|
||||
// NewAddressScriptHash returns a new AddressScriptHash.
|
||||
func NewAddressScriptHash(serializedScript []byte, net *btcnet.Params) (*AddressScriptHash, error) {
|
||||
scriptHash := Hash160(serializedScript)
|
||||
|
||||
return NewAddressScriptHashFromHash(scriptHash, net)
|
||||
return newAddressScriptHashFromHash(scriptHash, net.ScriptHashAddrID)
|
||||
}
|
||||
|
||||
// NewAddressScriptHashFromHash returns a new AddressScriptHash. scriptHash
|
||||
// must be 20 bytes.
|
||||
func NewAddressScriptHashFromHash(scriptHash []byte, net btcwire.BitcoinNet) (*AddressScriptHash, error) {
|
||||
func NewAddressScriptHashFromHash(scriptHash []byte, net *btcnet.Params) (*AddressScriptHash, error) {
|
||||
return newAddressScriptHashFromHash(scriptHash, net.ScriptHashAddrID)
|
||||
}
|
||||
|
||||
// newAddressScriptHashFromHash is the internal API to create a script hash
|
||||
// address with a known leading identifier byte for a network, rather than
|
||||
// looking it up through its parameters. This is useful when creating a new
|
||||
// address structure from a string encoding where the identifer byte is already
|
||||
// known.
|
||||
func newAddressScriptHashFromHash(scriptHash []byte, netID byte) (*AddressScriptHash, error) {
|
||||
// Check for a valid script hash length.
|
||||
if len(scriptHash) != ripemd160.Size {
|
||||
return nil, errors.New("scriptHash must be 20 bytes")
|
||||
}
|
||||
|
||||
// Check for a valid bitcoin network.
|
||||
if err := checkBitcoinNet(net); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Choose the appropriate network ID for the address based on the
|
||||
// network.
|
||||
var netID byte
|
||||
switch net {
|
||||
case btcwire.MainNet:
|
||||
netID = MainNetScriptHash
|
||||
|
||||
case btcwire.TestNet:
|
||||
fallthrough
|
||||
case btcwire.TestNet3:
|
||||
netID = TestNetScriptHash
|
||||
}
|
||||
|
||||
addr := &AddressScriptHash{netID: netID}
|
||||
copy(addr.hash[:], scriptHash)
|
||||
return addr, nil
|
||||
|
@ -307,17 +225,8 @@ func (a *AddressScriptHash) ScriptAddress() []byte {
|
|||
|
||||
// IsForNet returns whether or not the pay-to-script-hash address is associated
|
||||
// with the passed bitcoin network.
|
||||
func (a *AddressScriptHash) IsForNet(net btcwire.BitcoinNet) bool {
|
||||
switch net {
|
||||
case btcwire.MainNet:
|
||||
return a.netID == MainNetScriptHash
|
||||
case btcwire.TestNet:
|
||||
fallthrough
|
||||
case btcwire.TestNet3:
|
||||
return a.netID == TestNetScriptHash
|
||||
}
|
||||
|
||||
return false
|
||||
func (a *AddressScriptHash) IsForNet(net *btcnet.Params) bool {
|
||||
return a.netID == net.ScriptHashAddrID
|
||||
}
|
||||
|
||||
// String returns a human-readable string for the pay-to-script-hash address.
|
||||
|
@ -355,13 +264,13 @@ const (
|
|||
type AddressPubKey struct {
|
||||
pubKeyFormat PubKeyFormat
|
||||
pubKey *btcec.PublicKey
|
||||
netID byte
|
||||
pubKeyHashID byte
|
||||
}
|
||||
|
||||
// NewAddressPubKey returns a new AddressPubKey which represents a pay-to-pubkey
|
||||
// address. The serializedPubKey parameter must be a valid pubkey and can be
|
||||
// uncompressed, compressed, or hybrid.
|
||||
func NewAddressPubKey(serializedPubKey []byte, net btcwire.BitcoinNet) (*AddressPubKey, error) {
|
||||
func NewAddressPubKey(serializedPubKey []byte, net *btcnet.Params) (*AddressPubKey, error) {
|
||||
pubKey, err := btcec.ParsePubKey(serializedPubKey, btcec.S256())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -373,61 +282,34 @@ func NewAddressPubKey(serializedPubKey []byte, net btcwire.BitcoinNet) (*Address
|
|||
// the leading byte to get the format.
|
||||
pkFormat := PKFUncompressed
|
||||
switch serializedPubKey[0] {
|
||||
case 0x02:
|
||||
fallthrough
|
||||
case 0x03:
|
||||
case 0x02, 0x03:
|
||||
pkFormat = PKFCompressed
|
||||
|
||||
case 0x06:
|
||||
fallthrough
|
||||
case 0x07:
|
||||
case 0x06, 0x07:
|
||||
pkFormat = PKFHybrid
|
||||
}
|
||||
|
||||
// Check for a valid bitcoin network.
|
||||
if err := checkBitcoinNet(net); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Choose the appropriate network ID for the address based on the
|
||||
// network.
|
||||
var netID byte
|
||||
switch net {
|
||||
case btcwire.MainNet:
|
||||
netID = MainNetAddr
|
||||
|
||||
case btcwire.TestNet:
|
||||
fallthrough
|
||||
case btcwire.TestNet3:
|
||||
netID = TestNetAddr
|
||||
}
|
||||
|
||||
ecPubKey := pubKey
|
||||
return &AddressPubKey{
|
||||
pubKeyFormat: pkFormat,
|
||||
pubKey: ecPubKey,
|
||||
netID: netID,
|
||||
pubKey: pubKey,
|
||||
pubKeyHashID: net.PubKeyHashAddrID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// serialize returns the serialization of the public key according to the
|
||||
// format associated with the address.
|
||||
func (a *AddressPubKey) serialize() []byte {
|
||||
var serializedPubKey []byte
|
||||
switch a.pubKeyFormat {
|
||||
default:
|
||||
fallthrough
|
||||
case PKFUncompressed:
|
||||
serializedPubKey = a.pubKey.SerializeUncompressed()
|
||||
return a.pubKey.SerializeUncompressed()
|
||||
|
||||
case PKFCompressed:
|
||||
serializedPubKey = a.pubKey.SerializeCompressed()
|
||||
return a.pubKey.SerializeCompressed()
|
||||
|
||||
case PKFHybrid:
|
||||
serializedPubKey = a.pubKey.SerializeHybrid()
|
||||
return a.pubKey.SerializeHybrid()
|
||||
}
|
||||
|
||||
return serializedPubKey
|
||||
}
|
||||
|
||||
// EncodeAddress returns the string encoding of the public key as a
|
||||
|
@ -439,7 +321,7 @@ func (a *AddressPubKey) serialize() []byte {
|
|||
//
|
||||
// Part of the Address interface.
|
||||
func (a *AddressPubKey) EncodeAddress() string {
|
||||
return encodeAddress(Hash160(a.serialize()), a.netID)
|
||||
return encodeAddress(Hash160(a.serialize()), a.pubKeyHashID)
|
||||
}
|
||||
|
||||
// ScriptAddress returns the bytes to be included in a txout script to pay
|
||||
|
@ -451,18 +333,8 @@ func (a *AddressPubKey) ScriptAddress() []byte {
|
|||
|
||||
// IsForNet returns whether or not the pay-to-pubkey address is associated
|
||||
// with the passed bitcoin network.
|
||||
func (a *AddressPubKey) IsForNet(net btcwire.BitcoinNet) bool {
|
||||
switch net {
|
||||
case btcwire.MainNet:
|
||||
return a.netID == MainNetAddr
|
||||
|
||||
case btcwire.TestNet:
|
||||
fallthrough
|
||||
case btcwire.TestNet3:
|
||||
return a.netID == TestNetAddr
|
||||
}
|
||||
|
||||
return false
|
||||
func (a *AddressPubKey) IsForNet(net *btcnet.Params) bool {
|
||||
return a.pubKeyHashID == net.PubKeyHashAddrID
|
||||
}
|
||||
|
||||
// String returns the hex-encoded human-readable string for the pay-to-pubkey
|
||||
|
@ -490,10 +362,9 @@ func (a *AddressPubKey) SetFormat(pkFormat PubKeyFormat) {
|
|||
// differs with the format. At the time of this writing, most Bitcoin addresses
|
||||
// are pay-to-pubkey-hash constructed from the uncompressed public key.
|
||||
func (a *AddressPubKey) AddressPubKeyHash() *AddressPubKeyHash {
|
||||
addr := &AddressPubKeyHash{netID: a.netID}
|
||||
addr := &AddressPubKeyHash{netID: a.pubKeyHashID}
|
||||
copy(addr.hash[:], Hash160(a.serialize()))
|
||||
return addr
|
||||
|
||||
}
|
||||
|
||||
// PubKey returns the underlying public key for the address.
|
||||
|
|
134
address_test.go
134
address_test.go
|
@ -6,13 +6,16 @@ package btcutil_test
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"code.google.com/p/go.crypto/ripemd160"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/conformal/btcutil"
|
||||
"github.com/conformal/btcwire"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"code.google.com/p/go.crypto/ripemd160"
|
||||
|
||||
"github.com/conformal/btcnet"
|
||||
"github.com/conformal/btcutil"
|
||||
"github.com/conformal/btcwire"
|
||||
)
|
||||
|
||||
// invalidNet is an invalid bitcoin network.
|
||||
|
@ -26,7 +29,7 @@ func TestAddresses(t *testing.T) {
|
|||
valid bool
|
||||
result btcutil.Address
|
||||
f func() (btcutil.Address, error)
|
||||
net btcwire.BitcoinNet
|
||||
net *btcnet.Params
|
||||
}{
|
||||
// Positive P2PKH tests.
|
||||
{
|
||||
|
@ -38,14 +41,14 @@ func TestAddresses(t *testing.T) {
|
|||
[ripemd160.Size]byte{
|
||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||
0xc5, 0x4c, 0xe7, 0xd2, 0xa4, 0x91, 0xbb, 0x4a, 0x0e, 0x84},
|
||||
btcutil.MainNetAddr),
|
||||
btcnet.MainNetParams.PubKeyHashAddrID),
|
||||
f: func() (btcutil.Address, error) {
|
||||
pkHash := []byte{
|
||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||
0xc5, 0x4c, 0xe7, 0xd2, 0xa4, 0x91, 0xbb, 0x4a, 0x0e, 0x84}
|
||||
return btcutil.NewAddressPubKeyHash(pkHash, btcwire.MainNet)
|
||||
return btcutil.NewAddressPubKeyHash(pkHash, &btcnet.MainNetParams)
|
||||
},
|
||||
net: btcwire.MainNet,
|
||||
net: &btcnet.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "mainnet p2pkh 2",
|
||||
|
@ -56,14 +59,14 @@ func TestAddresses(t *testing.T) {
|
|||
[ripemd160.Size]byte{
|
||||
0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, 0xf4,
|
||||
0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad, 0xaa},
|
||||
btcutil.MainNetAddr),
|
||||
btcnet.MainNetParams.PubKeyHashAddrID),
|
||||
f: func() (btcutil.Address, error) {
|
||||
pkHash := []byte{
|
||||
0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, 0xf4,
|
||||
0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad, 0xaa}
|
||||
return btcutil.NewAddressPubKeyHash(pkHash, btcwire.MainNet)
|
||||
return btcutil.NewAddressPubKeyHash(pkHash, &btcnet.MainNetParams)
|
||||
},
|
||||
net: btcwire.MainNet,
|
||||
net: &btcnet.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "testnet p2pkh",
|
||||
|
@ -74,29 +77,17 @@ func TestAddresses(t *testing.T) {
|
|||
[ripemd160.Size]byte{
|
||||
0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83,
|
||||
0xe5, 0x12, 0xd3, 0x60, 0x3f, 0x1f, 0x1c, 0x8d, 0xe6, 0x8f},
|
||||
btcutil.TestNetAddr),
|
||||
btcnet.TestNet3Params.PubKeyHashAddrID),
|
||||
f: func() (btcutil.Address, error) {
|
||||
pkHash := []byte{
|
||||
0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83,
|
||||
0xe5, 0x12, 0xd3, 0x60, 0x3f, 0x1f, 0x1c, 0x8d, 0xe6, 0x8f}
|
||||
return btcutil.NewAddressPubKeyHash(pkHash, btcwire.TestNet3)
|
||||
return btcutil.NewAddressPubKeyHash(pkHash, &btcnet.TestNet3Params)
|
||||
},
|
||||
net: btcwire.TestNet3,
|
||||
net: &btcnet.TestNet3Params,
|
||||
},
|
||||
|
||||
// Negative P2PKH tests.
|
||||
{
|
||||
name: "p2pkh wrong byte identifier/net",
|
||||
addr: "MrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz",
|
||||
encoded: "MrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz",
|
||||
valid: false,
|
||||
f: func() (btcutil.Address, error) {
|
||||
pkHash := []byte{
|
||||
0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83,
|
||||
0xe5, 0x12, 0xd3, 0x60, 0x3f, 0x1f, 0x1c, 0x8d, 0xe6, 0x8f}
|
||||
return btcutil.NewAddressPubKeyHash(pkHash, invalidNet)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "p2pkh wrong hash length",
|
||||
addr: "",
|
||||
|
@ -106,7 +97,7 @@ func TestAddresses(t *testing.T) {
|
|||
0x00, 0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b,
|
||||
0xf4, 0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad,
|
||||
0xaa}
|
||||
return btcutil.NewAddressPubKeyHash(pkHash, btcwire.MainNet)
|
||||
return btcutil.NewAddressPubKeyHash(pkHash, &btcnet.MainNetParams)
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -128,7 +119,7 @@ func TestAddresses(t *testing.T) {
|
|||
[ripemd160.Size]byte{
|
||||
0xf8, 0x15, 0xb0, 0x36, 0xd9, 0xbb, 0xbc, 0xe5, 0xe9, 0xf2,
|
||||
0xa0, 0x0a, 0xbd, 0x1b, 0xf3, 0xdc, 0x91, 0xe9, 0x55, 0x10},
|
||||
btcutil.MainNetScriptHash),
|
||||
btcnet.MainNetParams.ScriptHashAddrID),
|
||||
f: func() (btcutil.Address, error) {
|
||||
script := []byte{
|
||||
0x52, 0x41, 0x04, 0x91, 0xbb, 0xa2, 0x51, 0x09, 0x12, 0xa5,
|
||||
|
@ -152,9 +143,9 @@ func TestAddresses(t *testing.T) {
|
|||
0xdb, 0xfb, 0x1e, 0x75, 0x4e, 0x35, 0xfa, 0x1c, 0x78, 0x44,
|
||||
0xc4, 0x1f, 0x32, 0x2a, 0x18, 0x63, 0xd4, 0x62, 0x13, 0x53,
|
||||
0xae}
|
||||
return btcutil.NewAddressScriptHash(script, btcwire.MainNet)
|
||||
return btcutil.NewAddressScriptHash(script, &btcnet.MainNetParams)
|
||||
},
|
||||
net: btcwire.MainNet,
|
||||
net: &btcnet.MainNetParams,
|
||||
},
|
||||
{
|
||||
// Taken from transactions:
|
||||
|
@ -168,14 +159,14 @@ func TestAddresses(t *testing.T) {
|
|||
[ripemd160.Size]byte{
|
||||
0xe8, 0xc3, 0x00, 0xc8, 0x79, 0x86, 0xef, 0xa8, 0x4c, 0x37,
|
||||
0xc0, 0x51, 0x99, 0x29, 0x01, 0x9e, 0xf8, 0x6e, 0xb5, 0xb4},
|
||||
btcutil.MainNetScriptHash),
|
||||
btcnet.MainNetParams.ScriptHashAddrID),
|
||||
f: func() (btcutil.Address, error) {
|
||||
hash := []byte{
|
||||
0xe8, 0xc3, 0x00, 0xc8, 0x79, 0x86, 0xef, 0xa8, 0x4c, 0x37,
|
||||
0xc0, 0x51, 0x99, 0x29, 0x01, 0x9e, 0xf8, 0x6e, 0xb5, 0xb4}
|
||||
return btcutil.NewAddressScriptHashFromHash(hash, btcwire.MainNet)
|
||||
return btcutil.NewAddressScriptHashFromHash(hash, &btcnet.MainNetParams)
|
||||
},
|
||||
net: btcwire.MainNet,
|
||||
net: &btcnet.MainNetParams,
|
||||
},
|
||||
{
|
||||
// Taken from bitcoind base58_keys_valid.
|
||||
|
@ -187,14 +178,14 @@ func TestAddresses(t *testing.T) {
|
|||
[ripemd160.Size]byte{
|
||||
0xc5, 0x79, 0x34, 0x2c, 0x2c, 0x4c, 0x92, 0x20, 0x20, 0x5e,
|
||||
0x2c, 0xdc, 0x28, 0x56, 0x17, 0x04, 0x0c, 0x92, 0x4a, 0x0a},
|
||||
btcutil.TestNetScriptHash),
|
||||
btcnet.TestNet3Params.ScriptHashAddrID),
|
||||
f: func() (btcutil.Address, error) {
|
||||
hash := []byte{
|
||||
0xc5, 0x79, 0x34, 0x2c, 0x2c, 0x4c, 0x92, 0x20, 0x20, 0x5e,
|
||||
0x2c, 0xdc, 0x28, 0x56, 0x17, 0x04, 0x0c, 0x92, 0x4a, 0x0a}
|
||||
return btcutil.NewAddressScriptHashFromHash(hash, btcwire.TestNet3)
|
||||
return btcutil.NewAddressScriptHashFromHash(hash, &btcnet.TestNet3Params)
|
||||
},
|
||||
net: btcwire.TestNet3,
|
||||
net: &btcnet.TestNet3Params,
|
||||
},
|
||||
|
||||
// Negative P2SH tests.
|
||||
|
@ -207,18 +198,7 @@ func TestAddresses(t *testing.T) {
|
|||
0x00, 0xf8, 0x15, 0xb0, 0x36, 0xd9, 0xbb, 0xbc, 0xe5, 0xe9,
|
||||
0xf2, 0xa0, 0x0a, 0xbd, 0x1b, 0xf3, 0xdc, 0x91, 0xe9, 0x55,
|
||||
0x10}
|
||||
return btcutil.NewAddressScriptHashFromHash(hash, btcwire.MainNet)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "p2sh wrong byte identifier/net",
|
||||
addr: "0NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n",
|
||||
valid: false,
|
||||
f: func() (btcutil.Address, error) {
|
||||
hash := []byte{
|
||||
0xc5, 0x79, 0x34, 0x2c, 0x2c, 0x4c, 0x92, 0x20, 0x20, 0x5e,
|
||||
0x2c, 0xdc, 0x28, 0x56, 0x17, 0x04, 0x0c, 0x92, 0x4a, 0x0a}
|
||||
return btcutil.NewAddressScriptHashFromHash(hash, invalidNet)
|
||||
return btcutil.NewAddressScriptHashFromHash(hash, &btcnet.MainNetParams)
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -234,16 +214,16 @@ func TestAddresses(t *testing.T) {
|
|||
0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03,
|
||||
0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca,
|
||||
0x52, 0xc6, 0xb4},
|
||||
btcutil.PKFCompressed, btcutil.MainNetAddr),
|
||||
btcutil.PKFCompressed, btcnet.MainNetParams.PubKeyHashAddrID),
|
||||
f: func() (btcutil.Address, error) {
|
||||
serializedPubKey := []byte{
|
||||
0x02, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95,
|
||||
0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03,
|
||||
0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca,
|
||||
0x52, 0xc6, 0xb4}
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, btcwire.MainNet)
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.MainNetParams)
|
||||
},
|
||||
net: btcwire.MainNet,
|
||||
net: &btcnet.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "mainnet p2pk compressed (0x03)",
|
||||
|
@ -256,16 +236,16 @@ func TestAddresses(t *testing.T) {
|
|||
0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0,
|
||||
0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e,
|
||||
0xb1, 0x6e, 0x65},
|
||||
btcutil.PKFCompressed, btcutil.MainNetAddr),
|
||||
btcutil.PKFCompressed, btcnet.MainNetParams.PubKeyHashAddrID),
|
||||
f: func() (btcutil.Address, error) {
|
||||
serializedPubKey := []byte{
|
||||
0x03, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1,
|
||||
0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0,
|
||||
0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e,
|
||||
0xb1, 0x6e, 0x65}
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, btcwire.MainNet)
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.MainNetParams)
|
||||
},
|
||||
net: btcwire.MainNet,
|
||||
net: &btcnet.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "mainnet p2pk uncompressed (0x04)",
|
||||
|
@ -282,7 +262,7 @@ func TestAddresses(t *testing.T) {
|
|||
0xf9, 0x74, 0x44, 0x64, 0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b,
|
||||
0x8b, 0x64, 0xf9, 0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43,
|
||||
0xf6, 0x56, 0xb4, 0x12, 0xa3},
|
||||
btcutil.PKFUncompressed, btcutil.MainNetAddr),
|
||||
btcutil.PKFUncompressed, btcnet.MainNetParams.PubKeyHashAddrID),
|
||||
f: func() (btcutil.Address, error) {
|
||||
serializedPubKey := []byte{
|
||||
0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01, 0x6b,
|
||||
|
@ -292,9 +272,9 @@ func TestAddresses(t *testing.T) {
|
|||
0xf9, 0x74, 0x44, 0x64, 0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b,
|
||||
0x8b, 0x64, 0xf9, 0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43,
|
||||
0xf6, 0x56, 0xb4, 0x12, 0xa3}
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, btcwire.MainNet)
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.MainNetParams)
|
||||
},
|
||||
net: btcwire.MainNet,
|
||||
net: &btcnet.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "mainnet p2pk hybrid (0x06)",
|
||||
|
@ -311,7 +291,7 @@ func TestAddresses(t *testing.T) {
|
|||
0x96, 0x85, 0x26, 0x62, 0xce, 0x6a, 0x84, 0x7b, 0x19, 0x73,
|
||||
0x76, 0x83, 0x01, 0x60, 0xc6, 0xd2, 0xeb, 0x5e, 0x6a, 0x4c,
|
||||
0x44, 0xd3, 0x3f, 0x45, 0x3e},
|
||||
btcutil.PKFHybrid, btcutil.MainNetAddr),
|
||||
btcutil.PKFHybrid, btcnet.MainNetParams.PubKeyHashAddrID),
|
||||
f: func() (btcutil.Address, error) {
|
||||
serializedPubKey := []byte{
|
||||
0x06, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95,
|
||||
|
@ -321,9 +301,9 @@ func TestAddresses(t *testing.T) {
|
|||
0x96, 0x85, 0x26, 0x62, 0xce, 0x6a, 0x84, 0x7b, 0x19, 0x73,
|
||||
0x76, 0x83, 0x01, 0x60, 0xc6, 0xd2, 0xeb, 0x5e, 0x6a, 0x4c,
|
||||
0x44, 0xd3, 0x3f, 0x45, 0x3e}
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, btcwire.MainNet)
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.MainNetParams)
|
||||
},
|
||||
net: btcwire.MainNet,
|
||||
net: &btcnet.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "mainnet p2pk hybrid (0x07)",
|
||||
|
@ -340,7 +320,7 @@ func TestAddresses(t *testing.T) {
|
|||
0x8a, 0x7e, 0xf8, 0xbd, 0x3b, 0x3c, 0xfb, 0x1e, 0xdb, 0x71,
|
||||
0x17, 0xab, 0x65, 0x12, 0x9b, 0x8a, 0x2e, 0x68, 0x1f, 0x3c,
|
||||
0x1e, 0x09, 0x08, 0xef, 0x7b},
|
||||
btcutil.PKFHybrid, btcutil.MainNetAddr),
|
||||
btcutil.PKFHybrid, btcnet.MainNetParams.PubKeyHashAddrID),
|
||||
f: func() (btcutil.Address, error) {
|
||||
serializedPubKey := []byte{
|
||||
0x07, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1,
|
||||
|
@ -350,9 +330,9 @@ func TestAddresses(t *testing.T) {
|
|||
0x8a, 0x7e, 0xf8, 0xbd, 0x3b, 0x3c, 0xfb, 0x1e, 0xdb, 0x71,
|
||||
0x17, 0xab, 0x65, 0x12, 0x9b, 0x8a, 0x2e, 0x68, 0x1f, 0x3c,
|
||||
0x1e, 0x09, 0x08, 0xef, 0x7b}
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, btcwire.MainNet)
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.MainNetParams)
|
||||
},
|
||||
net: btcwire.MainNet,
|
||||
net: &btcnet.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "testnet p2pk compressed (0x02)",
|
||||
|
@ -365,16 +345,16 @@ func TestAddresses(t *testing.T) {
|
|||
0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03,
|
||||
0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca,
|
||||
0x52, 0xc6, 0xb4},
|
||||
btcutil.PKFCompressed, btcutil.TestNetAddr),
|
||||
btcutil.PKFCompressed, btcnet.TestNet3Params.PubKeyHashAddrID),
|
||||
f: func() (btcutil.Address, error) {
|
||||
serializedPubKey := []byte{
|
||||
0x02, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95,
|
||||
0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03,
|
||||
0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca,
|
||||
0x52, 0xc6, 0xb4}
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, btcwire.TestNet3)
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.TestNet3Params)
|
||||
},
|
||||
net: btcwire.TestNet3,
|
||||
net: &btcnet.TestNet3Params,
|
||||
},
|
||||
{
|
||||
name: "testnet p2pk compressed (0x03)",
|
||||
|
@ -387,16 +367,16 @@ func TestAddresses(t *testing.T) {
|
|||
0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0,
|
||||
0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e,
|
||||
0xb1, 0x6e, 0x65},
|
||||
btcutil.PKFCompressed, btcutil.TestNetAddr),
|
||||
btcutil.PKFCompressed, btcnet.TestNet3Params.PubKeyHashAddrID),
|
||||
f: func() (btcutil.Address, error) {
|
||||
serializedPubKey := []byte{
|
||||
0x03, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1,
|
||||
0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0,
|
||||
0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e,
|
||||
0xb1, 0x6e, 0x65}
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, btcwire.TestNet3)
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.TestNet3Params)
|
||||
},
|
||||
net: btcwire.TestNet3,
|
||||
net: &btcnet.TestNet3Params,
|
||||
},
|
||||
{
|
||||
name: "testnet p2pk uncompressed (0x04)",
|
||||
|
@ -413,7 +393,7 @@ func TestAddresses(t *testing.T) {
|
|||
0xf9, 0x74, 0x44, 0x64, 0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b,
|
||||
0x8b, 0x64, 0xf9, 0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43,
|
||||
0xf6, 0x56, 0xb4, 0x12, 0xa3},
|
||||
btcutil.PKFUncompressed, btcutil.TestNetAddr),
|
||||
btcutil.PKFUncompressed, btcnet.TestNet3Params.PubKeyHashAddrID),
|
||||
f: func() (btcutil.Address, error) {
|
||||
serializedPubKey := []byte{
|
||||
0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01, 0x6b,
|
||||
|
@ -423,9 +403,9 @@ func TestAddresses(t *testing.T) {
|
|||
0xf9, 0x74, 0x44, 0x64, 0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b,
|
||||
0x8b, 0x64, 0xf9, 0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43,
|
||||
0xf6, 0x56, 0xb4, 0x12, 0xa3}
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, btcwire.TestNet3)
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.TestNet3Params)
|
||||
},
|
||||
net: btcwire.TestNet3,
|
||||
net: &btcnet.TestNet3Params,
|
||||
},
|
||||
{
|
||||
name: "testnet p2pk hybrid (0x06)",
|
||||
|
@ -442,7 +422,7 @@ func TestAddresses(t *testing.T) {
|
|||
0x96, 0x85, 0x26, 0x62, 0xce, 0x6a, 0x84, 0x7b, 0x19, 0x73,
|
||||
0x76, 0x83, 0x01, 0x60, 0xc6, 0xd2, 0xeb, 0x5e, 0x6a, 0x4c,
|
||||
0x44, 0xd3, 0x3f, 0x45, 0x3e},
|
||||
btcutil.PKFHybrid, btcutil.TestNetAddr),
|
||||
btcutil.PKFHybrid, btcnet.TestNet3Params.PubKeyHashAddrID),
|
||||
f: func() (btcutil.Address, error) {
|
||||
serializedPubKey := []byte{
|
||||
0x06, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95,
|
||||
|
@ -452,9 +432,9 @@ func TestAddresses(t *testing.T) {
|
|||
0x96, 0x85, 0x26, 0x62, 0xce, 0x6a, 0x84, 0x7b, 0x19, 0x73,
|
||||
0x76, 0x83, 0x01, 0x60, 0xc6, 0xd2, 0xeb, 0x5e, 0x6a, 0x4c,
|
||||
0x44, 0xd3, 0x3f, 0x45, 0x3e}
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, btcwire.TestNet3)
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.TestNet3Params)
|
||||
},
|
||||
net: btcwire.TestNet3,
|
||||
net: &btcnet.TestNet3Params,
|
||||
},
|
||||
{
|
||||
name: "testnet p2pk hybrid (0x07)",
|
||||
|
@ -471,7 +451,7 @@ func TestAddresses(t *testing.T) {
|
|||
0x8a, 0x7e, 0xf8, 0xbd, 0x3b, 0x3c, 0xfb, 0x1e, 0xdb, 0x71,
|
||||
0x17, 0xab, 0x65, 0x12, 0x9b, 0x8a, 0x2e, 0x68, 0x1f, 0x3c,
|
||||
0x1e, 0x09, 0x08, 0xef, 0x7b},
|
||||
btcutil.PKFHybrid, btcutil.TestNetAddr),
|
||||
btcutil.PKFHybrid, btcnet.TestNet3Params.PubKeyHashAddrID),
|
||||
f: func() (btcutil.Address, error) {
|
||||
serializedPubKey := []byte{
|
||||
0x07, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1,
|
||||
|
@ -481,9 +461,9 @@ func TestAddresses(t *testing.T) {
|
|||
0x8a, 0x7e, 0xf8, 0xbd, 0x3b, 0x3c, 0xfb, 0x1e, 0xdb, 0x71,
|
||||
0x17, 0xab, 0x65, 0x12, 0x9b, 0x8a, 0x2e, 0x68, 0x1f, 0x3c,
|
||||
0x1e, 0x09, 0x08, 0xef, 0x7b}
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, btcwire.TestNet3)
|
||||
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.TestNet3Params)
|
||||
},
|
||||
net: btcwire.TestNet3,
|
||||
net: &btcnet.TestNet3Params,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ func TstAddressPubKey(serializedPubKey []byte, pubKeyFormat PubKeyFormat,
|
|||
return &AddressPubKey{
|
||||
pubKeyFormat: pubKeyFormat,
|
||||
pubKey: (*btcec.PublicKey)(pubKey),
|
||||
netID: netID,
|
||||
pubKeyHashID: netID,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,65 +2,66 @@
|
|||
github.com/conformal/btcutil/base58.go Base58Decode 100.00% (20/20)
|
||||
github.com/conformal/btcutil/base58.go Base58Encode 100.00% (15/15)
|
||||
github.com/conformal/btcutil/block.go Block.Tx 100.00% (12/12)
|
||||
github.com/conformal/btcutil/wif.go WIF.String 100.00% (11/11)
|
||||
github.com/conformal/btcutil/block.go Block.Transactions 100.00% (11/11)
|
||||
github.com/conformal/btcutil/address.go encodeAddress 100.00% (9/9)
|
||||
github.com/conformal/btcutil/wif.go WIF.String 100.00% (11/11)
|
||||
github.com/conformal/btcutil/amount.go NewAmount 100.00% (9/9)
|
||||
github.com/conformal/btcutil/amount.go AmountUnit.String 100.00% (8/8)
|
||||
github.com/conformal/btcutil/block.go NewBlockFromBytes 100.00% (7/7)
|
||||
github.com/conformal/btcutil/tx.go NewTxFromBytes 100.00% (7/7)
|
||||
github.com/conformal/btcutil/block.go Block.Sha 100.00% (5/5)
|
||||
github.com/conformal/btcutil/address.go encodeAddress 100.00% (6/6)
|
||||
github.com/conformal/btcutil/address.go newAddressScriptHashFromHash 100.00% (5/5)
|
||||
github.com/conformal/btcutil/tx.go Tx.Sha 100.00% (5/5)
|
||||
github.com/conformal/btcutil/address.go checkBitcoinNet 100.00% (5/5)
|
||||
github.com/conformal/btcutil/block.go Block.Sha 100.00% (5/5)
|
||||
github.com/conformal/btcutil/address.go newAddressPubKeyHash 100.00% (5/5)
|
||||
github.com/conformal/btcutil/hash160.go calcHash 100.00% (2/2)
|
||||
github.com/conformal/btcutil/amount.go Amount.Format 100.00% (2/2)
|
||||
github.com/conformal/btcutil/address.go NewAddressScriptHash 100.00% (2/2)
|
||||
github.com/conformal/btcutil/block.go NewBlockFromBlockAndBytes 100.00% (1/1)
|
||||
github.com/conformal/btcutil/amount.go Amount.ToUnit 100.00% (1/1)
|
||||
github.com/conformal/btcutil/amount.go Amount.Format 100.00% (2/2)
|
||||
github.com/conformal/btcutil/amount.go Amount.String 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKeyHash.String 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKeyHash.Hash160 100.00% (1/1)
|
||||
github.com/conformal/btcutil/block.go OutOfRangeError.Error 100.00% (1/1)
|
||||
github.com/conformal/btcutil/block.go Block.MsgBlock 100.00% (1/1)
|
||||
github.com/conformal/btcutil/block.go NewBlock 100.00% (1/1)
|
||||
github.com/conformal/btcutil/block.go Block.SetHeight 100.00% (1/1)
|
||||
github.com/conformal/btcutil/block.go Block.Height 100.00% (1/1)
|
||||
github.com/conformal/btcutil/tx.go Tx.SetIndex 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go NewAddressPubKeyHash 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKeyHash.EncodeAddress 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKeyHash.ScriptAddress 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKeyHash.Hash160 100.00% (1/1)
|
||||
github.com/conformal/btcutil/tx.go NewTx 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKeyHash.IsForNet 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKeyHash.String 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go NewAddressScriptHashFromHash 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressScriptHash.EncodeAddress 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressScriptHash.ScriptAddress 100.00% (1/1)
|
||||
github.com/conformal/btcutil/tx.go Tx.SetIndex 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressScriptHash.IsForNet 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressScriptHash.String 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressScriptHash.Hash160 100.00% (1/1)
|
||||
github.com/conformal/btcutil/tx.go Tx.Index 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.EncodeAddress 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.ScriptAddress 100.00% (1/1)
|
||||
github.com/conformal/btcutil/tx.go Tx.MsgTx 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.IsForNet 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.String 100.00% (1/1)
|
||||
github.com/conformal/btcutil/amount.go Amount.ToUnit 100.00% (1/1)
|
||||
github.com/conformal/btcutil/block.go Block.Height 100.00% (1/1)
|
||||
github.com/conformal/btcutil/block.go Block.SetHeight 100.00% (1/1)
|
||||
github.com/conformal/btcutil/block.go NewBlock 100.00% (1/1)
|
||||
github.com/conformal/btcutil/block.go NewBlockFromBlockAndBytes 100.00% (1/1)
|
||||
github.com/conformal/btcutil/hash160.go Hash160 100.00% (1/1)
|
||||
github.com/conformal/btcutil/block.go OutOfRangeError.Error 100.00% (1/1)
|
||||
github.com/conformal/btcutil/address.go DecodeAddress 95.65% (22/23)
|
||||
github.com/conformal/btcutil/tx.go Tx.MsgTx 100.00% (1/1)
|
||||
github.com/conformal/btcutil/tx.go Tx.Index 100.00% (1/1)
|
||||
github.com/conformal/btcutil/tx.go NewTx 100.00% (1/1)
|
||||
github.com/conformal/btcutil/appdata.go appDataDir 92.00% (23/25)
|
||||
github.com/conformal/btcutil/address.go NewAddressPubKeyHash 91.67% (11/12)
|
||||
github.com/conformal/btcutil/address.go NewAddressScriptHashFromHash 91.67% (11/12)
|
||||
github.com/conformal/btcutil/block.go Block.TxLoc 88.89% (8/9)
|
||||
github.com/conformal/btcutil/block.go Block.Bytes 88.89% (8/9)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.serialize 85.71% (6/7)
|
||||
github.com/conformal/btcutil/address.go NewAddressPubKey 83.33% (15/18)
|
||||
github.com/conformal/btcutil/wif.go DecodeWIF 81.82% (18/22)
|
||||
github.com/conformal/btcutil/wif.go NewWIF 75.00% (3/4)
|
||||
github.com/conformal/btcutil/address.go NewAddressPubKey 87.50% (7/8)
|
||||
github.com/conformal/btcutil/address.go DecodeAddress 85.00% (17/20)
|
||||
github.com/conformal/btcutil/wif.go DecodeWIF 85.00% (17/20)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.serialize 80.00% (4/5)
|
||||
github.com/conformal/btcutil/block.go Block.TxSha 75.00% (3/4)
|
||||
github.com/conformal/btcutil/wif.go paddedAppend 66.67% (2/3)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.IsForNet 60.00% (3/5)
|
||||
github.com/conformal/btcutil/address.go AddressScriptHash.IsForNet 60.00% (3/5)
|
||||
github.com/conformal/btcutil/address.go AddressPubKeyHash.IsForNet 60.00% (3/5)
|
||||
github.com/conformal/btcutil/wif.go NewWIF 66.67% (2/3)
|
||||
github.com/conformal/btcutil/certgen.go NewTLSCertPair 0.00% (0/50)
|
||||
github.com/conformal/btcutil/wif.go WIF.SerializePubKey 0.00% (0/4)
|
||||
github.com/conformal/btcutil/wif.go WIF.IsForNet 0.00% (0/4)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.AddressPubKeyHash 0.00% (0/3)
|
||||
github.com/conformal/btcutil/appdata.go AppDataDir 0.00% (0/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.Format 0.00% (0/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.SetFormat 0.00% (0/1)
|
||||
github.com/conformal/btcutil/appdata.go AppDataDir 0.00% (0/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.PubKey 0.00% (0/1)
|
||||
github.com/conformal/btcutil ------------------------------- 76.70% (293/382)
|
||||
github.com/conformal/btcutil/wif.go WIF.IsForNet 0.00% (0/1)
|
||||
github.com/conformal/btcutil/address.go AddressPubKey.Format 0.00% (0/1)
|
||||
github.com/conformal/btcutil ------------------------------- 76.60% (252/329)
|
||||
|
||||
|
|
58
wif.go
58
wif.go
|
@ -9,6 +9,7 @@ import (
|
|||
"errors"
|
||||
|
||||
"github.com/conformal/btcec"
|
||||
"github.com/conformal/btcnet"
|
||||
"github.com/conformal/btcwire"
|
||||
)
|
||||
|
||||
|
@ -18,21 +19,9 @@ import (
|
|||
// encountered.
|
||||
var ErrMalformedPrivateKey = errors.New("malformed private key")
|
||||
|
||||
// These constants define the magic numbers used for identifing components
|
||||
// of a WIF-encoded private key and the bitcoin address associated with it.
|
||||
const (
|
||||
// mainNetKey is the magic number identifying a WIF private key for
|
||||
// the MainNet bitcoin network.
|
||||
mainNetKey byte = 0x80
|
||||
|
||||
// testNetKey is the magic number identifying a WIF private key for
|
||||
// the regression test and TestNet3 bitcoin networks.
|
||||
testNetKey byte = 0xef
|
||||
|
||||
// compressMagic is the magic byte used to identify a WIF encoding for
|
||||
// an address created from a compressed serialized public key.
|
||||
compressMagic byte = 0x01
|
||||
)
|
||||
// compressMagic is the magic byte used to identify a WIF encoding for
|
||||
// an address created from a compressed serialized public key.
|
||||
const compressMagic byte = 0x01
|
||||
|
||||
// WIF contains the individual components described by the Wallet Import Format
|
||||
// (WIF). A WIF string is typically used to represent a private key and its
|
||||
|
@ -56,35 +45,20 @@ type WIF struct {
|
|||
}
|
||||
|
||||
// NewWIF creates a new WIF structure to export an address and its private key
|
||||
// as a string encoded in the Wallet Import Format. The net argument must be
|
||||
// either btcwire.MainNet, btcwire.TestNet3 or btcwire.TestNet. The compress
|
||||
// argument specifies whether the address intended to be imported or exported
|
||||
// was created by serializing the public key compressed rather than
|
||||
// uncompressed.
|
||||
func NewWIF(privKey *btcec.PrivateKey, net btcwire.BitcoinNet, compress bool) (*WIF, error) {
|
||||
// Determine the key's network identifier byte. The same byte is
|
||||
// shared for TestNet3 and TestNet (the regression test network).
|
||||
switch net {
|
||||
case btcwire.MainNet:
|
||||
return &WIF{privKey, compress, mainNetKey}, nil
|
||||
case btcwire.TestNet, btcwire.TestNet3:
|
||||
return &WIF{privKey, compress, testNetKey}, nil
|
||||
default:
|
||||
return nil, ErrUnknownNet
|
||||
// as a string encoded in the Wallet Import Format. The compress argument
|
||||
// specifies whether the address intended to be imported or exported was created
|
||||
// by serializing the public key compressed rather than uncompressed.
|
||||
func NewWIF(privKey *btcec.PrivateKey, net *btcnet.Params, compress bool) (*WIF, error) {
|
||||
if net == nil {
|
||||
return nil, errors.New("no network")
|
||||
}
|
||||
return &WIF{privKey, compress, net.PrivateKeyID}, nil
|
||||
}
|
||||
|
||||
// IsForNet returns whether or not the decoded WIF structure is associated
|
||||
// with the passed bitcoin network.
|
||||
func (w *WIF) IsForNet(net btcwire.BitcoinNet) bool {
|
||||
switch net {
|
||||
case btcwire.MainNet:
|
||||
return w.netID == mainNetKey
|
||||
case btcwire.TestNet, btcwire.TestNet3:
|
||||
return w.netID == testNetKey
|
||||
default:
|
||||
return false
|
||||
}
|
||||
func (w *WIF) IsForNet(net *btcnet.Params) bool {
|
||||
return w.netID == net.PrivateKeyID
|
||||
}
|
||||
|
||||
// DecodeWIF creates a new WIF structure by decoding the string encoding of
|
||||
|
@ -126,11 +100,6 @@ func DecodeWIF(wif string) (*WIF, error) {
|
|||
return nil, ErrMalformedPrivateKey
|
||||
}
|
||||
|
||||
netID := decoded[0]
|
||||
if netID != mainNetKey && netID != testNetKey {
|
||||
return nil, ErrUnknownNet
|
||||
}
|
||||
|
||||
// Checksum is first four bytes of double SHA256 of the identifier byte
|
||||
// and privKey. Verify this matches the final 4 bytes of the decoded
|
||||
// private key.
|
||||
|
@ -145,6 +114,7 @@ func DecodeWIF(wif string) (*WIF, error) {
|
|||
return nil, ErrChecksumMismatch
|
||||
}
|
||||
|
||||
netID := decoded[0]
|
||||
privKeyBytes := decoded[1 : 1+btcec.PrivKeyBytesLen]
|
||||
privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes)
|
||||
return &WIF{privKey, compress, netID}, nil
|
||||
|
|
|
@ -8,8 +8,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/conformal/btcec"
|
||||
"github.com/conformal/btcnet"
|
||||
. "github.com/conformal/btcutil"
|
||||
"github.com/conformal/btcwire"
|
||||
)
|
||||
|
||||
func TestEncodeDecodeWIF(t *testing.T) {
|
||||
|
@ -25,11 +25,11 @@ func TestEncodeDecodeWIF(t *testing.T) {
|
|||
0x4e, 0x39, 0x6f, 0xb5, 0xdc, 0x29, 0x5f, 0xe9,
|
||||
0x94, 0xb9, 0x67, 0x89, 0xb2, 0x1a, 0x03, 0x98})
|
||||
|
||||
wif1, err := NewWIF(priv1, btcwire.MainNet, false)
|
||||
wif1, err := NewWIF(priv1, &btcnet.MainNetParams, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
wif2, err := NewWIF(priv2, btcwire.TestNet3, true)
|
||||
wif2, err := NewWIF(priv2, &btcnet.TestNet3Params, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue