Skip to content

Commit ea60c61

Browse files
author
Ryan X. Charles
committed
update bitcoinjs-lib to the latest version
Summary: update bitcoinjs-lib to the latest version - Remove our fork of bitcoinjs-lib and update the SDK to use the most recent version of bitcoinjs-lib. - Add some dependencies (the same as used by bitcoinjs-lib) that are not exposed by bitcoinjs-lib, but necessary for some functionality (bs58, b58check, bigi). - No longer expose bitcoinjs-lib classes like Address, ECKey, etc., since we cannot be responsible for maintaining bitcoinjs-lib's API. If a tool using our SDK needs bitcoinjs-lib functionality, it should include bitcoinjs-lib separately. - Rename main network from "prod" to "bitcoin" to be compatible with bitcoinjs-lib. Note that this is a backwards-incompatible change, so anyone using the setNetwork or getNetwork features of the SDK will need to change this. - Updated version number to 0.10.0, since this is an API-breaking change due to the removal of the now-obsolete bitcoinjs-lib from the exposures and changing of network name. (Although all of the BitGo-specific API stuff is still the same.) - Update the recover wallet example to link to use the new bitcoinjs-lib (and confirmed to work on testnet). - Updated the random number generator to use only node's (cryptographically secure) RNG, or the the browser's (cryptographically secure) window.crypto RNG (which is what browserify uses when browserifying node's RNG). Fail otherwise. Attempting to compensate for a poor RNG is futile - we should only support platforms that have a good RNG. Reviewers: mike, benchan, ben Reviewed By: benchan, ben Subscribers: ben Differential Revision: https://phabricator.bitgo.com/D831
1 parent f1daa8b commit ea60c61

67 files changed

Lines changed: 410 additions & 16349 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

example/recoverwallet.js

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@
99

1010
var BitGoJS = require('../src/index.js');
1111
var readline = require('readline');
12+
var HDNode = require('../src/hdnode');
13+
var Address = require('bitcoinjs-lib/src/address');
14+
var Script = require('bitcoinjs-lib/src/script');
15+
var Scripts = require('bitcoinjs-lib/src/scripts');
16+
var Transaction = require('bitcoinjs-lib/src/transaction');
17+
var TransactionBuilder = require('bitcoinjs-lib/src/transaction_builder');
18+
var networks = require('bitcoinjs-lib/src/networks');
19+
var Util = require('../src/util');
1220
var Q = require('q');
1321

1422
var chain = require('chain-node'); // Use chain.com as our alternate blockchain api provider
@@ -23,7 +31,7 @@ var bitgoKey; // The BIP32 xpub for the bitgo public key
2331
var subAddresses = {}; // A map of addresses containing funds to recover
2432
var unspents; // The unspents from the HD wallet
2533
var transaction; // The transaction to send
26-
var bitcoinNetwork = 'prod';
34+
var bitcoinNetwork = 'bitcoin';
2735

2836
var info = '\n' +
2937
'**********************************\n' +
@@ -36,7 +44,6 @@ var info = '\n' +
3644
'Please enter a blank line after each input.\n';
3745
console.log(info);
3846

39-
4047
//
4148
// collectInputs
4249
// Function to asynchronously collect inputs for the recovery tool.
@@ -114,7 +121,7 @@ var decryptKeys = function() {
114121
throw new Error('must be xprv key');
115122
}
116123
}
117-
return new BitGoJS.BIP32(key);
124+
return HDNode.fromBase58(key);
118125
} catch(e) {
119126
throw new Error('invalid key: ' + e);
120127
}
@@ -168,11 +175,12 @@ var findBaseAddress = function() {
168175

169176
for (var key in keys) {
170177
var keyData = keys[key];
171-
keyData.derived = keyData.key.derive(keyData.path);
172-
keyData.derivedPubKey = keyData.derived.eckey.getPub();
178+
keyData.derived = keyData.key.deriveFromPath(keyData.path);
179+
keyData.derivedPubKey = keyData.derived.pubKey;
173180
pubKeys.push(keyData.derivedPubKey);
174181
}
175-
var baseAddress = BitGoJS.Address.createMultiSigAddress(pubKeys, 2);
182+
var network = BitGoJS.getNetwork() === 'bitcoin' ? networks.bitcoin : networks.testnet;
183+
var baseAddress = Address.fromOutputScript(Util.p2shMultisigOutputScript(2, pubKeys), network).toBase58Check();
176184

177185
console.log("\tTrying address: " + baseAddress);
178186
chain.getAddress(baseAddress, function(err, data) {
@@ -280,13 +288,14 @@ var findSubAddresses = function(baseAddress) {
280288
for (var key in baseAddress.keys) {
281289
var keyData = baseAddress.keys[key];
282290
var path = keyData.path + '/' + keyIndex + '/' + addressIndex;
283-
keyData.derived = keyData.key.derive(path);
284-
keyData.derivedPubKey = keyData.derived.eckey.getPub();
291+
keyData.derived = keyData.key.deriveFromPath(path);
292+
keyData.derivedPubKey = keyData.derived.pubKey;
285293
pubKeys.push(keyData.derivedPubKey);
286294
}
287295

288-
var subAddress = BitGoJS.Address.createMultiSigAddress(pubKeys, 2);
289-
var subAddressString = subAddress.toString();
296+
var network = BitGoJS.getNetwork() === 'bitcoin' ? networks.bitcoin : networks.testnet;
297+
var redeemScript = Scripts.multisigOutput(2, pubKeys);
298+
var subAddressString = Address.fromOutputScript(Util.p2shMultisigOutputScript(2, pubKeys), network).toBase58Check();
290299

291300
console.log("Trying keyIndex " + keyIndex + " addressIndex " + addressIndex + ": " + subAddressString + "...");
292301
chain.getAddress(subAddressString, function(err, data) {
@@ -297,15 +306,15 @@ var findSubAddresses = function(baseAddress) {
297306
lookahead = 0;
298307
console.log('\tfound: ' + data.balance + ' at ' + subAddressString);
299308
subAddresses[subAddressString] = {
300-
address: subAddress,
309+
address: subAddressString,
301310
keyIndex: keyIndex,
302311
addressIndex: addressIndex,
303312
keys: [
304313
{ key: baseAddress.keys[0].derived, path: baseAddress.keys[0].path + '/' + keyIndex + '/' + addressIndex },
305314
{ key: baseAddress.keys[1].derived, path: baseAddress.keys[1].path + '/' + keyIndex + '/' + addressIndex },
306315
{ key: baseAddress.keys[2].derived, path: baseAddress.keys[2].path + '/' + keyIndex + '/' + addressIndex },
307316
],
308-
redeemScript: BitGoJS.Util.bytesToHex(subAddress.redeemScript)
317+
redeemScript: redeemScript.toBuffer().toString('hex')
309318
};
310319
} else {
311320
if (++lookahead >= MAX_LOOKAHEAD_ADDRESSES) {
@@ -358,22 +367,23 @@ var findUnspents = function() {
358367

359368
var createTransaction = function() {
360369
var totalValue = 0;
361-
transaction = new BitGoJS.Transaction();
370+
transaction = new Transaction();
362371

363372
// Add the inputs
364373
for (var index in unspents) {
365374
var unspent = unspents[index];
366-
transaction.addInput(new BitGoJS.TransactionIn({
367-
outpoint: { hash: unspent.transaction_hash, index: unspent.output_index },
368-
script: new BitGoJS.Script(unspent.script_hex),
369-
sequence: 4294967295
370-
}));
375+
var hash = new Buffer(unspent.transaction_hash, 'hex');
376+
hash = new Buffer(Array.prototype.reverse.call(hash));
377+
var index = unspent.output_index;
378+
var script = Script.fromHex(unspent.script_hex);
379+
var sequence = 0xffffffff;
380+
transaction.addInput(hash, index, sequence, script);
371381
totalValue += unspent.value;
372382
}
373383

374384
// Note: we haven't signed the inputs yet. When we sign them, the transaction will grow by
375385
// about 232 bytes per input (2 sigs + redeemscript + misc)
376-
var approximateSize = transaction.serialize().length + (232 * unspents.length);
386+
var approximateSize = transaction.toBuffer().length + (232 * unspents.length);
377387
var approximateFee = ((Math.floor(approximateSize / 1024)) + 1) * 0.0001 * 1e8;
378388
if (approximateFee > totalValue) {
379389
throw new Error("Insufficient funds to recover (Have your transactions confirmed yet?)");
@@ -384,22 +394,32 @@ var createTransaction = function() {
384394
console.log("Fee: " + approximateFee / 1e8 + "BTC");
385395

386396
// Create the output
387-
transaction.addOutput(new BitGoJS.Address(inputs.destination), totalValue);
397+
var script = Address.fromBase58Check(inputs.destination).toOutputScript();
398+
transaction.addOutput(Address.fromBase58Check(inputs.destination), totalValue);
399+
400+
var txb = TransactionBuilder.fromTransaction(transaction);
388401

389402
for (index in unspents) {
403+
index = parseInt(index);
390404
var unspent = unspents[index];
391-
var redeemScript = new BitGoJS.Script(unspent.redeemScript);
405+
var redeemScript = Script.fromHex(unspent.redeemScript);
392406

393-
console.log("Signing input " + (parseInt(index) + 1) + " of " + unspents.length);
407+
console.log("Signing input " + (index + 1) + " of " + unspents.length);
394408

395-
if (!transaction.signMultiSigWithKey(index, unspent.keys[0].key.eckey, redeemScript)) {
396-
throw new Error('Signature failure for user key');
409+
try {
410+
txb.sign(index, unspent.keys[0].key.privKey, redeemScript);
411+
} catch (e) {
412+
throw new Error('Signature failure for user key: ' + e);
397413
}
398-
if (!transaction.signMultiSigWithKey(index, unspent.keys[1].key.eckey, redeemScript)) {
399-
throw new Error('Signature failure for backup key');
414+
try {
415+
txb.sign(index, unspent.keys[1].key.privKey, redeemScript);
416+
} catch (e) {
417+
throw new Error('Signature failure for backup key: ' + e);
400418
}
401419
}
402420

421+
transaction = txb.build();
422+
403423
return Q.when();
404424
};
405425

@@ -408,7 +428,7 @@ var createTransaction = function() {
408428
// Actually send the fully created transaction to the bitcoin network.
409429
//
410430
var sendTransaction = function() {
411-
var tx = BitGoJS.Util.bytesToHex(transaction.serialize());
431+
var tx = transaction.toBuffer().toString('hex');
412432

413433
console.log("Sending transaction: " + tx);
414434

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "bitgo",
3-
"version": "0.9.26",
3+
"version": "0.10.0",
44
"description": "BitGo Javascript SDK",
55
"main": "./src/index.js",
66
"keywords": [
@@ -44,9 +44,13 @@
4444
"compile": "./node_modules/.bin/browserify ./src/index.js -s Bitcoin | ./node_modules/.bin/uglifyjs > BitGoJS-min.js",
4545
"compile-dbg": "./node_modules/.bin/browserify ./src/index.js -s Bitcoin | ./node_modules/.bin/uglifyjs --beautify > BitGoJS.js",
4646
"test": "npm run-script unit",
47-
"unit": "./node_modules/.bin/istanbul test ./node_modules/.bin/_mocha -- --timeout 10000 --reporter list test/*.js test/bitcoin/*.js"
47+
"unit": "./node_modules/.bin/istanbul test ./node_modules/.bin/_mocha -- --timeout 10000 --reporter list test/*.js"
4848
},
4949
"dependencies": {
50+
"bitcoinjs-lib": "1.5.4",
51+
"bs58": "2.0.1",
52+
"bs58check": "1.0.4",
53+
"bigi": "1.4.0",
5054
"chain-node": "0.0.17",
5155
"minimist": "0.2.0",
5256
"superagent": "0.18.0",

src/bitcoin/address.js

Lines changed: 0 additions & 110 deletions
This file was deleted.

0 commit comments

Comments
 (0)