add network.js and testnet support. see #40.

This commit is contained in:
Christopher Jeffrey 2015-12-09 16:12:52 -08:00
parent 26035c3b41
commit 57491aaadc
10 changed files with 242 additions and 44 deletions

View File

@ -14,3 +14,5 @@ bcoin.wallet = require('./bcoin/wallet');
bcoin.peer = require('./bcoin/peer');
bcoin.pool = require('./bcoin/pool');
bcoin.hd = require('./bcoin/hd');
bcoin.protocol.network.set(process.env.BCOIN_NETWORK || 'main');

View File

@ -3,7 +3,7 @@ var EventEmitter = require('events').EventEmitter;
var bcoin = require('../bcoin');
var constants = bcoin.protocol.constants;
var preload = bcoin.protocol.preload;
var network = bcoin.protocol.network;
var utils = bcoin.utils;
var assert = utils.assert;
@ -38,6 +38,8 @@ function Chain(options) {
};
this.request = new utils.RequestCache();
var preload = network.preload;
// Start from the genesis block
// if we're a full node.
if (this.options.fullNode) {
@ -516,6 +518,7 @@ Chain.prototype.toJSON = function toJSON() {
return {
v: 1,
type: 'chain',
network: network.type,
hashes: first.hashes.concat(last.hashes),
ts: first.ts.concat(last.ts),
heights: first.heights.concat(last.heights)
@ -525,6 +528,7 @@ Chain.prototype.toJSON = function toJSON() {
Chain.prototype.fromJSON = function fromJSON(json) {
assert.equal(json.v, 1);
assert.equal(json.type, 'chain');
assert.equal(json.network, network.type);
this.index.hashes = json.hashes.slice();
this.index.ts = json.ts.slice();
this.index.heights = json.heights.slice();
@ -534,7 +538,7 @@ Chain.prototype.fromJSON = function fromJSON(json) {
this.index.bloom = new bcoin.bloom(28 * 1024 * 1024, 16, 0xdeadbeef);
if (this.index.hashes.length === 0)
this.add(new bcoin.block(constants.genesis, 'block'));
this.add(new bcoin.block(network.genesis, 'block'));
for (var i = 0; i < this.index.hashes.length; i++) {
this.index.bloom.add(this.index.hashes[i], 'hex');

View File

@ -56,6 +56,7 @@ var bn = require('bn.js');
var elliptic = require('elliptic');
var utils = bcoin.utils;
var assert = utils.assert;
var network = bcoin.protocol.network;
var EventEmitter = require('events').EventEmitter;
@ -112,11 +113,6 @@ HDSeed._mnemonic = function(entropy) {
* HD Keys
*/
var VERSION = {
xpubkey: 0x0488b21e,
xprivkey: 0x0488ade4
};
var HARDENED = 0x80000000;
var MAX_INDEX = 2 * HARDENED;
var MIN_ENTROPY = 128 / 8;
@ -155,7 +151,7 @@ function HDPriv(options) {
data = options;
}
data = this._normalize(data, VERSION.xprivkey);
data = this._normalize(data, network.prefixes.xprivkey);
this.data = data;
@ -165,7 +161,7 @@ function HDPriv(options) {
HDPriv.prototype._normalize = function(data, version) {
var b;
data.version = version || VERSION.xprivkey;
data.version = version || network.prefixes.xprivkey;
data.version = +data.version;
data.depth = +data.depth;
@ -219,7 +215,7 @@ HDPriv.prototype._seed = function(seed) {
var hash = sha512hmac(seed, 'Bitcoin seed');
return {
// version: VERSION.xprivkey,
// version: network.prefixes.xprivkey,
depth: 0,
parentFingerPrint: 0,
childIndex: 0,
@ -413,7 +409,7 @@ function HDPub(options) {
else
data = options;
data = this._normalize(data, VERSION.xpubkey);
data = this._normalize(data, network.prefixes.xpubkey);
this.data = data;
@ -518,7 +514,7 @@ HDPub.prototype.derive = function(index, hard) {
var publicKey = bcoin.ecdsa.keyFromPublic(pubkeyPoint).getPublic(true, 'array');
return new HDPub({
// version: VERSION.xpubkey,
// version: network.prefixes.xpubkey,
depth: this.depth + 1,
parentFingerPrint: this.fingerPrint,
childIndex: index,

View File

@ -3,29 +3,6 @@ var utils = bcoin.utils;
exports.minVersion = 70001;
exports.version = 70002;
exports.magic = 0xd9b4bef9;
exports.genesis = {
version: 1,
prevBlock: [ 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 ],
merkleRoot: utils.toArray(
'4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b',
'hex'
).reverse(),
ts: 1231006505,
bits: 0x1d00ffff,
nonce: 2083236893
};
// address versions
exports.addr = {
normal: 0,
p2pkh: 0,
multisig: 0,
p2sh: 5
};
// version - services field
exports.services = {

View File

@ -1,4 +1,5 @@
var bcoin = require('../../bcoin');
var network = require('./network');
var constants = require('./constants');
var utils = bcoin.utils;
var assert = utils.assert;
@ -27,7 +28,7 @@ Framer.prototype.header = function header(cmd, payload) {
var h = new Array(24);
// Magic value
writeU32(h, constants.magic, 0);
writeU32(h, network.magic, 0);
// Command
var len = writeAscii(h, cmd, 4);

View File

@ -3,4 +3,4 @@ var protocol = exports;
protocol.constants = require('./constants');
protocol.framer = require('./framer');
protocol.parser = require('./parser');
protocol.preload = require('./preload');
protocol.network = require('./network');

View File

@ -0,0 +1,178 @@
var bcoin = require('../../bcoin');
var utils = bcoin.utils;
/**
* Network
*/
var network = exports;
network.set = function(type) {
var net = network[type];
utils.merge(network, net);
};
/**
* Main
*/
var main = network.main = {};
main.prefixes = {
pubkey: 0,
script: 5,
privkey: 128,
xpubkey: 0x0488b21e,
xprivkey: 0x0488ade4
};
utils.merge(main.prefixes, {
normal: main.prefixes.pubkey,
p2pkh: main.prefixes.pubkey,
multisig: main.prefixes.pubkey,
p2sh: main.prefixes.script
});
main.type = 'main';
main.seeds = [
'seed.bitcoin.sipa.be', // Pieter Wuille
'dnsseed.bluematt.me', // Matt Corallo
'dnsseed.bitcoin.dashjr.org', // Luke Dashjr
'seed.bitcoinstats.com', // Christian Decker
'bitseed.xf2.org', // Jeff Garzik
'seed.bitcoin.jonasschnelli.ch' // Jonas Schnelli
];
main.port = 8333;
main.alertKey = utils.toArray(''
+ '04fc9702847840aaf195de8442ebecedf5b095c'
+ 'dbb9bc716bda9110971b28a49e0ead8564ff0db'
+ '22209e0374782c093bb899692d524e9d6a6956e'
+ '7c5ecbcd68284',
'hex');
main.checkpoints = [
{ height: 11111, hash: '0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d' },
{ height: 33333, hash: '000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6' },
{ height: 74000, hash: '0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20' },
{ height: 105000, hash: '00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97' },
{ height: 134444, hash: '00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe' },
{ height: 168000, hash: '000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763' },
{ height: 193000, hash: '000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317' },
{ height: 210000, hash: '000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e' },
{ height: 216116, hash: '00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e' },
{ height: 225430, hash: '00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932' },
{ height: 250000, hash: '000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214' },
{ height: 279000, hash: '0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40' },
{ height: 295000, hash: '00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983' }
];
main.checkpoints.tsLastCheckpoint = 1397080064;
main.checkpoints.txsLastCheckpoint = 36544669;
main.checkpoints.txsPerDay = 60000.0;
// http://blockexplorer.com/b/0
// http://blockexplorer.com/rawblock/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
main.genesis = {
version: 1,
_hash: utils.toArray(
'000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f',
'hex'
).reverse(),
prevBlock: [ 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 ],
merkleRoot: utils.toArray(
'4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b',
'hex'
).reverse(),
ts: 1231006505,
bits: 0x1d00ffff,
nonce: 2083236893
};
main.magic = 0xd9b4bef9;
main.preload = require('./preload');
/**
* Testnet (v3)
* https://en.bitcoin.it/wiki/Testnet
*/
var testnet = network.testnet = {};
testnet.type = 'testnet';
testnet.prefixes = {
pubkey: 111,
script: 196,
privkey: 239,
xpubkey: 0x043587cf,
xprivkey: 0x04358394
};
utils.merge(testnet.prefixes, {
normal: testnet.prefixes.pubkey,
p2pkh: testnet.prefixes.pubkey,
multisig: testnet.prefixes.pubkey,
p2sh: testnet.prefixes.script
});
testnet.seeds = [
'testnet-seed.alexykot.me',
'testnet-seed.bitcoin.petertodd.org',
'testnet-seed.bluematt.me',
'testnet-seed.bitcoin.schildbach.de'
];
testnet.port = 18333;
testnet.alertKey = utils.toArray(''
+ '04302390343f91cc401d56d68b123028bf52e5f'
+ 'ca1939df127f63c6467cdf9c8e2c14b61104cf8'
+ '17d0b780da337893ecc4aaff1309e536162dabb'
+ 'db45200ca2b0a',
'hex');
testnet.checkpoints = [
{ height: 546, hash: '000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70' }
];
testnet.checkpoints.tsLastCheckpoint = 1338180505;
testnet.checkpoints.txsLastCheckpoint = 16341;
testnet.checkpoints.txsPerDay = 300;
// http://blockexplorer.com/testnet/b/0
// http://blockexplorer.com/testnet/rawblock/000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943
testnet.genesis = {
version: 1,
_hash: utils.toArray(
'000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943',
'hex'
).reverse(),
prevBlock: [ 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 ],
merkleRoot: utils.toArray(
'4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b',
'hex'
).reverse(),
ts: 1296688602,
bits: 0x1d00ffff,
nonce: 414098458
};
testnet.magic = 0x0709110b;
testnet.preload = {
'v': 1,
'type': 'chain',
'hashes': [utils.toHex(testnet.genesis._hash)],
'ts': [testnet.genesis.ts],
'heights': [0]
};

View File

@ -6,6 +6,7 @@ var bcoin = require('../../bcoin');
var utils = bcoin.utils;
var assert = utils.assert;
var constants = require('./constants');
var network = require('./network');
var readU32 = utils.readU32;
var readU64 = utils.readU64;
@ -71,7 +72,7 @@ Parser.prototype.parse = function parse(chunk) {
Parser.prototype.parseHeader = function parseHeader(h) {
var magic = readU32(h, 0);
if (magic !== constants.magic) {
if (magic !== network.magic) {
return this._error('Invalid magic value: ' + magic.toString(16));
}

View File

@ -2,6 +2,7 @@ var utils = exports;
var bn = require('bn.js');
var hash = require('hash.js');
var util = require('util');
function toArray(msg, enc) {
if (Array.isArray(msg))
@ -491,6 +492,41 @@ utils.toKeyArray = function(msg) {
return utils.fromBase58(msg);
};
utils.debug = function(msg) {
console.log('\x1b[31m' + msg + '\x1b[m');
utils.inspect = function(obj) {
return typeof obj !== 'string'
? util.inspect(obj, null, 20, true)
: obj;
};
utils.print = function(msg) {
return typeof msg === 'object'
? process.stdout.write(utils.inspect(msg) + '\n')
: console.log.apply(console, arguments);
};
utils.debug = function() {
var args = Array.prototype.slice.call(arguments);
args[0] = '\x1b[31m' + args[0] + '\x1b[m';
return utils.print.apply(null, args);
};
utils.merge = function(target) {
var args = Array.prototype.slice.call(arguments, 1);
args.forEach(function(obj) {
Object.keys(obj).forEach(function(key) {
target[key] = obj[key];
});
});
return target;
};
utils.fromBTC = function(btc) {
var satoshi = new bn(+btc || 0);
satoshi.imuln(100000000);
return satoshi;
};
utils.ntoBTC = function(satoshi) {
satoshi = new bn(Math.floor(+satoshi || 0).toString(16), 16);
return bcoin.utils.toBTC(satoshi);
};

View File

@ -6,6 +6,7 @@ var EventEmitter = require('events').EventEmitter;
var utils = bcoin.utils;
var assert = utils.assert;
var constants = bcoin.protocol.constants;
var network = bcoin.protocol.network;
function Wallet(options, passphrase) {
if (!(this instanceof Wallet))
@ -166,7 +167,7 @@ Wallet.prototype.getPrivateKey = function getPrivateKey(enc) {
if (enc === 'base58') {
// We'll be using ncompressed public key as an address
var arr = [ 128 ];
var arr = [ network.prefixes.privkey ];
// 0-pad key
while (arr.length + priv.length < 33)
@ -258,7 +259,7 @@ Wallet.prototype.getAddress = function getAddress() {
Wallet.hash2addr = function hash2addr(hash, version) {
hash = utils.toArray(hash, 'hex');
version = constants.addr[version || 'normal'];
version = network.prefixes[version || 'normal'];
hash = [ version ].concat(hash);
var addr = hash.concat(utils.checksum(hash));
@ -269,7 +270,7 @@ Wallet.addr2hash = function addr2hash(addr, version) {
if (!Array.isArray(addr))
addr = utils.fromBase58(addr);
version = constants.addr[version || 'normal'];
version = network.prefixes[version || 'normal'];
if (addr.length !== 25)
return [];
@ -417,6 +418,7 @@ Wallet.prototype.toJSON = function toJSON() {
return {
v: 1,
type: 'wallet',
network: network.type,
pub: this.getOwnPublicKey('base58'),
priv: this.getPrivateKey('base58'),
tx: this.tx.toJSON(),
@ -432,6 +434,7 @@ Wallet.prototype.toJSON = function toJSON() {
Wallet.fromJSON = function fromJSON(json) {
assert.equal(json.v, 1);
assert.equal(json.type, 'wallet');
assert.equal(json.network, network.type);
var priv;
var pub;
@ -440,7 +443,7 @@ Wallet.fromJSON = function fromJSON(json) {
if (json.priv) {
var key = bcoin.utils.fromBase58(json.priv);
assert(utils.isEqual(key.slice(-4), utils.checksum(key.slice(0, -4))));
assert.equal(key[0], 128);
assert.equal(key[0], network.prefixes.privkey);
key = key.slice(0, -4);
if (key.length === 34) {