[DEV-17] Move Bech32Prefix-related code from btcd/chaincfg/params.go to btcdutil (#62)

* [DEV-17] Moved Bech32 stuff from params.go to address.go.

* [DEV-17] Removed dagconfig dependency from address_test.go.

* [DEV-17] Removed dagconfig dependency from builder_test.go.

* [DEV-17] Removed dagconfig dependency from internal_test.go.

* [DEV-17] Removed dagconfig dependency from wif.go.

* [DEV-17] Removed dagconfig dependency from externdedkey.go.

* [DEV-17] Fixed compilation errors outside of hdkeychain.

* [DEV-17] Resolved circular dependencies.

* [DEV-17] Fixed failing tests.

* [DEV-17] Renamed DagXxx to Bech32PrefixDAGXxx

* [DEV-17] Fixed register_test.go.

* [DEV-17] Renamed HDKeyIDPairXxxNet to XxxNetHDKeyPair.

* [DEV-17] Renamed IsForNet to IsForPrefix.
This commit is contained in:
stasatdaglabs 2018-09-23 15:49:50 +03:00 committed by Svarog
parent 9b5aa66e5b
commit 6dd3b815c1
25 changed files with 606 additions and 593 deletions

View File

@ -6,6 +6,7 @@ package fullblocktests
import (
"encoding/hex"
"github.com/daglabs/btcd/util/hdkeychain"
"math"
"math/big"
"time"
@ -123,8 +124,7 @@ var regressionNetParams = &dagconfig.Params{
PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed)
// BIP32 hierarchical deterministic extended key magics
HDPrivateKeyID: [4]byte{0x04, 0x35, 0x83, 0x94}, // starts with tprv
HDPublicKeyID: [4]byte{0x04, 0x35, 0x87, 0xcf}, // starts with tpub
HDKeyIDPair: hdkeychain.HDKeyPairRegressionNet,
// BIP44 coin type used in the hierarchical deterministic path for
// address generation.

View File

@ -731,7 +731,7 @@ func loadConfig() (*Config, []string, error) {
// Check mining addresses are valid and saved parsed versions.
cfg.MiningAddrs = make([]util.Address, 0, len(cfg.configFlags.MiningAddrs))
for _, strAddr := range cfg.configFlags.MiningAddrs {
addr, err := util.DecodeAddress(strAddr, activeNetParams)
addr, err := util.DecodeAddress(strAddr, activeNetParams.Prefix)
if err != nil {
str := "%s: mining address '%s' failed to decode: %v"
err := fmt.Errorf(str, funcName, strAddr, err)
@ -739,7 +739,7 @@ func loadConfig() (*Config, []string, error) {
fmt.Fprintln(os.Stderr, usageMessage)
return nil, nil, err
}
if !addr.IsForNet(activeNetParams) {
if !addr.IsForPrefix(activeNetParams.Prefix) {
str := "%s: mining address '%s' is on the wrong network"
err := fmt.Errorf(str, funcName, strAddr)
fmt.Fprintln(os.Stderr, err)

View File

@ -6,12 +6,12 @@ package dagconfig
import (
"errors"
"github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/util/hdkeychain"
"math"
"math/big"
"time"
"fmt"
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/wire"
)
@ -96,57 +96,6 @@ const (
DefinedDeployments
)
// Bech32Prefix is the human-readable prefix for a Bech32 address.
type Bech32Prefix int
// Constants that define Bech32 address prefixes. Every network is assigned
// a unique prefix.
const (
// Unknown/Erroneous prefix
Unknown Bech32Prefix = iota
// Prefix for the main network.
DagCoin
// Prefix for the regression test network.
DagReg
// Prefix for the test network.
DagTest
// Prefix for the simulation network.
DagSim
)
// Map from strings to Bech32 address prefix constants for parsing purposes.
var stringsToBech32Prefixes = map[string]Bech32Prefix{
"dagcoin": DagCoin,
"dagreg": DagReg,
"dagtest": DagTest,
"dagsim": DagSim,
}
// ParsePrefix attempts to parse a Bech32 address prefix.
func ParsePrefix(prefixString string) (Bech32Prefix, error) {
prefix, ok := stringsToBech32Prefixes[prefixString]
if !ok {
return Unknown, fmt.Errorf("could not parse prefix %v", prefixString)
}
return prefix, nil
}
// Converts from Bech32 address prefixes to their string values
func (prefix Bech32Prefix) String() string {
for key, value := range stringsToBech32Prefixes {
if prefix == value {
return key
}
}
return ""
}
// Params defines a Bitcoin network by its parameters. These parameters may be
// used by Bitcoin applications to differentiate networks as well as addresses
// and keys for one network from those intended for use on another network.
@ -245,14 +194,13 @@ type Params struct {
RelayNonStdTxs bool
// Human-readable prefix for Bech32 encoded addresses
Prefix Bech32Prefix
Prefix util.Bech32Prefix
// Address encoding magics
PrivateKeyID byte // First byte of a WIF private key
// BIP32 hierarchical deterministic extended key magics
HDPrivateKeyID [4]byte
HDPublicKeyID [4]byte
HDKeyIDPair hdkeychain.HDKeyIDPair
// BIP44 coin type used in the hierarchical deterministic path for
// address generation.
@ -329,14 +277,13 @@ var MainNetParams = Params{
RelayNonStdTxs: false,
// Human-readable part for Bech32 encoded addresses
Prefix: DagCoin,
Prefix: util.Bech32PrefixDAGCoin,
// Address encoding magics
PrivateKeyID: 0x80, // starts with 5 (uncompressed) or K (compressed)
// BIP32 hierarchical deterministic extended key magics
HDPrivateKeyID: [4]byte{0x04, 0x88, 0xad, 0xe4}, // starts with xprv
HDPublicKeyID: [4]byte{0x04, 0x88, 0xb2, 0x1e}, // starts with xpub
HDKeyIDPair: hdkeychain.HDKeyPairMainNet,
// BIP44 coin type used in the hierarchical deterministic path for
// address generation.
@ -389,14 +336,13 @@ var RegressionNetParams = Params{
RelayNonStdTxs: true,
// Human-readable part for Bech32 encoded addresses
Prefix: DagReg,
Prefix: util.Bech32PrefixDAGReg,
// Address encoding magics
PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed)
// BIP32 hierarchical deterministic extended key magics
HDPrivateKeyID: [4]byte{0x04, 0x35, 0x83, 0x94}, // starts with tprv
HDPublicKeyID: [4]byte{0x04, 0x35, 0x87, 0xcf}, // starts with tpub
HDKeyIDPair: hdkeychain.HDKeyPairRegressionNet,
// BIP44 coin type used in the hierarchical deterministic path for
// address generation.
@ -466,14 +412,13 @@ var TestNet3Params = Params{
RelayNonStdTxs: true,
// Human-readable part for Bech32 encoded addresses
Prefix: DagTest,
Prefix: util.Bech32PrefixDAGTest,
// Address encoding magics
PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed)
// BIP32 hierarchical deterministic extended key magics
HDPrivateKeyID: [4]byte{0x04, 0x35, 0x83, 0x94}, // starts with tprv
HDPublicKeyID: [4]byte{0x04, 0x35, 0x87, 0xcf}, // starts with tpub
HDKeyIDPair: hdkeychain.HDKeyPairTestNet,
// BIP44 coin type used in the hierarchical deterministic path for
// address generation.
@ -531,11 +476,10 @@ var SimNetParams = Params{
PrivateKeyID: 0x64, // starts with 4 (uncompressed) or F (compressed)
// Human-readable part for Bech32 encoded addresses
Prefix: DagSim,
Prefix: util.Bech32PrefixDAGSim,
// BIP32 hierarchical deterministic extended key magics
HDPrivateKeyID: [4]byte{0x04, 0x20, 0xb9, 0x00}, // starts with sprv
HDPublicKeyID: [4]byte{0x04, 0x20, 0xbd, 0x3a}, // starts with spub
HDKeyIDPair: hdkeychain.HDKeyPairSimNet,
// BIP44 coin type used in the hierarchical deterministic path for
// address generation.
@ -547,16 +491,10 @@ var (
// network could not be set due to the network already being a standard
// network or previously-registered into this package.
ErrDuplicateNet = errors.New("duplicate Bitcoin network")
// ErrUnknownHDKeyID describes an error where the provided id which
// is intended to identify the network for a hierarchical deterministic
// private extended key is not registered.
ErrUnknownHDKeyID = errors.New("unknown hd private extended key bytes")
)
var (
registeredNets = make(map[wire.BitcoinNet]struct{})
hdPrivToPubKeyIDs = make(map[[4]byte][]byte)
registeredNets = make(map[wire.BitcoinNet]struct{})
)
// String returns the hostname of the DNS seed in human-readable form.
@ -578,7 +516,6 @@ func Register(params *Params) error {
return ErrDuplicateNet
}
registeredNets[params.Net] = struct{}{}
hdPrivToPubKeyIDs[params.HDPrivateKeyID] = params.HDPublicKeyID[:]
return nil
}
@ -591,24 +528,6 @@ func mustRegister(params *Params) {
}
}
// HDPrivateKeyToPublicKeyID accepts a private hierarchical deterministic
// extended key id and returns the associated public key id. When the provided
// id is not registered, the ErrUnknownHDKeyID error will be returned.
func HDPrivateKeyToPublicKeyID(id []byte) ([]byte, error) {
if len(id) != 4 {
return nil, ErrUnknownHDKeyID
}
var key [4]byte
copy(key[:], id)
pubBytes, ok := hdPrivToPubKeyIDs[key]
if !ok {
return nil, ErrUnknownHDKeyID
}
return pubBytes, nil
}
// newHashFromStr converts the passed big-endian hex string into a
// daghash.Hash. It only differs from the one available in daghash in that
// it panics on an error since it will only (and must only) be called with

View File

@ -34,57 +34,6 @@ func TestMustRegisterPanic(t *testing.T) {
mustRegister(&MainNetParams)
}
func TestParsePrefix(t *testing.T) {
tests := []struct {
prefixStr string
expectedPrefix Bech32Prefix
expectedError bool
}{
{"dagcoin", DagCoin, false},
{"dagreg", DagReg, false},
{"dagtest", DagTest, false},
{"dagsim", DagSim, false},
{"blabla", Unknown, true},
{"unknown", Unknown, true},
{"", Unknown, true},
}
for _, test := range tests {
result, err := ParsePrefix(test.prefixStr)
if (err != nil) != test.expectedError {
t.Errorf("TestParsePrefix: %s: expected error status: %t, but got %t",
test.prefixStr, test.expectedError, (err != nil))
}
if result != test.expectedPrefix {
t.Errorf("TestParsePrefix: %s: expected prefix: %d, but got %d",
test.prefixStr, test.expectedPrefix, result)
}
}
}
func TestPrefixToString(t *testing.T) {
tests := []struct {
prefix Bech32Prefix
expectedPrefixStr string
}{
{DagCoin, "dagcoin"},
{DagReg, "dagreg"},
{DagTest, "dagtest"},
{DagSim, "dagsim"},
{Unknown, ""},
}
for _, test := range tests {
result := test.prefix.String()
if result != test.expectedPrefixStr {
t.Errorf("TestPrefixToString: %s: expected string: %s, but got %s",
test.prefix, test.expectedPrefixStr, result)
}
}
}
func TestDNSSeedToString(t *testing.T) {
host := "test.dns.seed.com"
seed := DNSSeed{HasFiltering: false, Host: host}

View File

@ -2,6 +2,7 @@ package dagconfig_test
import (
"bytes"
"github.com/daglabs/btcd/util/hdkeychain"
"reflect"
"testing"
@ -12,10 +13,12 @@ import (
// network. This is necessary to test the registration of and
// lookup of encoding magics from the network.
var mockNetParams = Params{
Name: "mocknet",
Net: 1<<32 - 1,
HDPrivateKeyID: [4]byte{0x01, 0x02, 0x03, 0x04},
HDPublicKeyID: [4]byte{0x05, 0x06, 0x07, 0x08},
Name: "mocknet",
Net: 1<<32 - 1,
HDKeyIDPair: hdkeychain.HDKeyIDPair{
PrivateKeyID: [4]byte{0x01, 0x02, 0x03, 0x04},
PublicKeyID: [4]byte{0x05, 0x06, 0x07, 0x08},
},
}
func TestRegister(t *testing.T) {
@ -24,10 +27,6 @@ func TestRegister(t *testing.T) {
params *Params
err error
}
type prefixTest struct {
prefix string
valid bool
}
type hdTest struct {
priv []byte
want []byte
@ -65,36 +64,36 @@ func TestRegister(t *testing.T) {
},
hdMagics: []hdTest{
{
priv: MainNetParams.HDPrivateKeyID[:],
want: MainNetParams.HDPublicKeyID[:],
priv: MainNetParams.HDKeyIDPair.PrivateKeyID[:],
want: MainNetParams.HDKeyIDPair.PublicKeyID[:],
err: nil,
},
{
priv: TestNet3Params.HDPrivateKeyID[:],
want: TestNet3Params.HDPublicKeyID[:],
priv: TestNet3Params.HDKeyIDPair.PrivateKeyID[:],
want: TestNet3Params.HDKeyIDPair.PublicKeyID[:],
err: nil,
},
{
priv: RegressionNetParams.HDPrivateKeyID[:],
want: RegressionNetParams.HDPublicKeyID[:],
priv: RegressionNetParams.HDKeyIDPair.PrivateKeyID[:],
want: RegressionNetParams.HDKeyIDPair.PublicKeyID[:],
err: nil,
},
{
priv: SimNetParams.HDPrivateKeyID[:],
want: SimNetParams.HDPublicKeyID[:],
priv: SimNetParams.HDKeyIDPair.PrivateKeyID[:],
want: SimNetParams.HDKeyIDPair.PublicKeyID[:],
err: nil,
},
{
priv: mockNetParams.HDPrivateKeyID[:],
err: ErrUnknownHDKeyID,
priv: mockNetParams.HDKeyIDPair.PrivateKeyID[:],
err: hdkeychain.ErrUnknownHDKeyID,
},
{
priv: []byte{0xff, 0xff, 0xff, 0xff},
err: ErrUnknownHDKeyID,
err: hdkeychain.ErrUnknownHDKeyID,
},
{
priv: []byte{0xff},
err: ErrUnknownHDKeyID,
err: hdkeychain.ErrUnknownHDKeyID,
},
},
},
@ -109,8 +108,8 @@ func TestRegister(t *testing.T) {
},
hdMagics: []hdTest{
{
priv: mockNetParams.HDPrivateKeyID[:],
want: mockNetParams.HDPublicKeyID[:],
priv: mockNetParams.HDKeyIDPair.PrivateKeyID[:],
want: mockNetParams.HDKeyIDPair.PublicKeyID[:],
err: nil,
},
},
@ -146,37 +145,37 @@ func TestRegister(t *testing.T) {
},
hdMagics: []hdTest{
{
priv: MainNetParams.HDPrivateKeyID[:],
want: MainNetParams.HDPublicKeyID[:],
priv: MainNetParams.HDKeyIDPair.PrivateKeyID[:],
want: MainNetParams.HDKeyIDPair.PublicKeyID[:],
err: nil,
},
{
priv: TestNet3Params.HDPrivateKeyID[:],
want: TestNet3Params.HDPublicKeyID[:],
priv: TestNet3Params.HDKeyIDPair.PrivateKeyID[:],
want: TestNet3Params.HDKeyIDPair.PublicKeyID[:],
err: nil,
},
{
priv: RegressionNetParams.HDPrivateKeyID[:],
want: RegressionNetParams.HDPublicKeyID[:],
priv: RegressionNetParams.HDKeyIDPair.PrivateKeyID[:],
want: RegressionNetParams.HDKeyIDPair.PublicKeyID[:],
err: nil,
},
{
priv: SimNetParams.HDPrivateKeyID[:],
want: SimNetParams.HDPublicKeyID[:],
priv: SimNetParams.HDKeyIDPair.PrivateKeyID[:],
want: SimNetParams.HDKeyIDPair.PublicKeyID[:],
err: nil,
},
{
priv: mockNetParams.HDPrivateKeyID[:],
want: mockNetParams.HDPublicKeyID[:],
priv: mockNetParams.HDKeyIDPair.PrivateKeyID[:],
want: mockNetParams.HDKeyIDPair.PublicKeyID[:],
err: nil,
},
{
priv: []byte{0xff, 0xff, 0xff, 0xff},
err: ErrUnknownHDKeyID,
err: hdkeychain.ErrUnknownHDKeyID,
},
{
priv: []byte{0xff},
err: ErrUnknownHDKeyID,
err: hdkeychain.ErrUnknownHDKeyID,
},
},
},
@ -185,13 +184,17 @@ func TestRegister(t *testing.T) {
for _, test := range tests {
for _, regTest := range test.register {
err := Register(regTest.params)
// HDKeyIDPairs must be registered separately
hdkeychain.RegisterHDKeyIDPair(regTest.params.HDKeyIDPair)
if err != regTest.err {
t.Errorf("%s:%s: Registered network with unexpected error: got %v expected %v",
test.name, regTest.name, err, regTest.err)
}
}
for i, magTest := range test.hdMagics {
pubKey, err := HDPrivateKeyToPublicKeyID(magTest.priv[:])
pubKey, err := hdkeychain.HDPrivateKeyToPublicKeyID(magTest.priv[:])
if !reflect.DeepEqual(err, magTest.err) {
t.Errorf("%s: HD magic %d mismatched error: got %v expected %v ",
test.name, i, err, magTest.err)

View File

@ -118,7 +118,7 @@ func newMemWallet(net *dagconfig.Params, harnessID uint32) (*memWallet, error) {
copy(harnessHDSeed[:], hdSeed[:])
binary.BigEndian.PutUint32(harnessHDSeed[:daghash.HashSize], harnessID)
hdRoot, err := hdkeychain.NewMaster(harnessHDSeed[:], net)
hdRoot, err := hdkeychain.NewMaster(harnessHDSeed[:], net.HDKeyIDPair.PrivateKeyID)
if err != nil {
return nil, nil
}
@ -562,7 +562,7 @@ func (m *memWallet) ConfirmedBalance() util.Amount {
// keyToAddr maps the passed private to corresponding p2pkh address.
func keyToAddr(key *btcec.PrivateKey, net *dagconfig.Params) (util.Address, error) {
serializedKey := key.PubKey().SerializeCompressed()
pubKeyAddr, err := util.NewAddressPubKey(serializedKey, net)
pubKeyAddr, err := util.NewAddressPubKey(serializedKey, net.Prefix)
if err != nil {
return nil, err
}

View File

@ -257,7 +257,7 @@ func newPoolHarness(dagParams *dagconfig.Params, dbName string) (*poolHarness, [
// Generate associated pay-to-script-hash address and resulting payment
// script.
pubKeyBytes := signPub.SerializeCompressed()
payPubKeyAddr, err := util.NewAddressPubKey(pubKeyBytes, dagParams)
payPubKeyAddr, err := util.NewAddressPubKey(pubKeyBytes, dagParams.Prefix)
if err != nil {
return nil, nil, err
}

View File

@ -10,11 +10,10 @@ import (
"time"
"github.com/daglabs/btcd/btcec"
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/txscript"
"github.com/daglabs/btcd/wire"
"github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/wire"
)
// TestCalcMinRequiredTxRelayFee tests the calcMinRequiredTxRelayFee API.
@ -292,8 +291,7 @@ func TestCheckTransactionStandard(t *testing.T) {
Sequence: wire.MaxTxInSequenceNum,
}
addrHash := [20]byte{0x01}
addr, err := util.NewAddressPubKeyHash(addrHash[:],
&dagconfig.TestNet3Params)
addr, err := util.NewAddressPubKeyHash(addrHash[:], util.Bech32PrefixDAGTest)
if err != nil {
t.Fatalf("NewAddressPubKeyHash: unexpected error: %v", err)
}

View File

@ -183,5 +183,4 @@ var privKeyBytes, _ = hex.DecodeString("22a47fa09a223f2aa079edf85a7c2" +
var privKey, pubKey = btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes)
var pubKeyHash = util.Hash160(pubKey.SerializeCompressed())
var addr, err = util.NewAddressPubKeyHash(pubKeyHash,
&dagconfig.MainNetParams)
var addr, _ = util.NewAddressPubKeyHash(pubKeyHash, util.Bech32PrefixDAGCoin)

View File

@ -9,10 +9,9 @@ import (
"strconv"
"github.com/daglabs/btcd/btcjson"
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/wire"
"github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/wire"
)
// *****************************
@ -771,7 +770,7 @@ func (r FutureAddMultisigAddressResult) Receive() (util.Address, error) {
return nil, err
}
return util.DecodeAddress(addr, &dagconfig.MainNetParams)
return util.DecodeAddress(addr, util.Bech32PrefixDAGCoin)
}
// AddMultisigAddressAsync returns an instance of a type that can be used to get
@ -885,7 +884,7 @@ func (r FutureGetNewAddressResult) Receive() (util.Address, error) {
return nil, err
}
return util.DecodeAddress(addr, &dagconfig.MainNetParams)
return util.DecodeAddress(addr, util.Bech32PrefixDAGCoin)
}
// GetNewAddressAsync returns an instance of a type that can be used to get the
@ -923,7 +922,7 @@ func (r FutureGetRawChangeAddressResult) Receive() (util.Address, error) {
return nil, err
}
return util.DecodeAddress(addr, &dagconfig.MainNetParams)
return util.DecodeAddress(addr, util.Bech32PrefixDAGCoin)
}
// GetRawChangeAddressAsync returns an instance of a type that can be used to
@ -962,7 +961,7 @@ func (r FutureGetAccountAddressResult) Receive() (util.Address, error) {
return nil, err
}
return util.DecodeAddress(addr, &dagconfig.MainNetParams)
return util.DecodeAddress(addr, util.Bech32PrefixDAGCoin)
}
// GetAccountAddressAsync returns an instance of a type that can be used to get
@ -1068,7 +1067,7 @@ func (r FutureGetAddressesByAccountResult) Receive() ([]util.Address, error) {
addrs := make([]util.Address, 0, len(addrStrings))
for _, addrStr := range addrStrings {
addr, err := util.DecodeAddress(addrStr,
&dagconfig.MainNetParams)
util.Bech32PrefixDAGCoin)
if err != nil {
return nil, err
}

View File

@ -557,7 +557,7 @@ func handleCreateRawTransaction(s *Server, cmd interface{}, closeChan <-chan str
}
// Decode the provided address.
addr, err := util.DecodeAddress(encodedAddr, params)
addr, err := util.DecodeAddress(encodedAddr, params.Prefix)
if err != nil {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidAddressOrKey,
@ -577,7 +577,7 @@ func handleCreateRawTransaction(s *Server, cmd interface{}, closeChan <-chan str
Message: "Invalid address or key",
}
}
if !addr.IsForNet(params) {
if !addr.IsForPrefix(params.Prefix) {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidAddressOrKey,
Message: "Invalid address: " + encodedAddr +
@ -818,7 +818,7 @@ func handleDecodeScript(s *Server, cmd interface{}, closeChan <-chan struct{}) (
}
// Convert the script itself to a pay-to-script-hash address.
p2sh, err := util.NewAddressScriptHash(script, s.cfg.ChainParams)
p2sh, err := util.NewAddressScriptHash(script, s.cfg.ChainParams.Prefix)
if err != nil {
context := "Failed to convert script to pay-to-script-hash"
return nil, internalRPCError(err.Error(), context)
@ -2913,7 +2913,7 @@ func handleSearchRawTransactions(s *Server, cmd interface{}, closeChan <-chan st
// Attempt to decode the supplied address.
params := s.cfg.ChainParams
addr, err := util.DecodeAddress(c.Address, params)
addr, err := util.DecodeAddress(c.Address, params.Prefix)
if err != nil {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidAddressOrKey,
@ -3313,7 +3313,7 @@ func handleValidateAddress(s *Server, cmd interface{}, closeChan <-chan struct{}
c := cmd.(*btcjson.ValidateAddressCmd)
result := btcjson.ValidateAddressResult{}
addr, err := util.DecodeAddress(c.Address, s.cfg.ChainParams)
addr, err := util.DecodeAddress(c.Address, s.cfg.ChainParams.Prefix)
if err != nil {
// Return the default value (false) for IsValid.
return result, nil
@ -3385,7 +3385,7 @@ func handleVerifyMessage(s *Server, cmd interface{}, closeChan <-chan struct{})
// Decode the provided address.
params := s.cfg.ChainParams
addr, err := util.DecodeAddress(c.Address, params)
addr, err := util.DecodeAddress(c.Address, params.Prefix)
if err != nil {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidAddressOrKey,
@ -3431,7 +3431,7 @@ func handleVerifyMessage(s *Server, cmd interface{}, closeChan <-chan struct{})
} else {
serializedPK = pk.SerializeUncompressed()
}
address, err := util.NewAddressPubKey(serializedPK, params)
address, err := util.NewAddressPubKey(serializedPK, params.Prefix)
if err != nil {
// Again mirror Bitcoin Core behavior, which treats error in public key
// reconstruction as invalid signature.

View File

@ -28,8 +28,8 @@ import (
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/txscript"
"github.com/daglabs/btcd/wire"
"github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/wire"
)
const (
@ -330,7 +330,7 @@ func (f *wsClientFilter) addAddressStr(s string, params *dagconfig.Params) {
// If address can't be decoded, no point in saving it since it should also
// impossible to create the address from an inspected transaction output
// script.
a, err := util.DecodeAddress(s, params)
a, err := util.DecodeAddress(s, params.Prefix)
if err != nil {
return
}
@ -411,7 +411,7 @@ func (f *wsClientFilter) removeAddress(a util.Address) {
//
// NOTE: This extension was ported from github.com/decred/dcrd
func (f *wsClientFilter) removeAddressStr(s string, params *dagconfig.Params) {
a, err := util.DecodeAddress(s, params)
a, err := util.DecodeAddress(s, params.Prefix)
if err == nil {
f.removeAddress(a)
} else {
@ -1539,8 +1539,8 @@ out:
}
waiting = true
// This channel is notified when a notification has been sent
// across the network socket.
// This channel is notified when a notification has been sent
// across the network socket.
case <-ntfnSentChan:
// No longer waiting if there are no more messages in
// the pending messages queue.
@ -1948,7 +1948,7 @@ func handleStopNotifyReceived(wsc *wsClient, icmd interface{}) (interface{}, err
// properly, the function returns an error. Otherwise, nil is returned.
func checkAddressValidity(addrs []string, params *dagconfig.Params) error {
for _, addr := range addrs {
_, err := util.DecodeAddress(addr, params)
_, err := util.DecodeAddress(addr, params.Prefix)
if err != nil {
return &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidAddressOrKey,

View File

@ -12,8 +12,8 @@ import (
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/txscript"
"github.com/daglabs/btcd/wire"
"github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/wire"
)
// This example demonstrates creating a script which pays to a bitcoin address.
@ -25,7 +25,7 @@ func ExamplePayToAddrScript() {
// the address type. It is also required for the upcoming call to
// PayToAddrScript.
addressStr := "dagcoin:qqfgqp8l9l90zwetj84k2jcac2m8falvvy9uastr55"
address, err := util.DecodeAddress(addressStr, &dagconfig.MainNetParams)
address, err := util.DecodeAddress(addressStr, util.Bech32PrefixDAGCoin)
if err != nil {
fmt.Println(err)
return
@ -91,8 +91,7 @@ func ExampleSignTxOutput() {
}
privKey, pubKey := btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes)
pubKeyHash := util.Hash160(pubKey.SerializeCompressed())
addr, err := util.NewAddressPubKeyHash(pubKeyHash,
&dagconfig.MainNetParams)
addr, err := util.NewAddressPubKeyHash(pubKeyHash, util.Bech32PrefixDAGCoin)
if err != nil {
fmt.Println(err)
return

View File

@ -12,8 +12,8 @@ import (
"github.com/daglabs/btcd/btcec"
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/wire"
"github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/wire"
)
type addressToKey struct {
@ -152,7 +152,7 @@ func TestSignTxOutput(t *testing.T) {
pk := (*btcec.PublicKey)(&key.PublicKey).
SerializeUncompressed()
address, err := util.NewAddressPubKeyHash(
util.Hash160(pk), &dagconfig.TestNet3Params)
util.Hash160(pk), util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -189,7 +189,7 @@ func TestSignTxOutput(t *testing.T) {
pk := (*btcec.PublicKey)(&key.PublicKey).
SerializeUncompressed()
address, err := util.NewAddressPubKeyHash(
util.Hash160(pk), &dagconfig.TestNet3Params)
util.Hash160(pk), util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -250,7 +250,7 @@ func TestSignTxOutput(t *testing.T) {
pk := (*btcec.PublicKey)(&key.PublicKey).
SerializeCompressed()
address, err := util.NewAddressPubKeyHash(
util.Hash160(pk), &dagconfig.TestNet3Params)
util.Hash160(pk), util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -288,7 +288,7 @@ func TestSignTxOutput(t *testing.T) {
pk := (*btcec.PublicKey)(&key.PublicKey).
SerializeCompressed()
address, err := util.NewAddressPubKeyHash(
util.Hash160(pk), &dagconfig.TestNet3Params)
util.Hash160(pk), util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -348,7 +348,7 @@ func TestSignTxOutput(t *testing.T) {
pk := (*btcec.PublicKey)(&key.PublicKey).
SerializeUncompressed()
address, err := util.NewAddressPubKey(pk, &dagconfig.TestNet3Params)
address, err := util.NewAddressPubKey(pk, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -385,7 +385,7 @@ func TestSignTxOutput(t *testing.T) {
pk := (*btcec.PublicKey)(&key.PublicKey).
SerializeUncompressed()
address, err := util.NewAddressPubKey(pk, &dagconfig.TestNet3Params)
address, err := util.NewAddressPubKey(pk, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -445,7 +445,7 @@ func TestSignTxOutput(t *testing.T) {
pk := (*btcec.PublicKey)(&key.PublicKey).
SerializeCompressed()
address, err := util.NewAddressPubKey(pk, &dagconfig.TestNet3Params)
address, err := util.NewAddressPubKey(pk, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -482,7 +482,7 @@ func TestSignTxOutput(t *testing.T) {
pk := (*btcec.PublicKey)(&key.PublicKey).
SerializeCompressed()
address, err := util.NewAddressPubKey(pk, &dagconfig.TestNet3Params)
address, err := util.NewAddressPubKey(pk, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -543,7 +543,7 @@ func TestSignTxOutput(t *testing.T) {
pk := (*btcec.PublicKey)(&key.PublicKey).
SerializeUncompressed()
address, err := util.NewAddressPubKeyHash(
util.Hash160(pk), &dagconfig.TestNet3Params)
util.Hash160(pk), util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -558,7 +558,7 @@ func TestSignTxOutput(t *testing.T) {
}
scriptAddr, err := util.NewAddressScriptHash(
pkScript, &dagconfig.TestNet3Params)
pkScript, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
msg, err)
@ -599,7 +599,7 @@ func TestSignTxOutput(t *testing.T) {
pk := (*btcec.PublicKey)(&key.PublicKey).
SerializeUncompressed()
address, err := util.NewAddressPubKeyHash(
util.Hash160(pk), &dagconfig.TestNet3Params)
util.Hash160(pk), util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -614,7 +614,7 @@ func TestSignTxOutput(t *testing.T) {
}
scriptAddr, err := util.NewAddressScriptHash(
pkScript, &dagconfig.TestNet3Params)
pkScript, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
msg, err)
@ -681,7 +681,7 @@ func TestSignTxOutput(t *testing.T) {
pk := (*btcec.PublicKey)(&key.PublicKey).
SerializeCompressed()
address, err := util.NewAddressPubKeyHash(
util.Hash160(pk), &dagconfig.TestNet3Params)
util.Hash160(pk), util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -695,7 +695,7 @@ func TestSignTxOutput(t *testing.T) {
}
scriptAddr, err := util.NewAddressScriptHash(
pkScript, &dagconfig.TestNet3Params)
pkScript, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
msg, err)
@ -737,7 +737,7 @@ func TestSignTxOutput(t *testing.T) {
pk := (*btcec.PublicKey)(&key.PublicKey).
SerializeCompressed()
address, err := util.NewAddressPubKeyHash(
util.Hash160(pk), &dagconfig.TestNet3Params)
util.Hash160(pk), util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -751,7 +751,7 @@ func TestSignTxOutput(t *testing.T) {
}
scriptAddr, err := util.NewAddressScriptHash(
pkScript, &dagconfig.TestNet3Params)
pkScript, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
msg, err)
@ -817,7 +817,7 @@ func TestSignTxOutput(t *testing.T) {
pk := (*btcec.PublicKey)(&key.PublicKey).
SerializeUncompressed()
address, err := util.NewAddressPubKey(pk, &dagconfig.TestNet3Params)
address, err := util.NewAddressPubKey(pk, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -831,7 +831,7 @@ func TestSignTxOutput(t *testing.T) {
}
scriptAddr, err := util.NewAddressScriptHash(
pkScript, &dagconfig.TestNet3Params)
pkScript, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
msg, err)
@ -872,7 +872,7 @@ func TestSignTxOutput(t *testing.T) {
pk := (*btcec.PublicKey)(&key.PublicKey).
SerializeUncompressed()
address, err := util.NewAddressPubKey(pk, &dagconfig.TestNet3Params)
address, err := util.NewAddressPubKey(pk, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -886,7 +886,7 @@ func TestSignTxOutput(t *testing.T) {
}
scriptAddr, err := util.NewAddressScriptHash(
pkScript, &dagconfig.TestNet3Params)
pkScript, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
msg, err)
@ -951,7 +951,7 @@ func TestSignTxOutput(t *testing.T) {
pk := (*btcec.PublicKey)(&key.PublicKey).
SerializeCompressed()
address, err := util.NewAddressPubKey(pk, &dagconfig.TestNet3Params)
address, err := util.NewAddressPubKey(pk, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -965,7 +965,7 @@ func TestSignTxOutput(t *testing.T) {
}
scriptAddr, err := util.NewAddressScriptHash(
pkScript, &dagconfig.TestNet3Params)
pkScript, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
msg, err)
@ -1005,7 +1005,7 @@ func TestSignTxOutput(t *testing.T) {
pk := (*btcec.PublicKey)(&key.PublicKey).
SerializeCompressed()
address, err := util.NewAddressPubKey(pk, &dagconfig.TestNet3Params)
address, err := util.NewAddressPubKey(pk, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -1019,7 +1019,7 @@ func TestSignTxOutput(t *testing.T) {
}
scriptAddr, err := util.NewAddressScriptHash(
pkScript, &dagconfig.TestNet3Params)
pkScript, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
msg, err)
@ -1084,7 +1084,7 @@ func TestSignTxOutput(t *testing.T) {
pk1 := (*btcec.PublicKey)(&key1.PublicKey).
SerializeCompressed()
address1, err := util.NewAddressPubKey(pk1, &dagconfig.TestNet3Params)
address1, err := util.NewAddressPubKey(pk1, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -1100,7 +1100,7 @@ func TestSignTxOutput(t *testing.T) {
pk2 := (*btcec.PublicKey)(&key2.PublicKey).
SerializeCompressed()
address2, err := util.NewAddressPubKey(pk2, &dagconfig.TestNet3Params)
address2, err := util.NewAddressPubKey(pk2, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address 2 for %s: %v",
msg, err)
@ -1116,7 +1116,7 @@ func TestSignTxOutput(t *testing.T) {
}
scriptAddr, err := util.NewAddressScriptHash(
pkScript, &dagconfig.TestNet3Params)
pkScript, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
msg, err)
@ -1157,7 +1157,7 @@ func TestSignTxOutput(t *testing.T) {
pk1 := (*btcec.PublicKey)(&key1.PublicKey).
SerializeCompressed()
address1, err := util.NewAddressPubKey(pk1, &dagconfig.TestNet3Params)
address1, err := util.NewAddressPubKey(pk1, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -1173,7 +1173,7 @@ func TestSignTxOutput(t *testing.T) {
pk2 := (*btcec.PublicKey)(&key2.PublicKey).
SerializeCompressed()
address2, err := util.NewAddressPubKey(pk2, &dagconfig.TestNet3Params)
address2, err := util.NewAddressPubKey(pk2, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address 2 for %s: %v",
msg, err)
@ -1189,7 +1189,7 @@ func TestSignTxOutput(t *testing.T) {
}
scriptAddr, err := util.NewAddressScriptHash(
pkScript, &dagconfig.TestNet3Params)
pkScript, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
msg, err)
@ -1259,7 +1259,7 @@ func TestSignTxOutput(t *testing.T) {
pk1 := (*btcec.PublicKey)(&key1.PublicKey).
SerializeCompressed()
address1, err := util.NewAddressPubKey(pk1, &dagconfig.TestNet3Params)
address1, err := util.NewAddressPubKey(pk1, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -1275,7 +1275,7 @@ func TestSignTxOutput(t *testing.T) {
pk2 := (*btcec.PublicKey)(&key2.PublicKey).
SerializeCompressed()
address2, err := util.NewAddressPubKey(pk2, &dagconfig.TestNet3Params)
address2, err := util.NewAddressPubKey(pk2, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make address 2 for %s: %v",
msg, err)
@ -1291,7 +1291,7 @@ func TestSignTxOutput(t *testing.T) {
}
scriptAddr, err := util.NewAddressScriptHash(
pkScript, &dagconfig.TestNet3Params)
pkScript, util.Bech32PrefixDAGTest)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
msg, err)

View File

@ -430,7 +430,7 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *dagconfig.Params) (Scrip
// Skip the pubkey hash if it's invalid for some reason.
requiredSigs = 1
addr, err := util.NewAddressPubKeyHash(pops[2].data,
chainParams)
chainParams.Prefix)
if err == nil {
addrs = append(addrs, addr)
}
@ -441,7 +441,7 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *dagconfig.Params) (Scrip
// Therefore the pubkey is the first item on the stack.
// Skip the pubkey if it's invalid for some reason.
requiredSigs = 1
addr, err := util.NewAddressPubKey(pops[0].data, chainParams)
addr, err := util.NewAddressPubKey(pops[0].data, chainParams.Prefix)
if err == nil {
addrs = append(addrs, addr)
}
@ -453,7 +453,7 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *dagconfig.Params) (Scrip
// Skip the script hash if it's invalid for some reason.
requiredSigs = 1
addr, err := util.NewAddressScriptHashFromHash(pops[1].data,
chainParams)
chainParams.Prefix)
if err == nil {
addrs = append(addrs, addr)
}
@ -470,7 +470,7 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *dagconfig.Params) (Scrip
// Extract the public keys while skipping any that are invalid.
addrs = make([]util.Address, 0, numPubKeys)
for i := 0; i < numPubKeys; i++ {
addr, err := util.NewAddressPubKey(pops[i+1].data, chainParams)
addr, err := util.NewAddressPubKey(pops[i+1].data, chainParams.Prefix)
if err == nil {
addrs = append(addrs, addr)
}

View File

@ -32,7 +32,7 @@ func mustParseShortForm(script string) []byte {
// the tests as a helper since the only way it can fail is if there is an error
// in the test source code.
func newAddressPubKey(serializedPubKey []byte) util.Address {
addr, err := util.NewAddressPubKey(serializedPubKey, &dagconfig.MainNetParams)
addr, err := util.NewAddressPubKey(serializedPubKey, util.Bech32PrefixDAGCoin)
if err != nil {
panic("invalid public key in test source")
}
@ -45,7 +45,7 @@ func newAddressPubKey(serializedPubKey []byte) util.Address {
// as a helper since the only way it can fail is if there is an error in the
// test source code.
func newAddressPubKeyHash(pkHash []byte) util.Address {
addr, err := util.NewAddressPubKeyHash(pkHash, &dagconfig.MainNetParams)
addr, err := util.NewAddressPubKeyHash(pkHash, util.Bech32PrefixDAGCoin)
if err != nil {
panic("invalid public key hash in test source")
}
@ -59,7 +59,7 @@ func newAddressPubKeyHash(pkHash []byte) util.Address {
// test source code.
func newAddressScriptHash(scriptHash []byte) util.Address {
addr, err := util.NewAddressScriptHashFromHash(scriptHash,
&dagconfig.MainNetParams)
util.Bech32PrefixDAGCoin)
if err != nil {
panic("invalid script hash in test source")
}
@ -497,8 +497,8 @@ func (b *bogusAddress) ScriptAddress() []byte {
return nil
}
// IsForNet lies blatantly to satisfy the util.Address interface.
func (b *bogusAddress) IsForNet(chainParams *dagconfig.Params) bool {
// IsForPrefix lies blatantly to satisfy the util.Address interface.
func (b *bogusAddress) IsForPrefix(prefix util.Bech32Prefix) bool {
return true // why not?
}
@ -515,7 +515,7 @@ func TestPayToAddrScript(t *testing.T) {
// 1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gX
p2pkhMain, err := util.NewAddressPubKeyHash(hexToBytes("e34cce70c86"+
"373273efcc54ce7d2a491bb4a0e84"), &dagconfig.MainNetParams)
"373273efcc54ce7d2a491bb4a0e84"), util.Bech32PrefixDAGCoin)
if err != nil {
t.Fatalf("Unable to create public key hash address: %v", err)
}
@ -523,20 +523,20 @@ func TestPayToAddrScript(t *testing.T) {
// Taken from transaction:
// b0539a45de13b3e0403909b8bd1a555b8cbe45fd4e3f3fda76f3a5f52835c29d
p2shMain, _ := util.NewAddressScriptHashFromHash(hexToBytes("e8c300"+
"c87986efa84c37c0519929019ef86eb5b4"), &dagconfig.MainNetParams)
"c87986efa84c37c0519929019ef86eb5b4"), util.Bech32PrefixDAGCoin)
if err != nil {
t.Fatalf("Unable to create script hash address: %v", err)
}
// mainnet p2pk 13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg
p2pkCompressedMain, err := util.NewAddressPubKey(hexToBytes("02192d"+
"74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4"), &dagconfig.MainNetParams)
"74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4"), util.Bech32PrefixDAGCoin)
if err != nil {
t.Fatalf("Unable to create pubkey address (compressed): %v",
err)
}
p2pkCompressed2Main, err := util.NewAddressPubKey(hexToBytes("03b0b"+
"d634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65"), &dagconfig.MainNetParams)
"d634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65"), util.Bech32PrefixDAGCoin)
if err != nil {
t.Fatalf("Unable to create pubkey address (compressed 2): %v",
err)
@ -545,7 +545,7 @@ func TestPayToAddrScript(t *testing.T) {
p2pkUncompressedMain, err := util.NewAddressPubKey(hexToBytes("0411"+
"db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5"+
"cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b4"+
"12a3"), &dagconfig.MainNetParams)
"12a3"), util.Bech32PrefixDAGCoin)
if err != nil {
t.Fatalf("Unable to create pubkey address (uncompressed): %v",
err)
@ -632,13 +632,13 @@ func TestMultiSigScript(t *testing.T) {
// mainnet p2pk 13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg
p2pkCompressedMain, err := util.NewAddressPubKey(hexToBytes("02192d"+
"74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4"), &dagconfig.MainNetParams)
"74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4"), util.Bech32PrefixDAGCoin)
if err != nil {
t.Fatalf("Unable to create pubkey address (compressed): %v",
err)
}
p2pkCompressed2Main, err := util.NewAddressPubKey(hexToBytes("03b0b"+
"d634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65"), &dagconfig.MainNetParams)
"d634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65"), util.Bech32PrefixDAGCoin)
if err != nil {
t.Fatalf("Unable to create pubkey address (compressed 2): %v",
err)
@ -647,7 +647,7 @@ func TestMultiSigScript(t *testing.T) {
p2pkUncompressedMain, err := util.NewAddressPubKey(hexToBytes("0411"+
"db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5"+
"cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b4"+
"12a3"), &dagconfig.MainNetParams)
"12a3"), util.Bech32PrefixDAGCoin)
if err != nil {
t.Fatalf("Unable to create pubkey address (uncompressed): %v",
err)

View File

@ -8,9 +8,7 @@ import (
"encoding/hex"
"errors"
"fmt"
"github.com/daglabs/btcd/btcec"
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/util/bech32"
"golang.org/x/crypto/ripemd160"
)
@ -35,11 +33,62 @@ const (
scriptHashAddrID = 0x08
)
// Bech32Prefix is the human-readable prefix for a Bech32 address.
type Bech32Prefix int
// Constants that define Bech32 address prefixes. Every network is assigned
// a unique prefix.
const (
// Unknown/Erroneous prefix
Bech32PrefixUnknown Bech32Prefix = iota
// Prefix for the main network.
Bech32PrefixDAGCoin
// Prefix for the regression test network.
Bech32PrefixDAGReg
// Prefix for the test network.
Bech32PrefixDAGTest
// Prefix for the simulation network.
Bech32PrefixDAGSim
)
// Map from strings to Bech32 address prefix constants for parsing purposes.
var stringsToBech32Prefixes = map[string]Bech32Prefix{
"dagcoin": Bech32PrefixDAGCoin,
"dagreg": Bech32PrefixDAGReg,
"dagtest": Bech32PrefixDAGTest,
"dagsim": Bech32PrefixDAGSim,
}
// ParsePrefix attempts to parse a Bech32 address prefix.
func ParsePrefix(prefixString string) (Bech32Prefix, error) {
prefix, ok := stringsToBech32Prefixes[prefixString]
if !ok {
return Bech32PrefixUnknown, fmt.Errorf("could not parse prefix %v", prefixString)
}
return prefix, nil
}
// Converts from Bech32 address prefixes to their string values
func (prefix Bech32Prefix) String() string {
for key, value := range stringsToBech32Prefixes {
if prefix == value {
return key
}
}
return ""
}
// encodeAddress returns a human-readable payment address given a network prefix
// and a ripemd160 hash 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(prefix dagconfig.Bech32Prefix, hash160 []byte, version byte) string {
func encodeAddress(prefix Bech32Prefix, hash160 []byte, version byte) string {
return bech32.Encode(prefix.String(), hash160[:ripemd160.Size], version)
}
@ -68,9 +117,9 @@ type Address interface {
// when inserting the address into a txout's script.
ScriptAddress() []byte
// IsForNet returns whether or not the address is associated with the
// IsForPrefix returns whether or not the address is associated with the
// passed bitcoin network.
IsForNet(*dagconfig.Params) bool
IsForPrefix(prefix Bech32Prefix) bool
}
// DecodeAddress decodes the string encoding of an address and returns
@ -79,17 +128,17 @@ type Address interface {
// The bitcoin network 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 *dagconfig.Params) (Address, error) {
func DecodeAddress(addr string, defaultPrefix Bech32Prefix) (Address, error) {
prefixString, decoded, version, err := bech32.Decode(addr)
if err != nil {
return nil, fmt.Errorf("decoded address is of unknown format: %v", err)
}
prefix, err := dagconfig.ParsePrefix(prefixString)
prefix, err := ParsePrefix(prefixString)
if err != nil {
return nil, fmt.Errorf("decoded address's prefix could not be parsed: %v", err)
}
if defaultNet.Prefix != prefix {
if defaultPrefix != prefix {
return nil, fmt.Errorf("decoded address is of wrong network: %v", err)
}
@ -98,9 +147,9 @@ func DecodeAddress(addr string, defaultNet *dagconfig.Params) (Address, error) {
case ripemd160.Size: // P2PKH or P2SH
switch version {
case pubKeyHashAddrID:
return newAddressPubKeyHash(defaultNet.Prefix, decoded)
return newAddressPubKeyHash(defaultPrefix, decoded)
case scriptHashAddrID:
return newAddressScriptHashFromHash(defaultNet.Prefix, decoded)
return newAddressScriptHashFromHash(defaultPrefix, decoded)
default:
return nil, ErrUnknownAddressType
}
@ -112,14 +161,14 @@ func DecodeAddress(addr string, defaultNet *dagconfig.Params) (Address, error) {
// AddressPubKeyHash is an Address for a pay-to-pubkey-hash (P2PKH)
// transaction.
type AddressPubKeyHash struct {
prefix dagconfig.Bech32Prefix
prefix Bech32Prefix
hash [ripemd160.Size]byte
}
// NewAddressPubKeyHash returns a new AddressPubKeyHash. pkHash mustbe 20
// bytes.
func NewAddressPubKeyHash(pkHash []byte, net *dagconfig.Params) (*AddressPubKeyHash, error) {
return newAddressPubKeyHash(net.Prefix, pkHash)
func NewAddressPubKeyHash(pkHash []byte, prefix Bech32Prefix) (*AddressPubKeyHash, error) {
return newAddressPubKeyHash(prefix, pkHash)
}
// newAddressPubKeyHash is the internal API to create a pubkey hash address
@ -127,7 +176,7 @@ func NewAddressPubKeyHash(pkHash []byte, net *dagconfig.Params) (*AddressPubKeyH
// 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(prefix dagconfig.Bech32Prefix, pkHash []byte) (*AddressPubKeyHash, error) {
func newAddressPubKeyHash(prefix Bech32Prefix, pkHash []byte) (*AddressPubKeyHash, error) {
// Check for a valid pubkey hash length.
if len(pkHash) != ripemd160.Size {
return nil, errors.New("pkHash must be 20 bytes")
@ -150,10 +199,10 @@ func (a *AddressPubKeyHash) ScriptAddress() []byte {
return a.hash[:]
}
// IsForNet returns whether or not the pay-to-pubkey-hash address is associated
// IsForPrefix returns whether or not the pay-to-pubkey-hash address is associated
// with the passed bitcoin network.
func (a *AddressPubKeyHash) IsForNet(net *dagconfig.Params) bool {
return a.prefix == net.Prefix
func (a *AddressPubKeyHash) IsForPrefix(prefix Bech32Prefix) bool {
return a.prefix == prefix
}
// String returns a human-readable string for the pay-to-pubkey-hash address.
@ -173,20 +222,20 @@ func (a *AddressPubKeyHash) Hash160() *[ripemd160.Size]byte {
// AddressScriptHash is an Address for a pay-to-script-hash (P2SH)
// transaction.
type AddressScriptHash struct {
prefix dagconfig.Bech32Prefix
prefix Bech32Prefix
hash [ripemd160.Size]byte
}
// NewAddressScriptHash returns a new AddressScriptHash.
func NewAddressScriptHash(serializedScript []byte, net *dagconfig.Params) (*AddressScriptHash, error) {
func NewAddressScriptHash(serializedScript []byte, prefix Bech32Prefix) (*AddressScriptHash, error) {
scriptHash := Hash160(serializedScript)
return newAddressScriptHashFromHash(net.Prefix, scriptHash)
return newAddressScriptHashFromHash(prefix, scriptHash)
}
// NewAddressScriptHashFromHash returns a new AddressScriptHash. scriptHash
// must be 20 bytes.
func NewAddressScriptHashFromHash(scriptHash []byte, net *dagconfig.Params) (*AddressScriptHash, error) {
return newAddressScriptHashFromHash(net.Prefix, scriptHash)
func NewAddressScriptHashFromHash(scriptHash []byte, prefix Bech32Prefix) (*AddressScriptHash, error) {
return newAddressScriptHashFromHash(prefix, scriptHash)
}
// newAddressScriptHashFromHash is the internal API to create a script hash
@ -194,7 +243,7 @@ func NewAddressScriptHashFromHash(scriptHash []byte, net *dagconfig.Params) (*Ad
// 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(prefix dagconfig.Bech32Prefix, scriptHash []byte) (*AddressScriptHash, error) {
func newAddressScriptHashFromHash(prefix Bech32Prefix, scriptHash []byte) (*AddressScriptHash, error) {
// Check for a valid script hash length.
if len(scriptHash) != ripemd160.Size {
return nil, errors.New("scriptHash must be 20 bytes")
@ -217,10 +266,10 @@ func (a *AddressScriptHash) ScriptAddress() []byte {
return a.hash[:]
}
// IsForNet returns whether or not the pay-to-script-hash address is associated
// IsForPrefix returns whether or not the pay-to-script-hash address is associated
// with the passed bitcoin network.
func (a *AddressScriptHash) IsForNet(net *dagconfig.Params) bool {
return a.prefix == net.Prefix
func (a *AddressScriptHash) IsForPrefix(prefix Bech32Prefix) bool {
return a.prefix == prefix
}
// String returns a human-readable string for the pay-to-script-hash address.
@ -256,7 +305,7 @@ const (
// AddressPubKey is an Address for a pay-to-pubkey transaction.
type AddressPubKey struct {
prefix dagconfig.Bech32Prefix
prefix Bech32Prefix
pubKeyFormat PubKeyFormat
pubKey *btcec.PublicKey
pubKeyHashID byte
@ -265,7 +314,7 @@ type AddressPubKey struct {
// 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 *dagconfig.Params) (*AddressPubKey, error) {
func NewAddressPubKey(serializedPubKey []byte, prefix Bech32Prefix) (*AddressPubKey, error) {
pubKey, err := btcec.ParsePubKey(serializedPubKey, btcec.S256())
if err != nil {
return nil, err
@ -287,7 +336,7 @@ func NewAddressPubKey(serializedPubKey []byte, net *dagconfig.Params) (*AddressP
pubKeyFormat: pkFormat,
pubKey: pubKey,
pubKeyHashID: pubKeyHashAddrID,
prefix: net.Prefix,
prefix: prefix,
}, nil
}
@ -327,10 +376,10 @@ func (a *AddressPubKey) ScriptAddress() []byte {
return a.serialize()
}
// IsForNet returns whether or not the pay-to-pubkey address is associated
// IsForPrefix returns whether or not the pay-to-pubkey address is associated
// with the passed bitcoin network.
func (a *AddressPubKey) IsForNet(net *dagconfig.Params) bool {
return a.prefix == net.Prefix
func (a *AddressPubKey) IsForPrefix(prefix Bech32Prefix) bool {
return a.prefix == prefix
}
// String returns the hex-encoded human-readable string for the pay-to-pubkey

View File

@ -12,7 +12,6 @@ import (
"strings"
"testing"
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/util"
"golang.org/x/crypto/ripemd160"
)
@ -25,7 +24,7 @@ func TestAddresses(t *testing.T) {
valid bool
result util.Address
f func() (util.Address, error)
net *dagconfig.Params
prefix util.Bech32Prefix
}{
// Positive P2PKH tests.
{
@ -34,7 +33,7 @@ func TestAddresses(t *testing.T) {
encoded: "dagcoin:qr35ennsep3hxfe7lnz5ee7j5jgmkjswss74as46gy",
valid: true,
result: util.TstAddressPubKeyHash(
dagconfig.DagCoin,
util.Bech32PrefixDAGCoin,
[ripemd160.Size]byte{
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
0xc5, 0x4c, 0xe7, 0xd2, 0xa4, 0x91, 0xbb, 0x4a, 0x0e, 0x84}),
@ -42,9 +41,9 @@ func TestAddresses(t *testing.T) {
pkHash := []byte{
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
0xc5, 0x4c, 0xe7, 0xd2, 0xa4, 0x91, 0xbb, 0x4a, 0x0e, 0x84}
return util.NewAddressPubKeyHash(pkHash, &dagconfig.MainNetParams)
return util.NewAddressPubKeyHash(pkHash, util.Bech32PrefixDAGCoin)
},
net: &dagconfig.MainNetParams,
prefix: util.Bech32PrefixDAGCoin,
},
{
name: "mainnet p2pkh 2",
@ -52,7 +51,7 @@ func TestAddresses(t *testing.T) {
encoded: "dagcoin:qq80qvqs0lfxuzmt7sz3909ze6camq9d4gwzqeljga",
valid: true,
result: util.TstAddressPubKeyHash(
dagconfig.DagCoin,
util.Bech32PrefixDAGCoin,
[ripemd160.Size]byte{
0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, 0xf4,
0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad, 0xaa}),
@ -60,9 +59,9 @@ func TestAddresses(t *testing.T) {
pkHash := []byte{
0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, 0xf4,
0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad, 0xaa}
return util.NewAddressPubKeyHash(pkHash, &dagconfig.MainNetParams)
return util.NewAddressPubKeyHash(pkHash, util.Bech32PrefixDAGCoin)
},
net: &dagconfig.MainNetParams,
prefix: util.Bech32PrefixDAGCoin,
},
{
name: "testnet p2pkh",
@ -70,7 +69,7 @@ func TestAddresses(t *testing.T) {
encoded: "dagtest:qputx94qseratdmjs0j395mq8u03er0x3ucluj5qam",
valid: true,
result: util.TstAddressPubKeyHash(
dagconfig.DagTest,
util.Bech32PrefixDAGTest,
[ripemd160.Size]byte{
0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83,
0xe5, 0x12, 0xd3, 0x60, 0x3f, 0x1f, 0x1c, 0x8d, 0xe6, 0x8f}),
@ -78,9 +77,9 @@ func TestAddresses(t *testing.T) {
pkHash := []byte{
0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83,
0xe5, 0x12, 0xd3, 0x60, 0x3f, 0x1f, 0x1c, 0x8d, 0xe6, 0x8f}
return util.NewAddressPubKeyHash(pkHash, &dagconfig.TestNet3Params)
return util.NewAddressPubKeyHash(pkHash, util.Bech32PrefixDAGTest)
},
net: &dagconfig.TestNet3Params,
prefix: util.Bech32PrefixDAGTest,
},
// Negative P2PKH tests.
@ -93,15 +92,15 @@ 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 util.NewAddressPubKeyHash(pkHash, &dagconfig.MainNetParams)
return util.NewAddressPubKeyHash(pkHash, util.Bech32PrefixDAGCoin)
},
net: &dagconfig.MainNetParams,
prefix: util.Bech32PrefixDAGCoin,
},
{
name: "p2pkh bad checksum",
addr: "dagcoin:qr35ennsep3hxfe7lnz5ee7j5jgmkjswss74as46gx",
valid: false,
net: &dagconfig.MainNetParams,
name: "p2pkh bad checksum",
addr: "dagcoin:qr35ennsep3hxfe7lnz5ee7j5jgmkjswss74as46gx",
valid: false,
prefix: util.Bech32PrefixDAGCoin,
},
// Positive P2SH tests.
@ -114,7 +113,7 @@ func TestAddresses(t *testing.T) {
encoded: "dagcoin:pruptvpkmxamee0f72sq40gm70wfr624zq8mc2ujcn",
valid: true,
result: util.TstAddressScriptHash(
dagconfig.DagCoin,
util.Bech32PrefixDAGCoin,
[ripemd160.Size]byte{
0xf8, 0x15, 0xb0, 0x36, 0xd9, 0xbb, 0xbc, 0xe5, 0xe9, 0xf2,
0xa0, 0x0a, 0xbd, 0x1b, 0xf3, 0xdc, 0x91, 0xe9, 0x55, 0x10}),
@ -141,9 +140,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 util.NewAddressScriptHash(script, &dagconfig.MainNetParams)
return util.NewAddressScriptHash(script, util.Bech32PrefixDAGCoin)
},
net: &dagconfig.MainNetParams,
prefix: util.Bech32PrefixDAGCoin,
},
{
// Taken from transactions:
@ -154,7 +153,7 @@ func TestAddresses(t *testing.T) {
encoded: "dagcoin:pr5vxqxg0xrwl2zvxlq9rxffqx00sm44ksj47shjr6",
valid: true,
result: util.TstAddressScriptHash(
dagconfig.DagCoin,
util.Bech32PrefixDAGCoin,
[ripemd160.Size]byte{
0xe8, 0xc3, 0x00, 0xc8, 0x79, 0x86, 0xef, 0xa8, 0x4c, 0x37,
0xc0, 0x51, 0x99, 0x29, 0x01, 0x9e, 0xf8, 0x6e, 0xb5, 0xb4}),
@ -162,9 +161,9 @@ func TestAddresses(t *testing.T) {
hash := []byte{
0xe8, 0xc3, 0x00, 0xc8, 0x79, 0x86, 0xef, 0xa8, 0x4c, 0x37,
0xc0, 0x51, 0x99, 0x29, 0x01, 0x9e, 0xf8, 0x6e, 0xb5, 0xb4}
return util.NewAddressScriptHashFromHash(hash, &dagconfig.MainNetParams)
return util.NewAddressScriptHashFromHash(hash, util.Bech32PrefixDAGCoin)
},
net: &dagconfig.MainNetParams,
prefix: util.Bech32PrefixDAGCoin,
},
{
// Taken from bitcoind base58_keys_valid.
@ -173,7 +172,7 @@ func TestAddresses(t *testing.T) {
encoded: "dagtest:przhjdpv93xfygpqtckdc2zkzuzqeyj2pg6ghunlhx",
valid: true,
result: util.TstAddressScriptHash(
dagconfig.DagTest,
util.Bech32PrefixDAGTest,
[ripemd160.Size]byte{
0xc5, 0x79, 0x34, 0x2c, 0x2c, 0x4c, 0x92, 0x20, 0x20, 0x5e,
0x2c, 0xdc, 0x28, 0x56, 0x17, 0x04, 0x0c, 0x92, 0x4a, 0x0a}),
@ -181,9 +180,9 @@ func TestAddresses(t *testing.T) {
hash := []byte{
0xc5, 0x79, 0x34, 0x2c, 0x2c, 0x4c, 0x92, 0x20, 0x20, 0x5e,
0x2c, 0xdc, 0x28, 0x56, 0x17, 0x04, 0x0c, 0x92, 0x4a, 0x0a}
return util.NewAddressScriptHashFromHash(hash, &dagconfig.TestNet3Params)
return util.NewAddressScriptHashFromHash(hash, util.Bech32PrefixDAGTest)
},
net: &dagconfig.TestNet3Params,
prefix: util.Bech32PrefixDAGTest,
},
// Negative P2SH tests.
@ -196,15 +195,15 @@ 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 util.NewAddressScriptHashFromHash(hash, &dagconfig.MainNetParams)
return util.NewAddressScriptHashFromHash(hash, util.Bech32PrefixDAGCoin)
},
net: &dagconfig.MainNetParams,
prefix: util.Bech32PrefixDAGCoin,
},
}
for _, test := range tests {
// Decode addr and compare error against valid.
decoded, err := util.DecodeAddress(test.addr, test.net)
decoded, err := util.DecodeAddress(test.addr, test.prefix)
if (err == nil) != test.valid {
t.Errorf("%v: decoding test failed: %v", test.name, err)
return
@ -270,7 +269,7 @@ func TestAddresses(t *testing.T) {
}
// Ensure the address is for the expected network.
if !decoded.IsForNet(test.net) {
if !decoded.IsForPrefix(test.prefix) {
t.Errorf("%v: calculated network does not match expected",
test.name)
return
@ -310,33 +309,33 @@ func TestAddresses(t *testing.T) {
func TestDecodeAddressErrorConditions(t *testing.T) {
tests := []struct {
address string
prefix dagconfig.Bech32Prefix
prefix util.Bech32Prefix
errorMessage string
}{
{
"bitcoincash:qpzry9x8gf2tvdw0s3jn54khce6mua7lcw20ayyn",
dagconfig.Unknown,
util.Bech32PrefixUnknown,
"decoded address's prefix could not be parsed",
},
{
"dagreg:qpm2qsznhks23z7629mms6s4cwef74vcwvtmvqeszh",
dagconfig.DagTest,
util.Bech32PrefixDAGTest,
"decoded address is of wrong network",
},
{
"dagreg:raskzctpv9skzctpv9skzctpv9skzctpvyd070wnqg",
dagconfig.DagReg,
util.Bech32PrefixDAGReg,
"unknown address type",
},
{
"dagreg:raskzcg5egs6nnj",
dagconfig.DagReg,
util.Bech32PrefixDAGReg,
"decoded address is of unknown size",
},
}
for _, test := range tests {
_, err := util.DecodeAddress(test.address, &dagconfig.Params{Prefix: test.prefix})
_, err := util.DecodeAddress(test.address, test.prefix)
if err == nil {
t.Errorf("decodeAddress unexpectedly succeeded")
} else if !strings.Contains(err.Error(), test.errorMessage) {
@ -345,3 +344,54 @@ func TestDecodeAddressErrorConditions(t *testing.T) {
}
}
}
func TestParsePrefix(t *testing.T) {
tests := []struct {
prefixStr string
expectedPrefix util.Bech32Prefix
expectedError bool
}{
{"dagcoin", util.Bech32PrefixDAGCoin, false},
{"dagreg", util.Bech32PrefixDAGReg, false},
{"dagtest", util.Bech32PrefixDAGTest, false},
{"dagsim", util.Bech32PrefixDAGSim, false},
{"blabla", util.Bech32PrefixUnknown, true},
{"unknown", util.Bech32PrefixUnknown, true},
{"", util.Bech32PrefixUnknown, true},
}
for _, test := range tests {
result, err := util.ParsePrefix(test.prefixStr)
if (err != nil) != test.expectedError {
t.Errorf("TestParsePrefix: %s: expected error status: %t, but got %t",
test.prefixStr, test.expectedError, err != nil)
}
if result != test.expectedPrefix {
t.Errorf("TestParsePrefix: %s: expected prefix: %d, but got %d",
test.prefixStr, test.expectedPrefix, result)
}
}
}
func TestPrefixToString(t *testing.T) {
tests := []struct {
prefix util.Bech32Prefix
expectedPrefixStr string
}{
{util.Bech32PrefixDAGCoin, "dagcoin"},
{util.Bech32PrefixDAGReg, "dagreg"},
{util.Bech32PrefixDAGTest, "dagtest"},
{util.Bech32PrefixDAGSim, "dagsim"},
{util.Bech32PrefixUnknown, ""},
}
for _, test := range tests {
result := test.prefix.String()
if result != test.expectedPrefixStr {
t.Errorf("TestPrefixToString: %s: expected string: %s, but got %s",
test.prefix, test.expectedPrefixStr, result)
}
}
}

View File

@ -9,19 +9,15 @@ import (
"encoding/hex"
"testing"
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/txscript"
"github.com/daglabs/btcd/wire"
"github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/util/gcs/builder"
"github.com/daglabs/btcd/txscript"
"github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/util/gcs"
"github.com/daglabs/btcd/util/gcs/builder"
"github.com/daglabs/btcd/wire"
)
var (
// No need to allocate an err variable in every test
err error
// List of values for building a filter
contents = [][]byte{
[]byte("Alex"),
@ -66,7 +62,7 @@ func TestUseBlockHash(t *testing.T) {
}
// util.Address
addr, err := util.DecodeAddress(testAddr, &dagconfig.MainNetParams)
addr, err := util.DecodeAddress(testAddr, util.Bech32PrefixDAGCoin)
if err != nil {
t.Fatalf("Address decode failed: %s", err.Error())
}

View File

@ -6,8 +6,8 @@ package hdkeychain_test
import (
"fmt"
"github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/util/hdkeychain"
)
@ -22,7 +22,7 @@ func ExampleNewMaster() {
}
// Generate a new master node using the seed.
key, err := hdkeychain.NewMaster(seed, &dagconfig.MainNetParams)
key, err := hdkeychain.NewMaster(seed, hdkeychain.HDKeyPairMainNet.PrivateKeyID)
if err != nil {
fmt.Println(err)
return
@ -118,12 +118,12 @@ func Example_defaultWalletLayout() {
// Get and show the address associated with the extended keys for the
// main bitcoin network.
acct0ExtAddr, err := acct0Ext10.Address(&dagconfig.MainNetParams)
acct0ExtAddr, err := acct0Ext10.Address(util.Bech32PrefixDAGCoin)
if err != nil {
fmt.Println(err)
return
}
acct0IntAddr, err := acct0Int0.Address(&dagconfig.MainNetParams)
acct0IntAddr, err := acct0Int0.Address(util.Bech32PrefixDAGCoin)
if err != nil {
fmt.Println(err)
return

View File

@ -19,10 +19,9 @@ import (
"math/big"
"github.com/daglabs/btcd/btcec"
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/util/base58"
"github.com/daglabs/btcd/dagconfig/daghash"
)
const (
@ -96,12 +95,19 @@ var (
// key is not the expected length.
ErrInvalidKeyLen = errors.New("the provided serialized extended key " +
"length is invalid")
// ErrUnknownHDKeyID describes an error where the provided id which
// is intended to identify the network for a hierarchical deterministic
// private extended key is not registered.
ErrUnknownHDKeyID = errors.New("unknown hd private extended key bytes")
)
// masterKey is the master key used along with a random seed used to generate
// the master node in the hierarchical tree.
var masterKey = []byte("Bitcoin seed")
var hdPrivToPubKeyIDs = make(map[[4]byte][]byte)
// ExtendedKey houses all the information needed to support a hierarchical
// deterministic extended key. See the package overview documentation for
// more details on how to use extended keys.
@ -344,7 +350,7 @@ func (k *ExtendedKey) Neuter() (*ExtendedKey, error) {
}
// Get the associated public extended key version bytes.
version, err := dagconfig.HDPrivateKeyToPublicKeyID(k.version)
version, err := HDPrivateKeyToPublicKeyID(k.version)
if err != nil {
return nil, err
}
@ -357,6 +363,52 @@ func (k *ExtendedKey) Neuter() (*ExtendedKey, error) {
k.depth, k.childNum, false), nil
}
type HDKeyIDPair struct {
PrivateKeyID [4]byte
PublicKeyID [4]byte
}
var (
HDKeyPairMainNet = HDKeyIDPair{
PrivateKeyID: [4]byte{0x04, 0x88, 0xad, 0xe4}, // starts with xprv
PublicKeyID: [4]byte{0x04, 0x88, 0xb2, 0x1e}, // starts with xpub
}
HDKeyPairTestNet = HDKeyIDPair{
PrivateKeyID: [4]byte{0x04, 0x35, 0x83, 0x94}, // starts with tprv
PublicKeyID: [4]byte{0x04, 0x35, 0x87, 0xcf}, // starts with tpub
}
HDKeyPairRegressionNet = HDKeyIDPair{
PrivateKeyID: [4]byte{0x04, 0x35, 0x83, 0x94}, // starts with tprv
PublicKeyID: [4]byte{0x04, 0x35, 0x87, 0xcf}, // starts with tpub
}
HDKeyPairSimNet = HDKeyIDPair{
PrivateKeyID: [4]byte{0x04, 0x20, 0xb9, 0x00}, // starts with sprv
PublicKeyID: [4]byte{0x04, 0x20, 0xbd, 0x3a}, // starts with spub
}
)
func RegisterHDKeyIDPair(hdKeyIDPair HDKeyIDPair) {
hdPrivToPubKeyIDs[hdKeyIDPair.PrivateKeyID] = hdKeyIDPair.PublicKeyID[:]
}
// HDPrivateKeyToPublicKeyID accepts a private hierarchical deterministic
// extended key id and returns the associated public key id. When the provided
// id is not registered, the ErrUnknownHDKeyID error will be returned.
func HDPrivateKeyToPublicKeyID(id []byte) ([]byte, error) {
if len(id) != 4 {
return nil, ErrUnknownHDKeyID
}
var key [4]byte
copy(key[:], id)
pubBytes, ok := hdPrivToPubKeyIDs[key]
if !ok {
return nil, ErrUnknownHDKeyID
}
return pubBytes, nil
}
// ECPubKey converts the extended key to a btcec public key and returns it.
func (k *ExtendedKey) ECPubKey() (*btcec.PublicKey, error) {
return btcec.ParsePubKey(k.pubKeyBytes(), btcec.S256())
@ -377,9 +429,9 @@ func (k *ExtendedKey) ECPrivKey() (*btcec.PrivateKey, error) {
// Address converts the extended key to a standard bitcoin pay-to-pubkey-hash
// address for the passed network.
func (k *ExtendedKey) Address(net *dagconfig.Params) (*util.AddressPubKeyHash, error) {
func (k *ExtendedKey) Address(prefix util.Bech32Prefix) (*util.AddressPubKeyHash, error) {
pkHash := util.Hash160(k.pubKeyBytes())
return util.NewAddressPubKeyHash(pkHash, net)
return util.NewAddressPubKeyHash(pkHash, prefix)
}
// paddedAppend appends the src byte slice to dst, returning the new slice.
@ -423,19 +475,19 @@ func (k *ExtendedKey) String() string {
}
// IsForNet returns whether or not the extended key is associated with the
// passed bitcoin network.
func (k *ExtendedKey) IsForNet(net *dagconfig.Params) bool {
return bytes.Equal(k.version, net.HDPrivateKeyID[:]) ||
bytes.Equal(k.version, net.HDPublicKeyID[:])
// passed network keyIDs.
func (k *ExtendedKey) IsForNet(hdKeyIDPair HDKeyIDPair) bool {
return bytes.Equal(k.version, hdKeyIDPair.PrivateKeyID[:]) ||
bytes.Equal(k.version, hdKeyIDPair.PublicKeyID[:])
}
// SetNet associates the extended key, and any child keys yet to be derived from
// it, with the passed network.
func (k *ExtendedKey) SetNet(net *dagconfig.Params) {
// it, with the passed key IDs.
func (k *ExtendedKey) SetNet(hdKeyIDPair HDKeyIDPair) {
if k.isPrivate {
k.version = net.HDPrivateKeyID[:]
k.version = hdKeyIDPair.PrivateKeyID[:]
} else {
k.version = net.HDPublicKeyID[:]
k.version = hdKeyIDPair.PublicKeyID[:]
}
}
@ -472,7 +524,7 @@ func (k *ExtendedKey) Zero() {
// will derive to an unusable secret key. The ErrUnusable error will be
// returned if this should occur, so the caller must check for it and generate a
// new seed accordingly.
func NewMaster(seed []byte, net *dagconfig.Params) (*ExtendedKey, error) {
func NewMaster(seed []byte, hdPrivateKeyID [4]byte) (*ExtendedKey, error) {
// Per [BIP32], the seed must be in range [MinSeedBytes, MaxSeedBytes].
if len(seed) < MinSeedBytes || len(seed) > MaxSeedBytes {
return nil, ErrInvalidSeedLen
@ -497,7 +549,7 @@ func NewMaster(seed []byte, net *dagconfig.Params) (*ExtendedKey, error) {
}
parentFP := []byte{0x00, 0x00, 0x00, 0x00}
return NewExtendedKey(net.HDPrivateKeyID[:], secretKey, chainCode,
return NewExtendedKey(hdPrivateKeyID[:], secretKey, chainCode,
parentFP, 0, 0, true), nil
}
@ -575,3 +627,11 @@ func GenerateSeed(length uint8) ([]byte, error) {
return buf, nil
}
func init() {
// Register all default keyPairIDs when the package is initialized.
RegisterHDKeyIDPair(HDKeyPairMainNet)
RegisterHDKeyIDPair(HDKeyPairTestNet)
RegisterHDKeyIDPair(HDKeyPairRegressionNet)
RegisterHDKeyIDPair(HDKeyPairSimNet)
}

View File

@ -12,11 +12,10 @@ import (
"bytes"
"encoding/hex"
"errors"
"github.com/daglabs/btcd/util"
"math"
"reflect"
"testing"
"github.com/daglabs/btcd/dagconfig"
)
// TestBIP0032Vectors tests the vectors provided by [BIP32] to ensure the
@ -29,179 +28,179 @@ func TestBIP0032Vectors(t *testing.T) {
hkStart := uint32(0x80000000)
tests := []struct {
name string
master string
path []uint32
wantPub string
wantPriv string
net *dagconfig.Params
name string
master string
path []uint32
wantPub string
wantPriv string
hdKeyIDPair HDKeyIDPair
}{
// Test vector 1
{
name: "test vector 1 chain m",
master: testVec1MasterHex,
path: []uint32{},
wantPub: "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
wantPriv: "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
net: &dagconfig.MainNetParams,
name: "test vector 1 chain m",
master: testVec1MasterHex,
path: []uint32{},
wantPub: "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
wantPriv: "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
hdKeyIDPair: HDKeyPairMainNet,
},
{
name: "test vector 1 chain m/0H",
master: testVec1MasterHex,
path: []uint32{hkStart},
wantPub: "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw",
wantPriv: "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7",
net: &dagconfig.MainNetParams,
name: "test vector 1 chain m/0H",
master: testVec1MasterHex,
path: []uint32{hkStart},
wantPub: "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw",
wantPriv: "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7",
hdKeyIDPair: HDKeyPairMainNet,
},
{
name: "test vector 1 chain m/0H/1",
master: testVec1MasterHex,
path: []uint32{hkStart, 1},
wantPub: "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ",
wantPriv: "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs",
net: &dagconfig.MainNetParams,
name: "test vector 1 chain m/0H/1",
master: testVec1MasterHex,
path: []uint32{hkStart, 1},
wantPub: "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ",
wantPriv: "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs",
hdKeyIDPair: HDKeyPairMainNet,
},
{
name: "test vector 1 chain m/0H/1/2H",
master: testVec1MasterHex,
path: []uint32{hkStart, 1, hkStart + 2},
wantPub: "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5",
wantPriv: "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM",
net: &dagconfig.MainNetParams,
name: "test vector 1 chain m/0H/1/2H",
master: testVec1MasterHex,
path: []uint32{hkStart, 1, hkStart + 2},
wantPub: "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5",
wantPriv: "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM",
hdKeyIDPair: HDKeyPairMainNet,
},
{
name: "test vector 1 chain m/0H/1/2H/2",
master: testVec1MasterHex,
path: []uint32{hkStart, 1, hkStart + 2, 2},
wantPub: "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV",
wantPriv: "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334",
net: &dagconfig.MainNetParams,
name: "test vector 1 chain m/0H/1/2H/2",
master: testVec1MasterHex,
path: []uint32{hkStart, 1, hkStart + 2, 2},
wantPub: "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV",
wantPriv: "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334",
hdKeyIDPair: HDKeyPairMainNet,
},
{
name: "test vector 1 chain m/0H/1/2H/2/1000000000",
master: testVec1MasterHex,
path: []uint32{hkStart, 1, hkStart + 2, 2, 1000000000},
wantPub: "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy",
wantPriv: "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76",
net: &dagconfig.MainNetParams,
name: "test vector 1 chain m/0H/1/2H/2/1000000000",
master: testVec1MasterHex,
path: []uint32{hkStart, 1, hkStart + 2, 2, 1000000000},
wantPub: "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy",
wantPriv: "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76",
hdKeyIDPair: HDKeyPairMainNet,
},
// Test vector 2
{
name: "test vector 2 chain m",
master: testVec2MasterHex,
path: []uint32{},
wantPub: "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB",
wantPriv: "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U",
net: &dagconfig.MainNetParams,
name: "test vector 2 chain m",
master: testVec2MasterHex,
path: []uint32{},
wantPub: "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB",
wantPriv: "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U",
hdKeyIDPair: HDKeyPairMainNet,
},
{
name: "test vector 2 chain m/0",
master: testVec2MasterHex,
path: []uint32{0},
wantPub: "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH",
wantPriv: "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt",
net: &dagconfig.MainNetParams,
name: "test vector 2 chain m/0",
master: testVec2MasterHex,
path: []uint32{0},
wantPub: "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH",
wantPriv: "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt",
hdKeyIDPair: HDKeyPairMainNet,
},
{
name: "test vector 2 chain m/0/2147483647H",
master: testVec2MasterHex,
path: []uint32{0, hkStart + 2147483647},
wantPub: "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a",
wantPriv: "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9",
net: &dagconfig.MainNetParams,
name: "test vector 2 chain m/0/2147483647H",
master: testVec2MasterHex,
path: []uint32{0, hkStart + 2147483647},
wantPub: "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a",
wantPriv: "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9",
hdKeyIDPair: HDKeyPairMainNet,
},
{
name: "test vector 2 chain m/0/2147483647H/1",
master: testVec2MasterHex,
path: []uint32{0, hkStart + 2147483647, 1},
wantPub: "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon",
wantPriv: "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef",
net: &dagconfig.MainNetParams,
name: "test vector 2 chain m/0/2147483647H/1",
master: testVec2MasterHex,
path: []uint32{0, hkStart + 2147483647, 1},
wantPub: "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon",
wantPriv: "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef",
hdKeyIDPair: HDKeyPairMainNet,
},
{
name: "test vector 2 chain m/0/2147483647H/1/2147483646H",
master: testVec2MasterHex,
path: []uint32{0, hkStart + 2147483647, 1, hkStart + 2147483646},
wantPub: "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL",
wantPriv: "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc",
net: &dagconfig.MainNetParams,
name: "test vector 2 chain m/0/2147483647H/1/2147483646H",
master: testVec2MasterHex,
path: []uint32{0, hkStart + 2147483647, 1, hkStart + 2147483646},
wantPub: "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL",
wantPriv: "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc",
hdKeyIDPair: HDKeyPairMainNet,
},
{
name: "test vector 2 chain m/0/2147483647H/1/2147483646H/2",
master: testVec2MasterHex,
path: []uint32{0, hkStart + 2147483647, 1, hkStart + 2147483646, 2},
wantPub: "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt",
wantPriv: "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j",
net: &dagconfig.MainNetParams,
name: "test vector 2 chain m/0/2147483647H/1/2147483646H/2",
master: testVec2MasterHex,
path: []uint32{0, hkStart + 2147483647, 1, hkStart + 2147483646, 2},
wantPub: "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt",
wantPriv: "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j",
hdKeyIDPair: HDKeyPairMainNet,
},
// Test vector 3
{
name: "test vector 3 chain m",
master: testVec3MasterHex,
path: []uint32{},
wantPub: "xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13",
wantPriv: "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6",
net: &dagconfig.MainNetParams,
name: "test vector 3 chain m",
master: testVec3MasterHex,
path: []uint32{},
wantPub: "xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13",
wantPriv: "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6",
hdKeyIDPair: HDKeyPairMainNet,
},
{
name: "test vector 3 chain m/0H",
master: testVec3MasterHex,
path: []uint32{hkStart},
wantPub: "xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y",
wantPriv: "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L",
net: &dagconfig.MainNetParams,
name: "test vector 3 chain m/0H",
master: testVec3MasterHex,
path: []uint32{hkStart},
wantPub: "xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y",
wantPriv: "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L",
hdKeyIDPair: HDKeyPairMainNet,
},
// Test vector 1 - Testnet
{
name: "test vector 1 chain m - testnet",
master: testVec1MasterHex,
path: []uint32{},
wantPub: "tpubD6NzVbkrYhZ4XgiXtGrdW5XDAPFCL9h7we1vwNCpn8tGbBcgfVYjXyhWo4E1xkh56hjod1RhGjxbaTLV3X4FyWuejifB9jusQ46QzG87VKp",
wantPriv: "tprv8ZgxMBicQKsPeDgjzdC36fs6bMjGApWDNLR9erAXMs5skhMv36j9MV5ecvfavji5khqjWaWSFhN3YcCUUdiKH6isR4Pwy3U5y5egddBr16m",
net: &dagconfig.TestNet3Params,
name: "test vector 1 chain m - testnet",
master: testVec1MasterHex,
path: []uint32{},
wantPub: "tpubD6NzVbkrYhZ4XgiXtGrdW5XDAPFCL9h7we1vwNCpn8tGbBcgfVYjXyhWo4E1xkh56hjod1RhGjxbaTLV3X4FyWuejifB9jusQ46QzG87VKp",
wantPriv: "tprv8ZgxMBicQKsPeDgjzdC36fs6bMjGApWDNLR9erAXMs5skhMv36j9MV5ecvfavji5khqjWaWSFhN3YcCUUdiKH6isR4Pwy3U5y5egddBr16m",
hdKeyIDPair: HDKeyPairTestNet,
},
{
name: "test vector 1 chain m/0H - testnet",
master: testVec1MasterHex,
path: []uint32{hkStart},
wantPub: "tpubD8eQVK4Kdxg3gHrF62jGP7dKVCoYiEB8dFSpuTawkL5YxTus5j5pf83vaKnii4bc6v2NVEy81P2gYrJczYne3QNNwMTS53p5uzDyHvnw2jm",
wantPriv: "tprv8bxNLu25VazNnppTCP4fyhyCvBHcYtzE3wr3cwYeL4HA7yf6TLGEUdS4QC1vLT63TkjRssqJe4CvGNEC8DzW5AoPUw56D1Ayg6HY4oy8QZ9",
net: &dagconfig.TestNet3Params,
name: "test vector 1 chain m/0H - testnet",
master: testVec1MasterHex,
path: []uint32{hkStart},
wantPub: "tpubD8eQVK4Kdxg3gHrF62jGP7dKVCoYiEB8dFSpuTawkL5YxTus5j5pf83vaKnii4bc6v2NVEy81P2gYrJczYne3QNNwMTS53p5uzDyHvnw2jm",
wantPriv: "tprv8bxNLu25VazNnppTCP4fyhyCvBHcYtzE3wr3cwYeL4HA7yf6TLGEUdS4QC1vLT63TkjRssqJe4CvGNEC8DzW5AoPUw56D1Ayg6HY4oy8QZ9",
hdKeyIDPair: HDKeyPairTestNet,
},
{
name: "test vector 1 chain m/0H/1 - testnet",
master: testVec1MasterHex,
path: []uint32{hkStart, 1},
wantPub: "tpubDApXh6cD2fZ7WjtgpHd8yrWyYaneiFuRZa7fVjMkgxsmC1QzoXW8cgx9zQFJ81Jx4deRGfRE7yXA9A3STsxXj4CKEZJHYgpMYikkas9DBTP",
wantPriv: "tprv8e8VYgZxtHsSdGrtvdxYaSrryZGiYviWzGWtDDKTGh5NMXAEB8gYSCLHpFCywNs5uqV7ghRjimALQJkRFZnUrLHpzi2pGkwqLtbubgWuQ8q",
net: &dagconfig.TestNet3Params,
name: "test vector 1 chain m/0H/1 - testnet",
master: testVec1MasterHex,
path: []uint32{hkStart, 1},
wantPub: "tpubDApXh6cD2fZ7WjtgpHd8yrWyYaneiFuRZa7fVjMkgxsmC1QzoXW8cgx9zQFJ81Jx4deRGfRE7yXA9A3STsxXj4CKEZJHYgpMYikkas9DBTP",
wantPriv: "tprv8e8VYgZxtHsSdGrtvdxYaSrryZGiYviWzGWtDDKTGh5NMXAEB8gYSCLHpFCywNs5uqV7ghRjimALQJkRFZnUrLHpzi2pGkwqLtbubgWuQ8q",
hdKeyIDPair: HDKeyPairTestNet,
},
{
name: "test vector 1 chain m/0H/1/2H - testnet",
master: testVec1MasterHex,
path: []uint32{hkStart, 1, hkStart + 2},
wantPub: "tpubDDRojdS4jYQXNugn4t2WLrZ7mjfAyoVQu7MLk4eurqFCbrc7cHLZX8W5YRS8ZskGR9k9t3PqVv68bVBjAyW4nWM9pTGRddt3GQftg6MVQsm",
wantPriv: "tprv8gjmbDPpbAirVSezBEMuwSu1Ci9EpUJWKokZTYccSZSomNMLytWyLdtDNHRbucNaRJWWHANf9AzEdWVAqahfyRjVMKbNRhBmxAM8EJr7R15",
net: &dagconfig.TestNet3Params,
name: "test vector 1 chain m/0H/1/2H - testnet",
master: testVec1MasterHex,
path: []uint32{hkStart, 1, hkStart + 2},
wantPub: "tpubDDRojdS4jYQXNugn4t2WLrZ7mjfAyoVQu7MLk4eurqFCbrc7cHLZX8W5YRS8ZskGR9k9t3PqVv68bVBjAyW4nWM9pTGRddt3GQftg6MVQsm",
wantPriv: "tprv8gjmbDPpbAirVSezBEMuwSu1Ci9EpUJWKokZTYccSZSomNMLytWyLdtDNHRbucNaRJWWHANf9AzEdWVAqahfyRjVMKbNRhBmxAM8EJr7R15",
hdKeyIDPair: HDKeyPairTestNet,
},
{
name: "test vector 1 chain m/0H/1/2H/2 - testnet",
master: testVec1MasterHex,
path: []uint32{hkStart, 1, hkStart + 2, 2},
wantPub: "tpubDFfCa4Z1v25WTPAVm9EbEMiRrYwucPocLbEe12BPBGooxxEUg42vihy1DkRWyftztTsL23snYezF9uXjGGwGW6pQjEpcTpmsH6ajpf4CVPn",
wantPriv: "tprv8iyAReWmmePqZv8hsVZzpx4KHXRyT4chmHdriW95m11R8Tyi3fDLYDM93bq4NGn1V6eCu5cE3zSQ6hPd31F2ApKXkZgTyn1V78pHjkq1V2v",
net: &dagconfig.TestNet3Params,
name: "test vector 1 chain m/0H/1/2H/2 - testnet",
master: testVec1MasterHex,
path: []uint32{hkStart, 1, hkStart + 2, 2},
wantPub: "tpubDFfCa4Z1v25WTPAVm9EbEMiRrYwucPocLbEe12BPBGooxxEUg42vihy1DkRWyftztTsL23snYezF9uXjGGwGW6pQjEpcTpmsH6ajpf4CVPn",
wantPriv: "tprv8iyAReWmmePqZv8hsVZzpx4KHXRyT4chmHdriW95m11R8Tyi3fDLYDM93bq4NGn1V6eCu5cE3zSQ6hPd31F2ApKXkZgTyn1V78pHjkq1V2v",
hdKeyIDPair: HDKeyPairTestNet,
},
{
name: "test vector 1 chain m/0H/1/2H/2/1000000000 - testnet",
master: testVec1MasterHex,
path: []uint32{hkStart, 1, hkStart + 2, 2, 1000000000},
wantPub: "tpubDHNy3kAG39ThyiwwsgoKY4iRenXDRtce8qdCFJZXPMCJg5dsCUHayp84raLTpvyiNA9sXPob5rgqkKvkN8S7MMyXbnEhGJMW64Cf4vFAoaF",
wantPriv: "tprv8kgvuL81tmn36Fv9z38j8f4K5m1HGZRjZY2QxnXDy5PuqbP6a5TzoKWCgTcGHBu66W3TgSbAu2yX6sPza5FkHmy564Sh6gmCPUNeUt4yj2x",
net: &dagconfig.TestNet3Params,
name: "test vector 1 chain m/0H/1/2H/2/1000000000 - testnet",
master: testVec1MasterHex,
path: []uint32{hkStart, 1, hkStart + 2, 2, 1000000000},
wantPub: "tpubDHNy3kAG39ThyiwwsgoKY4iRenXDRtce8qdCFJZXPMCJg5dsCUHayp84raLTpvyiNA9sXPob5rgqkKvkN8S7MMyXbnEhGJMW64Cf4vFAoaF",
wantPriv: "tprv8kgvuL81tmn36Fv9z38j8f4K5m1HGZRjZY2QxnXDy5PuqbP6a5TzoKWCgTcGHBu66W3TgSbAu2yX6sPza5FkHmy564Sh6gmCPUNeUt4yj2x",
hdKeyIDPair: HDKeyPairTestNet,
},
}
@ -214,7 +213,7 @@ tests:
continue
}
extKey, err := NewMaster(masterSeed, test.net)
extKey, err := NewMaster(masterSeed, test.hdKeyIDPair.PrivateKeyID)
if err != nil {
t.Errorf("NewMaster #%d (%s): unexpected error when "+
"creating new master key: %v", i, test.name,
@ -648,7 +647,7 @@ func TestExtendedKeyAPI(t *testing.T) {
continue
}
addr, err := key.Address(&dagconfig.MainNetParams)
addr, err := key.Address(util.Bech32PrefixDAGCoin)
if err != nil {
t.Errorf("Address #%d (%s): unexpected error: %v", i,
test.name, err)
@ -666,84 +665,84 @@ func TestExtendedKeyAPI(t *testing.T) {
// TestNet ensures the network related APIs work as intended.
func TestNet(t *testing.T) {
tests := []struct {
name string
key string
origNet *dagconfig.Params
newNet *dagconfig.Params
newPriv string
newPub string
isPrivate bool
name string
key string
origHDKeyIDPair HDKeyIDPair
newHDKeyIDPair HDKeyIDPair
newPriv string
newPub string
isPrivate bool
}{
// Private extended keys.
{
name: "mainnet -> simnet",
key: "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
origNet: &dagconfig.MainNetParams,
newNet: &dagconfig.SimNetParams,
newPriv: "sprv8Erh3X3hFeKunvVdAGQQtambRPapECWiTDtvsTGdyrhzhbYgnSZajRRWbihzvq4AM4ivm6uso31VfKaukwJJUs3GYihXP8ebhMb3F2AHu3P",
newPub: "spub4Tr3T2ab61tD1Qa6GHwRFiiKyRRJdfEZpSpXfqgFYCEyaPsqKysqHDjzSzMJSiUEGbcsG3w2SLMoTqn44B8x6u3MLRRkYfACTUBnHK79THk",
isPrivate: true,
name: "mainnet -> simnet",
key: "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
origHDKeyIDPair: HDKeyPairMainNet,
newHDKeyIDPair: HDKeyPairSimNet,
newPriv: "sprv8Erh3X3hFeKunvVdAGQQtambRPapECWiTDtvsTGdyrhzhbYgnSZajRRWbihzvq4AM4ivm6uso31VfKaukwJJUs3GYihXP8ebhMb3F2AHu3P",
newPub: "spub4Tr3T2ab61tD1Qa6GHwRFiiKyRRJdfEZpSpXfqgFYCEyaPsqKysqHDjzSzMJSiUEGbcsG3w2SLMoTqn44B8x6u3MLRRkYfACTUBnHK79THk",
isPrivate: true,
},
{
name: "simnet -> mainnet",
key: "sprv8Erh3X3hFeKunvVdAGQQtambRPapECWiTDtvsTGdyrhzhbYgnSZajRRWbihzvq4AM4ivm6uso31VfKaukwJJUs3GYihXP8ebhMb3F2AHu3P",
origNet: &dagconfig.SimNetParams,
newNet: &dagconfig.MainNetParams,
newPriv: "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
newPub: "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
isPrivate: true,
name: "simnet -> mainnet",
key: "sprv8Erh3X3hFeKunvVdAGQQtambRPapECWiTDtvsTGdyrhzhbYgnSZajRRWbihzvq4AM4ivm6uso31VfKaukwJJUs3GYihXP8ebhMb3F2AHu3P",
origHDKeyIDPair: HDKeyPairSimNet,
newHDKeyIDPair: HDKeyPairMainNet,
newPriv: "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
newPub: "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
isPrivate: true,
},
{
name: "mainnet -> regtest",
key: "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
origNet: &dagconfig.MainNetParams,
newNet: &dagconfig.RegressionNetParams,
newPriv: "tprv8ZgxMBicQKsPeDgjzdC36fs6bMjGApWDNLR9erAXMs5skhMv36j9MV5ecvfavji5khqjWaWSFhN3YcCUUdiKH6isR4Pwy3U5y5egddBr16m",
newPub: "tpubD6NzVbkrYhZ4XgiXtGrdW5XDAPFCL9h7we1vwNCpn8tGbBcgfVYjXyhWo4E1xkh56hjod1RhGjxbaTLV3X4FyWuejifB9jusQ46QzG87VKp",
isPrivate: true,
name: "mainnet -> regtest",
key: "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
origHDKeyIDPair: HDKeyPairMainNet,
newHDKeyIDPair: HDKeyPairRegressionNet,
newPriv: "tprv8ZgxMBicQKsPeDgjzdC36fs6bMjGApWDNLR9erAXMs5skhMv36j9MV5ecvfavji5khqjWaWSFhN3YcCUUdiKH6isR4Pwy3U5y5egddBr16m",
newPub: "tpubD6NzVbkrYhZ4XgiXtGrdW5XDAPFCL9h7we1vwNCpn8tGbBcgfVYjXyhWo4E1xkh56hjod1RhGjxbaTLV3X4FyWuejifB9jusQ46QzG87VKp",
isPrivate: true,
},
{
name: "regtest -> mainnet",
key: "tprv8ZgxMBicQKsPeDgjzdC36fs6bMjGApWDNLR9erAXMs5skhMv36j9MV5ecvfavji5khqjWaWSFhN3YcCUUdiKH6isR4Pwy3U5y5egddBr16m",
origNet: &dagconfig.RegressionNetParams,
newNet: &dagconfig.MainNetParams,
newPriv: "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
newPub: "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
isPrivate: true,
name: "regtest -> mainnet",
key: "tprv8ZgxMBicQKsPeDgjzdC36fs6bMjGApWDNLR9erAXMs5skhMv36j9MV5ecvfavji5khqjWaWSFhN3YcCUUdiKH6isR4Pwy3U5y5egddBr16m",
origHDKeyIDPair: HDKeyPairRegressionNet,
newHDKeyIDPair: HDKeyPairMainNet,
newPriv: "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
newPub: "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
isPrivate: true,
},
// Public extended keys.
{
name: "mainnet -> simnet",
key: "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
origNet: &dagconfig.MainNetParams,
newNet: &dagconfig.SimNetParams,
newPub: "spub4Tr3T2ab61tD1Qa6GHwRFiiKyRRJdfEZpSpXfqgFYCEyaPsqKysqHDjzSzMJSiUEGbcsG3w2SLMoTqn44B8x6u3MLRRkYfACTUBnHK79THk",
isPrivate: false,
name: "mainnet -> simnet",
key: "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
origHDKeyIDPair: HDKeyPairMainNet,
newHDKeyIDPair: HDKeyPairSimNet,
newPub: "spub4Tr3T2ab61tD1Qa6GHwRFiiKyRRJdfEZpSpXfqgFYCEyaPsqKysqHDjzSzMJSiUEGbcsG3w2SLMoTqn44B8x6u3MLRRkYfACTUBnHK79THk",
isPrivate: false,
},
{
name: "simnet -> mainnet",
key: "spub4Tr3T2ab61tD1Qa6GHwRFiiKyRRJdfEZpSpXfqgFYCEyaPsqKysqHDjzSzMJSiUEGbcsG3w2SLMoTqn44B8x6u3MLRRkYfACTUBnHK79THk",
origNet: &dagconfig.SimNetParams,
newNet: &dagconfig.MainNetParams,
newPub: "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
isPrivate: false,
name: "simnet -> mainnet",
key: "spub4Tr3T2ab61tD1Qa6GHwRFiiKyRRJdfEZpSpXfqgFYCEyaPsqKysqHDjzSzMJSiUEGbcsG3w2SLMoTqn44B8x6u3MLRRkYfACTUBnHK79THk",
origHDKeyIDPair: HDKeyPairSimNet,
newHDKeyIDPair: HDKeyPairMainNet,
newPub: "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
isPrivate: false,
},
{
name: "mainnet -> regtest",
key: "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
origNet: &dagconfig.MainNetParams,
newNet: &dagconfig.RegressionNetParams,
newPub: "tpubD6NzVbkrYhZ4XgiXtGrdW5XDAPFCL9h7we1vwNCpn8tGbBcgfVYjXyhWo4E1xkh56hjod1RhGjxbaTLV3X4FyWuejifB9jusQ46QzG87VKp",
isPrivate: false,
name: "mainnet -> regtest",
key: "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
origHDKeyIDPair: HDKeyPairMainNet,
newHDKeyIDPair: HDKeyPairRegressionNet,
newPub: "tpubD6NzVbkrYhZ4XgiXtGrdW5XDAPFCL9h7we1vwNCpn8tGbBcgfVYjXyhWo4E1xkh56hjod1RhGjxbaTLV3X4FyWuejifB9jusQ46QzG87VKp",
isPrivate: false,
},
{
name: "regtest -> mainnet",
key: "tpubD6NzVbkrYhZ4XgiXtGrdW5XDAPFCL9h7we1vwNCpn8tGbBcgfVYjXyhWo4E1xkh56hjod1RhGjxbaTLV3X4FyWuejifB9jusQ46QzG87VKp",
origNet: &dagconfig.RegressionNetParams,
newNet: &dagconfig.MainNetParams,
newPub: "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
isPrivate: false,
name: "regtest -> mainnet",
key: "tpubD6NzVbkrYhZ4XgiXtGrdW5XDAPFCL9h7we1vwNCpn8tGbBcgfVYjXyhWo4E1xkh56hjod1RhGjxbaTLV3X4FyWuejifB9jusQ46QzG87VKp",
origHDKeyIDPair: HDKeyPairRegressionNet,
newHDKeyIDPair: HDKeyPairMainNet,
newPub: "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
isPrivate: false,
},
}
@ -756,17 +755,17 @@ func TestNet(t *testing.T) {
continue
}
if !extKey.IsForNet(test.origNet) {
if !extKey.IsForNet(test.origHDKeyIDPair) {
t.Errorf("IsForNet #%d (%s): key is not for expected "+
"network %v", i, test.name, test.origNet.Name)
"network %v", i, test.name, test.origHDKeyIDPair)
continue
}
extKey.SetNet(test.newNet)
if !extKey.IsForNet(test.newNet) {
extKey.SetNet(test.newHDKeyIDPair)
if !extKey.IsForNet(test.newHDKeyIDPair) {
t.Errorf("SetNet/IsForNet #%d (%s): key is not for "+
"expected network %v", i, test.name,
test.newNet.Name)
test.newHDKeyIDPair)
continue
}
@ -801,15 +800,15 @@ func TestNet(t *testing.T) {
// the errors are handled properly.
func TestErrors(t *testing.T) {
// Should get an error when seed has too few bytes.
net := &dagconfig.MainNetParams
_, err := NewMaster(bytes.Repeat([]byte{0x00}, 15), net)
hdKeyIDPair := HDKeyPairMainNet
_, err := NewMaster(bytes.Repeat([]byte{0x00}, 15), hdKeyIDPair.PrivateKeyID)
if err != ErrInvalidSeedLen {
t.Fatalf("NewMaster: mismatched error -- got: %v, want: %v",
err, ErrInvalidSeedLen)
}
// Should get an error when seed has too many bytes.
_, err = NewMaster(bytes.Repeat([]byte{0x00}, 65), net)
_, err = NewMaster(bytes.Repeat([]byte{0x00}, 65), hdKeyIDPair.PrivateKeyID)
if err != ErrInvalidSeedLen {
t.Fatalf("NewMaster: mismatched error -- got: %v, want: %v",
err, ErrInvalidSeedLen)
@ -820,7 +819,7 @@ func TestErrors(t *testing.T) {
if err != nil {
t.Fatalf("GenerateSeed: unexpected error: %v", err)
}
extKey, err := NewMaster(seed, net)
extKey, err := NewMaster(seed, hdKeyIDPair.PrivateKeyID)
if err != nil {
t.Fatalf("NewMaster: unexpected error: %v", err)
}
@ -864,7 +863,7 @@ func TestErrors(t *testing.T) {
key: "xbad4LfUL9eKmA66w2GJdVMqhvDmYGJpTGjWRAtjHqoUY17sGaymoMV9Cm3ocn9Ud6Hh2vLFVC7KSKCRVVrqc6dsEdsTjRV1WUmkK85YEUujAPX",
err: nil,
neuter: true,
neuterErr: dagconfig.ErrUnknownHDKeyID,
neuterErr: ErrUnknownHDKeyID,
},
}
@ -892,25 +891,25 @@ func TestErrors(t *testing.T) {
// TestZero ensures that zeroing an extended key works as intended.
func TestZero(t *testing.T) {
tests := []struct {
name string
master string
extKey string
net *dagconfig.Params
name string
master string
extKey string
hdKeyIDPair HDKeyIDPair
}{
// Test vector 1
{
name: "test vector 1 chain m",
master: "000102030405060708090a0b0c0d0e0f",
extKey: "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
net: &dagconfig.MainNetParams,
name: "test vector 1 chain m",
master: "000102030405060708090a0b0c0d0e0f",
extKey: "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
hdKeyIDPair: HDKeyPairMainNet,
},
// Test vector 2
{
name: "test vector 2 chain m",
master: "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542",
extKey: "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U",
net: &dagconfig.MainNetParams,
name: "test vector 2 chain m",
master: "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542",
extKey: "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U",
hdKeyIDPair: HDKeyPairMainNet,
},
}
@ -960,7 +959,7 @@ func TestZero(t *testing.T) {
}
wantAddr := "dagcoin:qz689gnx6z7cnsfhq6jpxtx0k9hhcwulevtzqltud6"
addr, err := key.Address(&dagconfig.MainNetParams)
addr, err := key.Address(util.Bech32PrefixDAGCoin)
if err != nil {
t.Errorf("Addres s #%d (%s): unexpected error: %v", i,
testName, err)
@ -984,7 +983,7 @@ func TestZero(t *testing.T) {
i, test.name, err)
continue
}
key, err := NewMaster(masterSeed, test.net)
key, err := NewMaster(masterSeed, test.hdKeyIDPair.PrivateKeyID)
if err != nil {
t.Errorf("NewMaster #%d (%s): unexpected error when "+
"creating new master key: %v", i, test.name,
@ -1041,8 +1040,7 @@ func TestZero(t *testing.T) {
// uint8 to encode the depth. This implicitly bounds the depth of the tree to
// 255 derivations. Here we test that an error is returned after 'max uint8'.
func TestMaximumDepth(t *testing.T) {
net := &dagconfig.MainNetParams
extKey, err := NewMaster([]byte(`abcd1234abcd1234abcd1234abcd1234`), net)
extKey, err := NewMaster([]byte(`abcd1234abcd1234abcd1234abcd1234`), HDKeyPairMainNet.PrivateKeyID)
if err != nil {
t.Fatalf("NewMaster: unexpected error: %v", err)
}

View File

@ -13,7 +13,6 @@ package util
import (
"github.com/daglabs/btcd/btcec"
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/util/bech32"
"golang.org/x/crypto/ripemd160"
)
@ -31,7 +30,7 @@ func TstAppDataDir(goos, appName string, roaming bool) string {
return appDataDir(goos, appName, roaming)
}
func TstAddressPubKeyHash(prefix dagconfig.Bech32Prefix, hash [ripemd160.Size]byte) *AddressPubKeyHash {
func TstAddressPubKeyHash(prefix Bech32Prefix, hash [ripemd160.Size]byte) *AddressPubKeyHash {
return &AddressPubKeyHash{
prefix: prefix,
hash: hash,
@ -40,7 +39,7 @@ func TstAddressPubKeyHash(prefix dagconfig.Bech32Prefix, hash [ripemd160.Size]by
// TstAddressScriptHash makes an AddressScriptHash, setting the
// unexported fields with the parameters hash and netID.
func TstAddressScriptHash(prefix dagconfig.Bech32Prefix, hash [ripemd160.Size]byte) *AddressScriptHash {
func TstAddressScriptHash(prefix Bech32Prefix, hash [ripemd160.Size]byte) *AddressScriptHash {
return &AddressScriptHash{
prefix: prefix,

View File

@ -7,9 +7,7 @@ package util
import (
"bytes"
"errors"
"github.com/daglabs/btcd/btcec"
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/util/base58"
)
@ -49,17 +47,14 @@ type WIF struct {
// 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 *dagconfig.Params, compress bool) (*WIF, error) {
if net == nil {
return nil, errors.New("no network")
}
return &WIF{privKey, compress, net.PrivateKeyID}, nil
func NewWIF(privKey *btcec.PrivateKey, privateKeyID byte, compress bool) (*WIF, error) {
return &WIF{privKey, compress, privateKeyID}, nil
}
// IsForNet returns whether or not the decoded WIF structure is associated
// with the passed bitcoin network.
func (w *WIF) IsForNet(net *dagconfig.Params) bool {
return w.netID == net.PrivateKeyID
func (w *WIF) IsForNet(privateKeyID byte) bool {
return w.netID == privateKeyID
}
// DecodeWIF creates a new WIF structure by decoding the string encoding of

View File

@ -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, &dagconfig.MainNetParams, false)
wif1, err := NewWIF(priv1, dagconfig.MainNetParams.PrivateKeyID, false)
if err != nil {
t.Fatal(err)
}
wif2, err := NewWIF(priv2, &dagconfig.TestNet3Params, true)
wif2, err := NewWIF(priv2, dagconfig.TestNet3Params.PrivateKeyID, true)
if err != nil {
t.Fatal(err)
}