diff --git a/Transaction.js b/Transaction.js index 37d2ad8..1da4964 100644 --- a/Transaction.js +++ b/Transaction.js @@ -679,6 +679,56 @@ Transaction.prototype.parse = function (parser) { this.calcHash(); }; +/* + * selectUnspent + * + * Selects some unspend outputs for later usage in tx inputs + * + * @unspentArray: unspent array (UTXO) avaible on the form: + * [{ + * address: "mqSjTad2TKbPcKQ3Jq4kgCkKatyN44UMgZ", + * hash: "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1", + * scriptPubKey: "76a9146ce4e1163eb18939b1440c42844d5f0261c0338288ac", + * vout: 1, + * amount: 0.01, + * }, [...] + * ] + * This is compatible con insight's /utxo API. + * NOTE that amount is in BTCs! (as returned in insight and bitcoind. + * + * @totalNeededAmount: output transaction amount in BTC, including fee + * + * + * Return the selected outputs or null if there are not enough funds. + * It does not check for confirmations. The unspendArray should be filtered. + * + */ +Transaction.selectUnspent = function (unspentArray, totalNeededAmount) { + + // TODO we could randomize or select the selection + + var selected = []; + var l = unspentArray.length; + var totalSat = bignum(0); + var totalNeededAmountSat = bignum(totalNeededAmount * util.COIN); + var fullfill = false; + + for(var i = 0; i= 0) { + fullfill = true; + break; + } + } + if (!fullfill) return []; + return selected; +} + + + var TransactionInputsCache = exports.TransactionInputsCache = function TransactionInputsCache(tx) { diff --git a/test/data/unspends.json b/test/data/unspends.json new file mode 100644 index 0000000..d9fac53 --- /dev/null +++ b/test/data/unspends.json @@ -0,0 +1,24 @@ +[ + { + "address": "mqSjTad2TKbPcKQ3Jq4kgCkKatyN44UMgZ", + "txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1", + "scriptPubKey": "76a9146ce4e1163eb18939b1440c42844d5f0261c0338288ac", + "vout": 1, + "amount": 0.01 + }, + { + "address": "mqSjTad2TKbPcKQ3Jq4kgCkKatyN44UMgZ", + "txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc2", + "scriptPubKey": "76a9146ce4e1163eb18939b1440c42844d5f0261c0338288ad", + "vout": 1, + "amount": 0.1 + }, + { + "address": "mqSjTad2TKbPcKQ3Jq4kgCkKatyN44UMgZ", + "txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc3", + "scriptPubKey": "76a9146ce4e1163eb18939b1440c42844d5f0261c0338288ae", + "vout": 3, + "amount": 1 + } +] + diff --git a/test/test.Transaction.js b/test/test.Transaction.js index ff2dc4b..c8bf0b0 100644 --- a/test/test.Transaction.js +++ b/test/test.Transaction.js @@ -25,11 +25,40 @@ describe('Transaction', function() { should.exist(In); should.exist(Out); }); + + it('should be able to create instance', function() { var t = new Transaction(); should.exist(t); }); + + it('should be able to select unspents', function() { + var u = Transaction.selectUnspent(testdata.dataUnspends,1.0); + u.length.should.equal(3); + u = Transaction.selectUnspent(testdata.dataUnspends,0.5); + u.length.should.equal(3); + u = Transaction.selectUnspent(testdata.dataUnspends,0.1); + u.length.should.equal(2); + u = Transaction.selectUnspent(testdata.dataUnspends,0.05); + u.length.should.equal(2); + u = Transaction.selectUnspent(testdata.dataUnspends,0.015); + u.length.should.equal(2); + u = Transaction.selectUnspent(testdata.dataUnspends,0.01); + u.length.should.equal(1); + should.exist(u[0].amount); + should.exist(u[0].txid); + should.exist(u[0].scriptPubKey); + should.exist(u[0].vout); + }); + + + it.skip('should be able to create instance thru #create', function() { + var t = Transaction.create({ + }); + should.exist(t); + }); + // Read tests from test/data/tx_valid.json // Format is an array of arrays // Inner arrays are either [ "comment" ] diff --git a/test/testdata.js b/test/testdata.js index dd05be7..6eef35a 100644 --- a/test/testdata.js +++ b/test/testdata.js @@ -7,6 +7,8 @@ var dataTxValid = JSON.parse(fs.readFileSync('test/data/tx_valid.json')); var dataTxInvalid = JSON.parse(fs.readFileSync('test/data/tx_invalid.json')); var dataScriptValid = JSON.parse(fs.readFileSync('test/data/script_valid.json')); var dataScriptInvalid = JSON.parse(fs.readFileSync('test/data/script_invalid.json')); +var dataUnspends = JSON.parse(fs.readFileSync('test/data/unspends.json')); + module.exports.dataValid = dataValid; module.exports.dataInvalid = dataInvalid; @@ -16,3 +18,4 @@ module.exports.dataTxInvalid = dataTxInvalid; module.exports.dataScriptValid = dataScriptValid; module.exports.dataScriptInvalid = dataScriptInvalid; module.exports.dataScriptAll = dataScriptValid.concat(dataScriptInvalid); +module.exports.dataUnspends = dataUnspends;