From 6dd3b815c172f3d4c0e9d19a98ff0467f91f9268 Mon Sep 17 00:00:00 2001 From: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com> Date: Sun, 23 Sep 2018 15:49:50 +0300 Subject: [PATCH] [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. --- blockdag/fullblocktests/params.go | 4 +- config/config.go | 4 +- dagconfig/params.go | 107 +------ dagconfig/params_test.go | 51 ---- dagconfig/register_test.go | 73 ++--- integration/rpctest/memwallet.go | 4 +- mempool/mempool_test.go | 2 +- mempool/policy_test.go | 6 +- mining/policy_test.go | 3 +- rpcclient/wallet.go | 13 +- server/rpc/rpcserver.go | 14 +- server/rpc/rpcwebsocket.go | 12 +- txscript/example_test.go | 7 +- txscript/sign_test.go | 68 ++--- txscript/standard.go | 8 +- txscript/standard_test.go | 26 +- util/address.go | 113 +++++--- util/address_test.go | 122 +++++--- util/gcs/builder/builder_test.go | 14 +- util/hdkeychain/example_test.go | 8 +- util/hdkeychain/extendedkey.go | 90 +++++- util/hdkeychain/extendedkey_test.go | 428 ++++++++++++++-------------- util/internal_test.go | 5 +- util/wif.go | 13 +- util/wif_test.go | 4 +- 25 files changed, 606 insertions(+), 593 deletions(-) diff --git a/blockdag/fullblocktests/params.go b/blockdag/fullblocktests/params.go index 8defc97ec..579b9bf31 100644 --- a/blockdag/fullblocktests/params.go +++ b/blockdag/fullblocktests/params.go @@ -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. diff --git a/config/config.go b/config/config.go index 15504ec6f..06547ddab 100644 --- a/config/config.go +++ b/config/config.go @@ -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) diff --git a/dagconfig/params.go b/dagconfig/params.go index 322d8480a..82294ab0f 100644 --- a/dagconfig/params.go +++ b/dagconfig/params.go @@ -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 diff --git a/dagconfig/params_test.go b/dagconfig/params_test.go index 97534f1fc..83d04262a 100644 --- a/dagconfig/params_test.go +++ b/dagconfig/params_test.go @@ -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} diff --git a/dagconfig/register_test.go b/dagconfig/register_test.go index 0613b12bb..313b516c7 100644 --- a/dagconfig/register_test.go +++ b/dagconfig/register_test.go @@ -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) diff --git a/integration/rpctest/memwallet.go b/integration/rpctest/memwallet.go index 727134484..ccd3e740d 100644 --- a/integration/rpctest/memwallet.go +++ b/integration/rpctest/memwallet.go @@ -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 } diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index e93ef72a9..022773974 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -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 } diff --git a/mempool/policy_test.go b/mempool/policy_test.go index 027ccf77f..74c74fc43 100644 --- a/mempool/policy_test.go +++ b/mempool/policy_test.go @@ -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) } diff --git a/mining/policy_test.go b/mining/policy_test.go index 426076e4a..aff0389c8 100644 --- a/mining/policy_test.go +++ b/mining/policy_test.go @@ -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) diff --git a/rpcclient/wallet.go b/rpcclient/wallet.go index 4c5f13b4d..ecc536f32 100644 --- a/rpcclient/wallet.go +++ b/rpcclient/wallet.go @@ -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 } diff --git a/server/rpc/rpcserver.go b/server/rpc/rpcserver.go index 76822c740..97d6cc08c 100644 --- a/server/rpc/rpcserver.go +++ b/server/rpc/rpcserver.go @@ -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. diff --git a/server/rpc/rpcwebsocket.go b/server/rpc/rpcwebsocket.go index 6ec083e9b..33719ec3a 100644 --- a/server/rpc/rpcwebsocket.go +++ b/server/rpc/rpcwebsocket.go @@ -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, diff --git a/txscript/example_test.go b/txscript/example_test.go index e20a33488..f81cbdc5e 100644 --- a/txscript/example_test.go +++ b/txscript/example_test.go @@ -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 diff --git a/txscript/sign_test.go b/txscript/sign_test.go index 1609a82ff..07771e28e 100644 --- a/txscript/sign_test.go +++ b/txscript/sign_test.go @@ -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) diff --git a/txscript/standard.go b/txscript/standard.go index 9869026af..3e2f870b3 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -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) } diff --git a/txscript/standard_test.go b/txscript/standard_test.go index b29877323..626d5c2b2 100644 --- a/txscript/standard_test.go +++ b/txscript/standard_test.go @@ -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) diff --git a/util/address.go b/util/address.go index 86fc81d65..dc8f59232 100644 --- a/util/address.go +++ b/util/address.go @@ -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 diff --git a/util/address_test.go b/util/address_test.go index f86353503..94ca9b010 100644 --- a/util/address_test.go +++ b/util/address_test.go @@ -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) + } + } +} diff --git a/util/gcs/builder/builder_test.go b/util/gcs/builder/builder_test.go index ebab888c8..1c0e30b88 100644 --- a/util/gcs/builder/builder_test.go +++ b/util/gcs/builder/builder_test.go @@ -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()) } diff --git a/util/hdkeychain/example_test.go b/util/hdkeychain/example_test.go index 4c818511a..4e7c2a2f3 100644 --- a/util/hdkeychain/example_test.go +++ b/util/hdkeychain/example_test.go @@ -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 diff --git a/util/hdkeychain/extendedkey.go b/util/hdkeychain/extendedkey.go index aa4484780..ded5a4e33 100644 --- a/util/hdkeychain/extendedkey.go +++ b/util/hdkeychain/extendedkey.go @@ -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) +} \ No newline at end of file diff --git a/util/hdkeychain/extendedkey_test.go b/util/hdkeychain/extendedkey_test.go index 5d609f4a8..50e7a638c 100644 --- a/util/hdkeychain/extendedkey_test.go +++ b/util/hdkeychain/extendedkey_test.go @@ -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) } diff --git a/util/internal_test.go b/util/internal_test.go index c231c5807..12d987c80 100644 --- a/util/internal_test.go +++ b/util/internal_test.go @@ -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, diff --git a/util/wif.go b/util/wif.go index 3a5d63000..b5715ea34 100644 --- a/util/wif.go +++ b/util/wif.go @@ -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 diff --git a/util/wif_test.go b/util/wif_test.go index f793e51e3..98f99ac1c 100644 --- a/util/wif_test.go +++ b/util/wif_test.go @@ -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) }