From 7675cf14e4bd7643af61a95aa5231863434c5e0e Mon Sep 17 00:00:00 2001 From: booo Date: Wed, 28 Dec 2011 13:44:30 +0100 Subject: [PATCH 1/4] src/wallet.js: retab file --- src/wallet.js | 412 +++++++++++++++++++++++++------------------------- 1 file changed, 206 insertions(+), 206 deletions(-) diff --git a/src/wallet.js b/src/wallet.js index f6ac8ad..31c8747 100755 --- a/src/wallet.js +++ b/src/wallet.js @@ -1,249 +1,249 @@ Bitcoin.Wallet = (function () { - var Script = Bitcoin.Script, - TransactionIn = Bitcoin.TransactionIn, - TransactionOut = Bitcoin.TransactionOut; + var Script = Bitcoin.Script, + TransactionIn = Bitcoin.TransactionIn, + TransactionOut = Bitcoin.TransactionOut; - var Wallet = function () { - // Keychain - var keys = []; - this.addressHashes = []; + var Wallet = function () { + // Keychain + var keys = []; + this.addressHashes = []; - // Transaction data - this.txIndex = {}; - this.unspentOuts = []; + // Transaction data + this.txIndex = {}; + this.unspentOuts = []; - // Other fields - this.addressPointer = 0; + // Other fields + this.addressPointer = 0; - this.addKey = function (key, pub) { - if (!(key instanceof Bitcoin.ECKey)) { - key = new Bitcoin.ECKey(key); - } - keys.push(key); + this.addKey = function (key, pub) { + if (!(key instanceof Bitcoin.ECKey)) { + key = new Bitcoin.ECKey(key); + } + keys.push(key); - if (pub) { - if ("string" === typeof pub) { - pub = Crypto.util.base64ToBytes(pub); - } - key.pub = pub; - } + if (pub) { + if ("string" === typeof pub) { + pub = Crypto.util.base64ToBytes(pub); + } + key.pub = pub; + } - this.addressHashes.push(key.getBitcoinAddress().getHashBase64()); - }; + this.addressHashes.push(key.getBitcoinAddress().getHashBase64()); + }; - this.addKeys = function (keys, pubs) { - if ("string" === typeof keys) { - keys = keys.split(','); - } - if ("string" === typeof pubs) { - pubs = pubs.split(','); - } - console.log(pubs); - if (Array.isArray(pubs) && keys.length == pubs.length) { - for (var i = 0; i < keys.length; i++) { - this.addKey(keys[i], pubs[i]); - } - } else { - for (var i = 0; i < keys.length; i++) { - this.addKey(keys[i]); - } - } - }; + this.addKeys = function (keys, pubs) { + if ("string" === typeof keys) { + keys = keys.split(','); + } + if ("string" === typeof pubs) { + pubs = pubs.split(','); + } + console.log(pubs); + if (Array.isArray(pubs) && keys.length == pubs.length) { + for (var i = 0; i < keys.length; i++) { + this.addKey(keys[i], pubs[i]); + } + } else { + for (var i = 0; i < keys.length; i++) { + this.addKey(keys[i]); + } + } + }; - this.getKeys = function () { - var serializedWallet = []; + this.getKeys = function () { + var serializedWallet = []; - for (var i = 0; i < keys.length; i++) { - serializedWallet.push(keys[i].toString('base64')); - } + for (var i = 0; i < keys.length; i++) { + serializedWallet.push(keys[i].toString('base64')); + } - return serializedWallet; - }; + return serializedWallet; + }; - this.getPubKeys = function () { - var pubs = []; + this.getPubKeys = function () { + var pubs = []; - for (var i = 0; i < keys.length; i++) { - pubs.push(Crypto.util.bytesToBase64(keys[i].getPub())); - } + for (var i = 0; i < keys.length; i++) { + pubs.push(Crypto.util.bytesToBase64(keys[i].getPub())); + } - return pubs; + return pubs; + }; + + this.clear = function () { + keys = []; + }; + + this.getLength = function () { + return keys.length; + }; + + this.getAllAddresses = function () { + var addresses = []; + for (var i = 0; i < keys.length; i++) { + addresses.push(keys[i].getBitcoinAddress()); + } + return addresses; + }; + + this.getCurAddress = function () { + if (keys[this.addressPointer]) { + return keys[this.addressPointer].getBitcoinAddress(); + } else { + return null; + } + }; + + this.getNextAddress = function () { + if (keys.length) { + // TODO: Create new addresses if we run out + this.addressPointer = (this.addressPointer + 1) % keys.length; + return keys[this.addressPointer].getBitcoinAddress(); + } else { + return null; + } + }; + + this.signWithKey = function (pubKeyHash, hash) { + pubKeyHash = Crypto.util.bytesToBase64(pubKeyHash); + for (var i = 0; i < this.addressHashes.length; i++) { + if (this.addressHashes[i] == pubKeyHash) { + return keys[i].sign(hash); + } + } + throw new Error("Missing key for signature"); + }; + + this.getPubKeyFromHash = function (pubKeyHash) { + pubKeyHash = Crypto.util.bytesToBase64(pubKeyHash); + for (var i = 0; i < this.addressHashes.length; i++) { + if (this.addressHashes[i] == pubKeyHash) { + console.log(Crypto.util.bytesToBase64(Bitcoin.Util.sha256ripe160(keys[i].getPub())), pubKeyHash); + return keys[i].getPub(); + } + } + throw new Error("Hash unknown"); + }; }; - this.clear = function () { - keys = []; - }; - - this.getLength = function () { - return keys.length; + Wallet.prototype.generateAddress = function () { + this.addKey(new Bitcoin.ECKey()); }; - this.getAllAddresses = function () { - var addresses = []; - for (var i = 0; i < keys.length; i++) { - addresses.push(keys[i].getBitcoinAddress()); - } - return addresses; - }; + Wallet.prototype.process = function (tx) { + if (this.txIndex[tx.hash]) return; - this.getCurAddress = function () { - if (keys[this.addressPointer]) { - return keys[this.addressPointer].getBitcoinAddress(); - } else { - return null; - } - }; + // Gather outputs + for (var j = 0; j < tx.outs.length; j++) { + var txout = new TransactionOut(tx.outs[j]); + var hash = Crypto.util.bytesToBase64(txout.script.simpleOutPubKeyHash()); + for (var k = 0; k < this.addressHashes.length; k++) { + if (this.addressHashes[k] === hash) { + this.unspentOuts.push({tx: tx, index: j, out: txout}); + break; + } + } + } - this.getNextAddress = function () { - if (keys.length) { - // TODO: Create new addresses if we run out - this.addressPointer = (this.addressPointer + 1) % keys.length; - return keys[this.addressPointer].getBitcoinAddress(); - } else { - return null; - } - }; + // Remove spent outputs + for (var j = 0; j < tx.ins.length; j++) { + var txin = new TransactionIn(tx.ins[j]); + var pubkey = txin.script.simpleInPubKey(); + var hash = Crypto.util.bytesToBase64(Bitcoin.Util.sha256ripe160(pubkey)); + for (var k = 0; k < this.addressHashes.length; k++) { + if (this.addressHashes[k] === hash) { + for (var l = 0; l < this.unspentOuts.length; l++) { + if (txin.outpoint.hash == this.unspentOuts[l].tx.hash && + txin.outpoint.index == this.unspentOuts[l].index) { + this.unspentOuts.splice(l, 1); + } + } + break; + } + } + } - this.signWithKey = function (pubKeyHash, hash) { - pubKeyHash = Crypto.util.bytesToBase64(pubKeyHash); - for (var i = 0; i < this.addressHashes.length; i++) { - if (this.addressHashes[i] == pubKeyHash) { - return keys[i].sign(hash); - } - } - throw new Error("Missing key for signature"); - }; + // Index transaction + this.txIndex[tx.hash] = tx; + }; - this.getPubKeyFromHash = function (pubKeyHash) { - pubKeyHash = Crypto.util.bytesToBase64(pubKeyHash); - for (var i = 0; i < this.addressHashes.length; i++) { - if (this.addressHashes[i] == pubKeyHash) { - console.log(Crypto.util.bytesToBase64(Bitcoin.Util.sha256ripe160(keys[i].getPub())), pubKeyHash); - return keys[i].getPub(); - } - } - throw new Error("Hash unknown"); - }; - }; + Wallet.prototype.getBalance = function () { + var balance = BigInteger.valueOf(0); + for (var i = 0; i < this.unspentOuts.length; i++) { + var txout = this.unspentOuts[i].out; + balance = balance.add(Bitcoin.Util.valueToBigInt(txout.value)); + } + return balance; + }; - Wallet.prototype.generateAddress = function () { - this.addKey(new Bitcoin.ECKey()); - }; + Wallet.prototype.createSend = function (address, sendValue, feeValue) { + var selectedOuts = []; + var txValue = sendValue.add(feeValue); + var availableValue = BigInteger.ZERO; + for (var i = 0; i < this.unspentOuts.length; i++) { + selectedOuts.push(this.unspentOuts[i]); + availableValue = availableValue.add(Bitcoin.Util.valueToBigInt(this.unspentOuts[i].out.value)); - Wallet.prototype.process = function (tx) { - if (this.txIndex[tx.hash]) return; + if (availableValue.compareTo(txValue) >= 0) break; + } - // Gather outputs - for (var j = 0; j < tx.outs.length; j++) { - var txout = new TransactionOut(tx.outs[j]); - var hash = Crypto.util.bytesToBase64(txout.script.simpleOutPubKeyHash()); - for (var k = 0; k < this.addressHashes.length; k++) { - if (this.addressHashes[k] === hash) { - this.unspentOuts.push({tx: tx, index: j, out: txout}); - break; - } - } - } + if (availableValue.compareTo(txValue) < 0) { + throw new Error('Insufficient funds.'); + } - // Remove spent outputs - for (var j = 0; j < tx.ins.length; j++) { - var txin = new TransactionIn(tx.ins[j]); - var pubkey = txin.script.simpleInPubKey(); - var hash = Crypto.util.bytesToBase64(Bitcoin.Util.sha256ripe160(pubkey)); - for (var k = 0; k < this.addressHashes.length; k++) { - if (this.addressHashes[k] === hash) { - for (var l = 0; l < this.unspentOuts.length; l++) { - if (txin.outpoint.hash == this.unspentOuts[l].tx.hash && - txin.outpoint.index == this.unspentOuts[l].index) { - this.unspentOuts.splice(l, 1); - } - } - break; - } - } - } + console.log(selectedOuts); - // Index transaction - this.txIndex[tx.hash] = tx; - }; + var changeValue = availableValue.subtract(txValue); - Wallet.prototype.getBalance = function () { - var balance = BigInteger.valueOf(0); - for (var i = 0; i < this.unspentOuts.length; i++) { - var txout = this.unspentOuts[i].out; - balance = balance.add(Bitcoin.Util.valueToBigInt(txout.value)); - } - return balance; - }; + var sendTx = new Bitcoin.Transaction(); - Wallet.prototype.createSend = function (address, sendValue, feeValue) { - var selectedOuts = []; - var txValue = sendValue.add(feeValue); - var availableValue = BigInteger.ZERO; - for (var i = 0; i < this.unspentOuts.length; i++) { - selectedOuts.push(this.unspentOuts[i]); - availableValue = availableValue.add(Bitcoin.Util.valueToBigInt(this.unspentOuts[i].out.value)); + for (var i = 0; i < selectedOuts.length; i++) { + sendTx.addInput(selectedOuts[i].tx, selectedOuts[i].index); + } - if (availableValue.compareTo(txValue) >= 0) break; - } + sendTx.addOutput(address, sendValue); + if (changeValue.compareTo(BigInteger.ZERO) > 0) { + sendTx.addOutput(this.getNextAddress(), changeValue); + } - if (availableValue.compareTo(txValue) < 0) { - throw new Error('Insufficient funds.'); - } + var hashType = 1; // SIGHASH_ALL - console.log(selectedOuts); + for (var i = 0; i < sendTx.ins.length; i++) { + var hash = sendTx.hashTransactionForSignature(selectedOuts[i].out.script, i, hashType); + var pubKeyHash = selectedOuts[i].out.script.simpleOutPubKeyHash(); + var signature = this.signWithKey(pubKeyHash, hash); - var changeValue = availableValue.subtract(txValue); + // Append hash type + signature.push(parseInt(hashType)); - var sendTx = new Bitcoin.Transaction(); + sendTx.ins[i].script = Script.createInputScript(signature, this.getPubKeyFromHash(pubKeyHash)); + } - for (var i = 0; i < selectedOuts.length; i++) { - sendTx.addInput(selectedOuts[i].tx, selectedOuts[i].index); - } + console.log(sendTx); - sendTx.addOutput(address, sendValue); - if (changeValue.compareTo(BigInteger.ZERO) > 0) { - sendTx.addOutput(this.getNextAddress(), changeValue); - } + console.log("pubkey: "+Crypto.util.bytesToHex(this.getPubKeyFromHash(pubKeyHash))); - var hashType = 1; // SIGHASH_ALL + return sendTx; + }; - for (var i = 0; i < sendTx.ins.length; i++) { - var hash = sendTx.hashTransactionForSignature(selectedOuts[i].out.script, i, hashType); - var pubKeyHash = selectedOuts[i].out.script.simpleOutPubKeyHash(); - var signature = this.signWithKey(pubKeyHash, hash); + Wallet.prototype.clearTransactions = function () { + this.txIndex = {}; + this.unspentOuts = []; + }; - // Append hash type - signature.push(parseInt(hashType)); + /** + * Check to see if a pubKeyHash belongs to this wallet. + */ + Wallet.prototype.hasHash = function (hash) { + if (Bitcoin.Util.isArray(hash)) hash = Crypto.util.bytesToBase64(hash); - sendTx.ins[i].script = Script.createInputScript(signature, this.getPubKeyFromHash(pubKeyHash)); - } + // TODO: Just create an object with base64 hashes as keys for faster lookup + for (var k = 0; k < this.addressHashes.length; k++) { + if (this.addressHashes[k] === hash) return true; + } + return false; + }; - console.log(sendTx); - - console.log("pubkey: "+Crypto.util.bytesToHex(this.getPubKeyFromHash(pubKeyHash))); - - return sendTx; - }; - - Wallet.prototype.clearTransactions = function () { - this.txIndex = {}; - this.unspentOuts = []; - }; - - /** - * Check to see if a pubKeyHash belongs to this wallet. - */ - Wallet.prototype.hasHash = function (hash) { - if (Bitcoin.Util.isArray(hash)) hash = Crypto.util.bytesToBase64(hash); - - // TODO: Just create an object with base64 hashes as keys for faster lookup - for (var k = 0; k < this.addressHashes.length; k++) { - if (this.addressHashes[k] === hash) return true; - } - return false; - }; - - return Wallet; + return Wallet; })(); From 57d26950b9e4835090f153e81f4d90e4f534380f Mon Sep 17 00:00:00 2001 From: booo Date: Wed, 28 Dec 2011 13:47:55 +0100 Subject: [PATCH 2/4] src/wallet.js: remove console.log statements --- src/wallet.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/wallet.js b/src/wallet.js index 31c8747..379e54c 100755 --- a/src/wallet.js +++ b/src/wallet.js @@ -38,7 +38,6 @@ Bitcoin.Wallet = (function () { if ("string" === typeof pubs) { pubs = pubs.split(','); } - console.log(pubs); if (Array.isArray(pubs) && keys.length == pubs.length) { for (var i = 0; i < keys.length; i++) { this.addKey(keys[i], pubs[i]); @@ -118,7 +117,6 @@ Bitcoin.Wallet = (function () { pubKeyHash = Crypto.util.bytesToBase64(pubKeyHash); for (var i = 0; i < this.addressHashes.length; i++) { if (this.addressHashes[i] == pubKeyHash) { - console.log(Crypto.util.bytesToBase64(Bitcoin.Util.sha256ripe160(keys[i].getPub())), pubKeyHash); return keys[i].getPub(); } } @@ -191,7 +189,6 @@ Bitcoin.Wallet = (function () { throw new Error('Insufficient funds.'); } - console.log(selectedOuts); var changeValue = availableValue.subtract(txValue); @@ -219,10 +216,6 @@ Bitcoin.Wallet = (function () { sendTx.ins[i].script = Script.createInputScript(signature, this.getPubKeyFromHash(pubKeyHash)); } - console.log(sendTx); - - console.log("pubkey: "+Crypto.util.bytesToHex(this.getPubKeyFromHash(pubKeyHash))); - return sendTx; }; From 3445ae2a3649e40a4ec639654defed1113e3980a Mon Sep 17 00:00:00 2001 From: booo Date: Wed, 28 Dec 2011 13:50:58 +0100 Subject: [PATCH 3/4] src/wallet.js: use jshint --- src/wallet.js | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/wallet.js b/src/wallet.js index 379e54c..0fd3406 100755 --- a/src/wallet.js +++ b/src/wallet.js @@ -38,12 +38,13 @@ Bitcoin.Wallet = (function () { if ("string" === typeof pubs) { pubs = pubs.split(','); } + var i; if (Array.isArray(pubs) && keys.length == pubs.length) { - for (var i = 0; i < keys.length; i++) { + for (i = 0; i < keys.length; i++) { this.addKey(keys[i], pubs[i]); } } else { - for (var i = 0; i < keys.length; i++) { + for (i = 0; i < keys.length; i++) { this.addKey(keys[i]); } } @@ -131,11 +132,14 @@ Bitcoin.Wallet = (function () { Wallet.prototype.process = function (tx) { if (this.txIndex[tx.hash]) return; + var j; + var k; + var hash; // Gather outputs - for (var j = 0; j < tx.outs.length; j++) { + for (j = 0; j < tx.outs.length; j++) { var txout = new TransactionOut(tx.outs[j]); - var hash = Crypto.util.bytesToBase64(txout.script.simpleOutPubKeyHash()); - for (var k = 0; k < this.addressHashes.length; k++) { + hash = Crypto.util.bytesToBase64(txout.script.simpleOutPubKeyHash()); + for (k = 0; k < this.addressHashes.length; k++) { if (this.addressHashes[k] === hash) { this.unspentOuts.push({tx: tx, index: j, out: txout}); break; @@ -144,11 +148,11 @@ Bitcoin.Wallet = (function () { } // Remove spent outputs - for (var j = 0; j < tx.ins.length; j++) { + for (j = 0; j < tx.ins.length; j++) { var txin = new TransactionIn(tx.ins[j]); var pubkey = txin.script.simpleInPubKey(); - var hash = Crypto.util.bytesToBase64(Bitcoin.Util.sha256ripe160(pubkey)); - for (var k = 0; k < this.addressHashes.length; k++) { + hash = Crypto.util.bytesToBase64(Bitcoin.Util.sha256ripe160(pubkey)); + for (k = 0; k < this.addressHashes.length; k++) { if (this.addressHashes[k] === hash) { for (var l = 0; l < this.unspentOuts.length; l++) { if (txin.outpoint.hash == this.unspentOuts[l].tx.hash && @@ -178,7 +182,8 @@ Bitcoin.Wallet = (function () { var selectedOuts = []; var txValue = sendValue.add(feeValue); var availableValue = BigInteger.ZERO; - for (var i = 0; i < this.unspentOuts.length; i++) { + var i; + for (i = 0; i < this.unspentOuts.length; i++) { selectedOuts.push(this.unspentOuts[i]); availableValue = availableValue.add(Bitcoin.Util.valueToBigInt(this.unspentOuts[i].out.value)); @@ -194,7 +199,7 @@ Bitcoin.Wallet = (function () { var sendTx = new Bitcoin.Transaction(); - for (var i = 0; i < selectedOuts.length; i++) { + for (i = 0; i < selectedOuts.length; i++) { sendTx.addInput(selectedOuts[i].tx, selectedOuts[i].index); } @@ -205,13 +210,13 @@ Bitcoin.Wallet = (function () { var hashType = 1; // SIGHASH_ALL - for (var i = 0; i < sendTx.ins.length; i++) { + for (i = 0; i < sendTx.ins.length; i++) { var hash = sendTx.hashTransactionForSignature(selectedOuts[i].out.script, i, hashType); var pubKeyHash = selectedOuts[i].out.script.simpleOutPubKeyHash(); var signature = this.signWithKey(pubKeyHash, hash); // Append hash type - signature.push(parseInt(hashType)); + signature.push(parseInt(hashType, 10)); sendTx.ins[i].script = Script.createInputScript(signature, this.getPubKeyFromHash(pubKeyHash)); } From ef903bae07c600bb0eb1e17e406646a494205f43 Mon Sep 17 00:00:00 2001 From: booo Date: Wed, 28 Dec 2011 16:29:16 +0100 Subject: [PATCH 4/4] src/wallet: getNextAddresss: add new address if necessary --- src/wallet.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/wallet.js b/src/wallet.js index 0fd3406..28f3c1f 100755 --- a/src/wallet.js +++ b/src/wallet.js @@ -95,13 +95,11 @@ Bitcoin.Wallet = (function () { }; this.getNextAddress = function () { - if (keys.length) { - // TODO: Create new addresses if we run out - this.addressPointer = (this.addressPointer + 1) % keys.length; - return keys[this.addressPointer].getBitcoinAddress(); - } else { - return null; + this.addressPointer++; + if(!keys[this.addressPointer]) { + this.generateAddress(); } + return keys[this.addressPointer].getBitcoinAddress(); }; this.signWithKey = function (pubKeyHash, hash) {