Skip to content
This repository has been archived by the owner on Jan 25, 2024. It is now read-only.

Commit

Permalink
fix(networks): BIP32 constants for litecoin
Browse files Browse the repository at this point in the history
Litecoin in fact has the same BIP32 prefixes (xpub/xprv, tpub/tprv) as
all other utxo coins.

This error was introduced in bitcoinjs-lib and propagated to
`cryptocoinjs/coininfo`, where a similar fix is pending:
https://github.com/cryptocoinjs/coininfo/pull/76/files

It is unclear what the source for the incorrect values was originally.

Litecoin Mainnet:
https://github.com/litecoin-project/litecoin/blob/1b6c480/src/chainparams.cpp#L142-L143

Litecoin Testnet:
https://github.com/litecoin-project/litecoin/blob/1b6c480/src/chainparams.cpp#L249-L250

* Add `getDefaultBip32Mainnet()` and `getDefaultBip32Testnet()` to make
  shared values more obvious.

* Modify tests fixtures and tests which previously assumed
  bip32-exported coins have different prefixes.

BREAKING CHANGE:

While this is a breaking change, I don't think these values were
actually used anywhere.

Issue: BG-16466
  • Loading branch information
OttoAllmendinger committed Jan 9, 2020
1 parent b08089a commit 69d0244
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 89 deletions.
4 changes: 3 additions & 1 deletion src/hdnode.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ HDNode.fromSeedHex = function (hex, network) {
}

HDNode.fromBase58 = function (string, networks) {
// FixMe: Issue #38, this method just pops the latest network object from the list instead of being more discerning.
var buffer = base58check.decode(string)
if (buffer.length !== 78) throw new Error('Invalid buffer length')

Expand All @@ -66,6 +65,9 @@ HDNode.fromBase58 = function (string, networks) {

// list of networks?
if (Array.isArray(networks)) {
// FIXME(BG-16845):
// This is only useful when you know the coin but you are not sure if it is mainnet or testnet.
// All mainnets have xpub/xprv and all testnets have tpub/tprv as version.
network = networks.filter(function (x) {
return version === x.bip32.private ||
version === x.bip32.public
Expand Down
103 changes: 40 additions & 63 deletions src/networks.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
The values for the various fork coins can be found in these files:
property filename varname
------------------------------------------------------------------
messagePrefix: src/validation.cpp strMessageMagic
bech32_hrp: src/chainparams.cpp bech32_hrp
bip32.public: src/chainparams.cpp base58Prefixes[EXT_PUBLIC_KEY]
bip32.private src/chainparams.cpp base58Prefixes[EXT_SECRET_KEY]
pubKeyHash: src/chainparams.cpp base58Prefixes[PUBKEY_ADDRESS]
scriptHash: src/chainparams.cpp base58Prefixes[SCRIPT_ADDRESS]
wif: src/chainparams.cpp base58Prefixes[SECRET_KEY]
property filename varname notes
------------------------------------------------------------------------------------------------------------------------
messagePrefix src/validation.cpp strMessageMagic Format `${CoinName} Signed Message`
bech32_hrp src/chainparams.cpp bech32_hrp Only for some networks
bip32.public src/chainparams.cpp base58Prefixes[EXT_PUBLIC_KEY] Mainnets have same value, testnets have same value
bip32.private src/chainparams.cpp base58Prefixes[EXT_SECRET_KEY] Mainnets have same value, testnets have same value
pubKeyHash src/chainparams.cpp base58Prefixes[PUBKEY_ADDRESS]
scriptHash src/chainparams.cpp base58Prefixes[SCRIPT_ADDRESS]
wif src/chainparams.cpp base58Prefixes[SECRET_KEY] Testnets have same value
*/

Expand All @@ -24,17 +24,32 @@ const coins = {
DASH: 'dash'
}

function getDefaultBip32Mainnet () {
return {
// base58 'xpub'
public: 0x0488b21e,
// base58 'xprv'
private: 0x0488ade4
}
}

function getDefaultBip32Testnet () {
return {
// base58 'tpub'
public: 0x043587cf,
// base58 'tprv'
private: 0x04358394
}
}

module.exports = {

// https://github.com/bitcoin/bitcoin/blob/master/src/validation.cpp
// https://github.com/bitcoin/bitcoin/blob/master/src/chainparams.cpp
bitcoin: {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'bc',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
bip32: getDefaultBip32Mainnet(),
pubKeyHash: 0x00,
scriptHash: 0x05,
wif: 0x80,
Expand All @@ -43,10 +58,7 @@ module.exports = {
testnet: {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'tb',
bip32: {
public: 0x043587cf,
private: 0x04358394
},
bip32: getDefaultBip32Testnet(),
pubKeyHash: 0x6f,
scriptHash: 0xc4,
wif: 0xef,
Expand All @@ -57,10 +69,7 @@ module.exports = {
// https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/src/chainparams.cpp
bitcoincash: {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
bip32: getDefaultBip32Mainnet(),
pubKeyHash: 0x00,
scriptHash: 0x05,
wif: 0x80,
Expand All @@ -69,10 +78,7 @@ module.exports = {
},
bitcoincashTestnet: {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bip32: {
public: 0x043587cf,
private: 0x04358394
},
bip32: getDefaultBip32Testnet(),
pubKeyHash: 0x6f,
scriptHash: 0xc4,
wif: 0xef,
Expand All @@ -84,10 +90,7 @@ module.exports = {
bitcoingold: {
messagePrefix: '\x18Bitcoin Gold Signed Message:\n',
bech32: 'btg',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
bip32: getDefaultBip32Mainnet(),
pubKeyHash: 0x26,
scriptHash: 0x17,
wif: 0x80,
Expand All @@ -100,10 +103,7 @@ module.exports = {
// https://github.com/bitcoin-sv/bitcoin-sv/blob/master/src/chainparams.cpp
bitcoinsv: {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
bip32: getDefaultBip32Mainnet(),
pubKeyHash: 0x00,
scriptHash: 0x05,
wif: 0x80,
Expand All @@ -112,10 +112,7 @@ module.exports = {
},
bitcoinsvTestnet: {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bip32: {
public: 0x043587cf,
private: 0x04358394
},
bip32: getDefaultBip32Testnet(),
pubKeyHash: 0x6f,
scriptHash: 0xc4,
wif: 0xef,
Expand All @@ -126,21 +123,15 @@ module.exports = {
// https://github.com/dashpay/dash/blob/master/src/chainparams.cpp
dash: {
messagePrefix: '\x19DarkCoin Signed Message:\n',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
bip32: getDefaultBip32Mainnet(),
pubKeyHash: 0x4c,
scriptHash: 0x10,
wif: 0xcc,
coin: coins.DASH
},
dashTest: {
messagePrefix: '\x19DarkCoin Signed Message:\n',
bip32: {
public: 0x043587cf,
private: 0x04358394
},
bip32: getDefaultBip32Testnet(),
pubKeyHash: 0x8c,
scriptHash: 0x13,
wif: 0xef,
Expand All @@ -152,11 +143,7 @@ module.exports = {
litecoin: {
messagePrefix: '\x19Litecoin Signed Message:\n',
bech32: 'ltc',
bip32: {
// FIXME(BG-16466): these are incorrect
public: 0x019da462,
private: 0x019d9cfe
},
bip32: getDefaultBip32Mainnet(),
pubKeyHash: 0x30,
scriptHash: 0x32,
wif: 0xb0,
Expand All @@ -165,11 +152,7 @@ module.exports = {
litecoinTest: {
messagePrefix: '\x19Litecoin Signed Message:\n',
bech32: 'tltc',
bip32: {
// FIXME(BG-16466): these are incorrect
public: 0x0488b21e,
private: 0x0488ade4
},
bip32: getDefaultBip32Testnet(),
pubKeyHash: 0x6f,
scriptHash: 0x3a,
wif: 0xef,
Expand All @@ -180,10 +163,7 @@ module.exports = {
// https://github.com/zcash/zcash/blob/master/src/chainparams.cpp
zcash: {
messagePrefix: '\x18ZCash Signed Message:\n',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
bip32: getDefaultBip32Mainnet(),
pubKeyHash: 0x1cb8,
scriptHash: 0x1cbd,
wif: 0x80,
Expand All @@ -200,10 +180,7 @@ module.exports = {
},
zcashTest: {
messagePrefix: '\x18ZCash Signed Message:\n',
bip32: {
public: 0x043587cf,
private: 0x04358394
},
bip32: getDefaultBip32Testnet(),
pubKeyHash: 0x1d25,
scriptHash: 0x1cba,
wif: 0xef,
Expand Down
8 changes: 4 additions & 4 deletions test/fixtures/hdnode.json
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@
"wif": "TAroS5Knm8GZcnpPycBgzjwwDLWMyQjDrcuGPPoArgrbW7Ln22qp",
"pubKey": "0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2",
"chainCode": "873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508",
"base58": "Ltub2SSUS19CirucWFod2ZsYA2J4v4U76YiCXHdcQttnoiy5aGanFHCPDBX7utfG6f95u1cUbZJNafmvzNCzZZJTw1EmyFoL8u1gJbGM8ipu491",
"base58Priv": "Ltpv71G8qDifUiNetP6nmxPA5STrUVmv2J9YSmXajv8VsYBUyuPhvN9xCaQrfX2wo5xxJNtEazYCFRUu5FmokYMM79pcqz8pcdo4rNXAFPgyB4k",
"base58": "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
"base58Priv": "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
"identifier": "3442193e1bb70916e914552172cd4e2dbc9df811",
"fingerprint": "3442193e",
"address": "LPzGaoLUtXFkmNo3u1chDxGxDnSaBQTTxm"
Expand All @@ -227,8 +227,8 @@
"wif": "TB22qU2V9EJCVKJ8cdYaTfvDhnYcCzthcWgFm1k6hbvbKM1NLxoL",
"pubKey": "035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56",
"chainCode": "47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141",
"base58": "Ltub2UhtRiSfp82berwLEKkB34QBEt2TUdCDCu4WNzGumvAMwYsxfWjULKsXhADxqy3cuDu3TnqoKJr1xmB8Wb2qzthWAtbb4CutpXPuSU1YMgG",
"base58Priv": "Ltpv73XYpw28ZyVe2zEVyiFnxUZxoKLGQNdZ8NxUi1WcqjNmMBgtLbh3KimGSnPHCoLv1RmvxHs4dnKmo1oXQ8dXuDu8uroxrbVxZPA1gXboYvx",
"base58": "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw",
"base58Priv": "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7",
"identifier": "5c1bd648ed23aa5fd50ba52b2457c11e9e80a6a7",
"fingerprint": "5c1bd648",
"address": "LTcyn1jun6g9hvxtsT7cqMRSyix7AULC76",
Expand Down
12 changes: 6 additions & 6 deletions test/hdnode.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ var fixtures = require('./fixtures/hdnode.json')
var curve = ecdsa.__curve

var NETWORKS = require('../src/networks')
var NETWORKS_LIST = [] // Object.values(NETWORKS)
for (var networkName in NETWORKS) {
NETWORKS_LIST.push(NETWORKS[networkName])
}
var NETWORKS_LIST = [
NETWORKS.bitcoin,
NETWORKS.testnet
]

var validAll = []
fixtures.valid.forEach(function (f) {
Expand Down Expand Up @@ -176,7 +176,7 @@ describe('HDNode', function () {
describe('fromBase58 / toBase58', function () {
validAll.forEach(function (f) {
it('exports ' + f.base58 + ' (public) correctly', function () {
var hd = HDNode.fromBase58(f.base58, NETWORKS_LIST)
var hd = HDNode.fromBase58(f.base58, f.network ? NETWORKS[f.network] : undefined)

assert.strictEqual(hd.toBase58(), f.base58)
assert.throws(function () { hd.keyPair.toWIF() }, /Missing private key/)
Expand All @@ -185,7 +185,7 @@ describe('HDNode', function () {

validAll.forEach(function (f) {
it('exports ' + f.base58Priv + ' (private) correctly', function () {
var hd = HDNode.fromBase58(f.base58Priv, NETWORKS_LIST)
var hd = HDNode.fromBase58(f.base58Priv, f.network ? NETWORKS[f.network] : undefined)

assert.strictEqual(hd.toBase58(), f.base58Priv)
assert.strictEqual(hd.keyPair.toWIF(), f.wif)
Expand Down
19 changes: 4 additions & 15 deletions test/networks.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,23 +87,12 @@ describe('networks', function () {
assert.strictEqual(typeof network.wif, 'number')
assert.strictEqual(typeof network.coin, 'string')

// FIXME(BG-16466): litecoin should not be a special case here -- all forks have the same bip32 values
const isLitecoin = coins.getMainnet(network) === networks.litecoin

if (coins.isMainnet(network)) {
assert.strictEqual(
(network.bip32.public === networks.bitcoin.bip32.public), !isLitecoin
)
assert.strictEqual(
(network.bip32.private === networks.bitcoin.bip32.private), !isLitecoin
)
assert.strictEqual(network.bip32.public, networks.bitcoin.bip32.public)
assert.strictEqual(network.bip32.private, networks.bitcoin.bip32.private)
} else {
assert.strictEqual(
(network.bip32.public === networks.testnet.bip32.public), !isLitecoin
)
assert.strictEqual(
(network.bip32.private === networks.testnet.bip32.private), !isLitecoin
)
assert.strictEqual(network.bip32.public, networks.testnet.bip32.public)
assert.strictEqual(network.bip32.private, networks.testnet.bip32.private)
}
})

Expand Down

0 comments on commit 69d0244

Please sign in to comment.