new interfase for create TX (select + prepare + sign)
This commit is contained in:
parent
42d30f44a8
commit
0c83ecf5fb
203
Transaction.js
203
Transaction.js
|
@ -16,7 +16,7 @@ var WalletKey = imports.WalletKey || require('./WalletKey');
|
||||||
var PrivateKey = imports.PrivateKey || require('./PrivateKey');
|
var PrivateKey = imports.PrivateKey || require('./PrivateKey');
|
||||||
|
|
||||||
var COINBASE_OP = Buffer.concat([util.NULL_HASH, new Buffer('FFFFFFFF', 'hex')]);
|
var COINBASE_OP = Buffer.concat([util.NULL_HASH, new Buffer('FFFFFFFF', 'hex')]);
|
||||||
var DEFAULT_FEE = 0.0001;
|
var DEFAULT_FEE = 0.001;
|
||||||
|
|
||||||
function TransactionIn(data) {
|
function TransactionIn(data) {
|
||||||
if ("object" !== typeof data) {
|
if ("object" !== typeof data) {
|
||||||
|
@ -690,20 +690,7 @@ Transaction.prototype.parse = function (parser) {
|
||||||
*
|
*
|
||||||
* Selects some unspent outputs for later usage in tx inputs
|
* Selects some unspent outputs for later usage in tx inputs
|
||||||
*
|
*
|
||||||
* @unspentArray: unspent array (UTXO) avaible on the form:
|
* @utxos
|
||||||
* [{
|
|
||||||
* address: "mqSjTad2TKbPcKQ3Jq4kgCkKatyN44UMgZ",
|
|
||||||
* hash: "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1",
|
|
||||||
* scriptPubKey: "76a9146ce4e1163eb18939b1440c42844d5f0261c0338288ac",
|
|
||||||
* vout: 1,
|
|
||||||
* amount: 0.01,
|
|
||||||
* confirmations: 3
|
|
||||||
* }, [...]
|
|
||||||
* ]
|
|
||||||
* This is compatible con insight's utxo API.
|
|
||||||
* That amount is in BTCs (as returned in insight and bitcoind).
|
|
||||||
* amountSat (instead of amount) can be given to provide amount in satochis.
|
|
||||||
*
|
|
||||||
* @totalNeededAmount: output transaction amount in BTC, including fee
|
* @totalNeededAmount: output transaction amount in BTC, including fee
|
||||||
* @allowUnconfirmed: false (allow selecting unconfirmed utxos)
|
* @allowUnconfirmed: false (allow selecting unconfirmed utxos)
|
||||||
*
|
*
|
||||||
|
@ -715,13 +702,13 @@ Transaction.prototype.parse = function (parser) {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Transaction.selectUnspent = function (unspentArray, totalNeededAmount, allowUnconfirmed) {
|
Transaction.selectUnspent = function (utxos, totalNeededAmount, allowUnconfirmed) {
|
||||||
|
|
||||||
var minConfirmationSteps = [6,1];
|
var minConfirmationSteps = [6,1];
|
||||||
if (allowUnconfirmed) minConfirmationSteps.push(0);
|
if (allowUnconfirmed) minConfirmationSteps.push(0);
|
||||||
|
|
||||||
var ret = [];
|
var ret = [];
|
||||||
var l = unspentArray.length;
|
var l = utxos.length;
|
||||||
var totalSat = bignum(0);
|
var totalSat = bignum(0);
|
||||||
var totalNeededAmountSat = util.parseValue(totalNeededAmount);
|
var totalNeededAmountSat = util.parseValue(totalNeededAmount);
|
||||||
var fulfill = false;
|
var fulfill = false;
|
||||||
|
@ -730,7 +717,7 @@ Transaction.selectUnspent = function (unspentArray, totalNeededAmount, allowUnco
|
||||||
do {
|
do {
|
||||||
var minConfirmations = minConfirmationSteps.shift();
|
var minConfirmations = minConfirmationSteps.shift();
|
||||||
for(var i = 0; i<l; i++) {
|
for(var i = 0; i<l; i++) {
|
||||||
var u = unspentArray[i];
|
var u = utxos[i];
|
||||||
|
|
||||||
var c = u.confirmations || 0;
|
var c = u.confirmations || 0;
|
||||||
|
|
||||||
|
@ -776,39 +763,18 @@ Transaction._scriptForAddress = function (addressString) {
|
||||||
return script;
|
return script;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
Transaction._sumOutputs = function(outs) {
|
||||||
* create
|
var valueOutSat = bignum(0);
|
||||||
*
|
var l = outs.length;
|
||||||
* creates a transaction
|
|
||||||
*
|
|
||||||
* @ins
|
|
||||||
* a selected set of utxos, as described on selectUnspent
|
|
||||||
* @outs
|
|
||||||
* an array of [{
|
|
||||||
* address: xx,
|
|
||||||
* amount:0.001
|
|
||||||
* },...]
|
|
||||||
* @opts
|
|
||||||
* {
|
|
||||||
* remainderAddress: null,
|
|
||||||
* fee: 0.001,
|
|
||||||
* lockTime: null,
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* Amounts are in BTC. instead of fee and amount; feeSat and amountSat can be given,
|
|
||||||
* repectively, to provide amounts in satoshis.
|
|
||||||
*
|
|
||||||
* (TODO: should we use uBTC already?)
|
|
||||||
*
|
|
||||||
* If no remainderAddress is given, and there is a remainderAddress
|
|
||||||
* first in address will be used. (TODO: is this is reasonable?)
|
|
||||||
*
|
|
||||||
* The address from the inputs will be added to the Transaction object
|
|
||||||
* for latter signing
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
Transaction.create = function (ins, outs, opts) {
|
for(var i=0;i<outs.length;i++) {
|
||||||
|
var sat = outs[i].amountSat || util.parseValue(outs[i].amount);
|
||||||
|
valueOutSat = valueOutSat.add(sat);
|
||||||
|
}
|
||||||
|
return valueOutSat;
|
||||||
|
}
|
||||||
|
|
||||||
|
Transaction.prepare = function (ins, outs, opts) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
|
|
||||||
var feeSat = opts.feeSat || util.parseValue(opts.fee || DEFAULT_FEE);
|
var feeSat = opts.feeSat || util.parseValue(opts.fee || DEFAULT_FEE);
|
||||||
|
@ -818,7 +784,6 @@ Transaction.create = function (ins, outs, opts) {
|
||||||
txobj.ins = [];
|
txobj.ins = [];
|
||||||
txobj.outs = [];
|
txobj.outs = [];
|
||||||
|
|
||||||
var inputMap = [];
|
|
||||||
|
|
||||||
var l = ins.length;
|
var l = ins.length;
|
||||||
var valueInSat = bignum(0);
|
var valueInSat = bignum(0);
|
||||||
|
@ -838,20 +803,9 @@ Transaction.create = function (ins, outs, opts) {
|
||||||
|
|
||||||
txin.o = Buffer.concat([hashReversed, voutBuf]);
|
txin.o = Buffer.concat([hashReversed, voutBuf]);
|
||||||
txobj.ins.push(txin);
|
txobj.ins.push(txin);
|
||||||
inputMap[i]= {
|
|
||||||
address: ins[i].address,
|
|
||||||
scriptPubKey: ins[i].scriptPubKey
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var valueOutSat = Transaction._sumOutputs(outs);
|
||||||
var valueOutSat = bignum(0);
|
|
||||||
l = outs.length;
|
|
||||||
|
|
||||||
for(var i=0;i<outs.length;i++) {
|
|
||||||
var sat = outs[i].amountSat || util.parseValue(outs[i].amount);
|
|
||||||
valueOutSat = valueOutSat.add(sat);
|
|
||||||
}
|
|
||||||
valueOutSat = valueOutSat.add(feeSat);
|
valueOutSat = valueOutSat.add(feeSat);
|
||||||
|
|
||||||
if (valueInSat.cmp(valueOutSat)<0) {
|
if (valueInSat.cmp(valueOutSat)<0) {
|
||||||
|
@ -886,38 +840,54 @@ Transaction.create = function (ins, outs, opts) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var tx = new Transaction(txobj);
|
return new Transaction(txobj);
|
||||||
tx.inputMap = inputMap;
|
|
||||||
return tx;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Transaction.prototype.isComplete = function () {
|
||||||
|
var l = this.ins.length;
|
||||||
|
|
||||||
|
var ret = true;
|
||||||
|
for (var i=0; i<l; i++) {
|
||||||
|
if ( buffertools.compare(this.ins[i].s,util.EMPTY_BUFFER)===0 ) {
|
||||||
|
ret = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sign
|
* sign
|
||||||
*
|
*
|
||||||
* signs the transaction
|
* signs the transaction
|
||||||
*
|
*
|
||||||
|
* @ utxos
|
||||||
* @keypairs
|
* @keypairs
|
||||||
* an array of strings representing private keys to sign the
|
|
||||||
* transaction in WIF private key format OR WalletKey objects
|
|
||||||
*
|
|
||||||
* @opts
|
* @opts
|
||||||
* signhash: Transaction.SIGHASH_ALL
|
* signhash: Transaction.SIGHASH_ALL
|
||||||
*
|
*
|
||||||
* Return the 'completeness' status of the tx (i.e, if all inputs are signed).
|
* Return the 'completeness' status of the tx (i.e, if all inputs are signed).
|
||||||
*
|
*
|
||||||
* To sign a TX, the TX must contain .inputMap to match private keys
|
|
||||||
* with inputs and scriptPubKey
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Transaction.prototype.sign = function (keys, opts) {
|
Transaction.prototype.sign = function (selectedUtxos, keys, opts) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var complete = false;
|
var complete = false;
|
||||||
var m = keys.length;
|
var m = keys.length;
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
var signhash = opts.signhash || SIGHASH_ALL;
|
var signhash = opts.signhash || SIGHASH_ALL;
|
||||||
|
|
||||||
if (!self.inputMap) {
|
if (selectedUtxos.length !== self.ins.length)
|
||||||
throw new Error('this TX does not have information about input address, cannot be signed');
|
throw new Error('given selectedUtxos do not match tx inputs');
|
||||||
|
|
||||||
|
var inputMap = [];
|
||||||
|
var l = selectedUtxos.length;
|
||||||
|
for(var i=0; i<l; i++) {
|
||||||
|
inputMap[i]= {
|
||||||
|
address: selectedUtxos[i].address,
|
||||||
|
scriptPubKey: selectedUtxos[i].scriptPubKey
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//prepare keys
|
//prepare keys
|
||||||
|
@ -945,14 +915,14 @@ Transaction.prototype.sign = function (keys, opts) {
|
||||||
l = self.ins.length;
|
l = self.ins.length;
|
||||||
for(var i=0;i<l;i++) {
|
for(var i=0;i<l;i++) {
|
||||||
var aIn = self.ins[i];
|
var aIn = self.ins[i];
|
||||||
var wk = walletKeyMap[self.inputMap[i].address];
|
var wk = walletKeyMap[inputMap[i].address];
|
||||||
|
|
||||||
if (typeof wk === 'undefined') {
|
if (typeof wk === 'undefined') {
|
||||||
if ( buffertools.compare(aIn.s,util.EMPTY_BUFFER)!==0 )
|
if ( buffertools.compare(aIn.s,util.EMPTY_BUFFER)!==0 )
|
||||||
inputSigned++;
|
inputSigned++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var scriptBuf = new Buffer(self.inputMap[i].scriptPubKey, 'hex');
|
var scriptBuf = new Buffer(inputMap[i].scriptPubKey, 'hex');
|
||||||
var s = new Script(scriptBuf);
|
var s = new Script(scriptBuf);
|
||||||
if (s.classify() !== Script.TX_PUBKEYHASH) {
|
if (s.classify() !== Script.TX_PUBKEYHASH) {
|
||||||
throw new Error('input:'+i+' script type:'+ s.getRawOutType() +' not supported yet');
|
throw new Error('input:'+i+' script type:'+ s.getRawOutType() +' not supported yet');
|
||||||
|
@ -991,6 +961,87 @@ Transaction.prototype.sign = function (keys, opts) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create
|
||||||
|
*
|
||||||
|
* creates and signs a transaction
|
||||||
|
*
|
||||||
|
* @utxos
|
||||||
|
* unspent outputs array (UTXO), using the following format:
|
||||||
|
* [{
|
||||||
|
* address: "mqSjTad2TKbPcKQ3Jq4kgCkKatyN44UMgZ",
|
||||||
|
* hash: "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1",
|
||||||
|
* scriptPubKey: "76a9146ce4e1163eb18939b1440c42844d5f0261c0338288ac",
|
||||||
|
* vout: 1,
|
||||||
|
* amount: 0.01,
|
||||||
|
* confirmations: 3
|
||||||
|
* }, ...
|
||||||
|
* ]
|
||||||
|
* This is compatible con insight's utxo API.
|
||||||
|
* That amount is in BTCs (as returned in insight and bitcoind).
|
||||||
|
* amountSat (instead of amount) can be given to provide amount in satochis.
|
||||||
|
*
|
||||||
|
|
||||||
|
* @outs
|
||||||
|
* an array of [{
|
||||||
|
* address: xx,
|
||||||
|
* amount:0.001
|
||||||
|
* },...]
|
||||||
|
*
|
||||||
|
* @keys
|
||||||
|
* an array of strings representing private keys to sign the
|
||||||
|
* transaction in WIF private key format OR WalletKey objects
|
||||||
|
*
|
||||||
|
* @opts
|
||||||
|
* {
|
||||||
|
* remainderAddress: null,
|
||||||
|
* fee: 0.001,
|
||||||
|
* lockTime: null,
|
||||||
|
* allowUnconfirmed: false,
|
||||||
|
* signhash: SIGHASH_ALL
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Amounts are in BTC. instead of fee and amount; feeSat and amountSat can be given,
|
||||||
|
* repectively, to provide amounts in satoshis.
|
||||||
|
*
|
||||||
|
* If no remainderAddress is given, and there is a remainderAddress
|
||||||
|
* first in address will be used. (TODO: is this is reasonable?)
|
||||||
|
*
|
||||||
|
* if not keys are provided, the transaction will no be signed. .sign can be used to
|
||||||
|
* sign it later.
|
||||||
|
*
|
||||||
|
* The Transaction creation is handled in 3 steps:
|
||||||
|
* .selectUnspent
|
||||||
|
* .prepare
|
||||||
|
* .sign
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
Transaction.create = function (utxos, outs, keys, opts) {
|
||||||
|
|
||||||
|
var valueOutSat = Transaction
|
||||||
|
._sumOutputs(outs)
|
||||||
|
.add(DEFAULT_FEE * util.COIN);
|
||||||
|
|
||||||
|
var selectedUtxos = Transaction
|
||||||
|
.selectUnspent(utxos,valueOutSat / util.COIN, opts.allowUnconfirmed);
|
||||||
|
|
||||||
|
if (!selectedUtxos) {
|
||||||
|
throw new Error(
|
||||||
|
'the given UTXOs dont sum up the given outputs: '
|
||||||
|
+ valueOutSat.toString()
|
||||||
|
+ ' SAT'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = Transaction.prepare(selectedUtxos, outs, opts);
|
||||||
|
//TODO interate with the new TX fee
|
||||||
|
if (keys) tx.sign(selectedUtxos, keys);
|
||||||
|
return tx;
|
||||||
|
};
|
||||||
|
|
||||||
var TransactionInputsCache = exports.TransactionInputsCache =
|
var TransactionInputsCache = exports.TransactionInputsCache =
|
||||||
function TransactionInputsCache(tx)
|
function TransactionInputsCache(tx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -78,44 +78,49 @@ describe('Transaction', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var opts = {remainderAddress: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd'};
|
var opts = {
|
||||||
|
remainderAddress: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd',
|
||||||
|
allowUnconfirmed: true,
|
||||||
|
};
|
||||||
|
|
||||||
it('#create should be able to create instance', function() {
|
it('#create should be able to create instance', function() {
|
||||||
var utxos = Transaction.selectUnspent(testdata.dataUnspent,0.1);
|
var utxos =testdata.dataUnspent;
|
||||||
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
||||||
var tx = Transaction.create(utxos, outs, opts);
|
var tx = Transaction.create(utxos, outs, null, opts);
|
||||||
should.exist(tx);
|
should.exist(tx);
|
||||||
|
|
||||||
tx.version.should.equal(1);
|
tx.version.should.equal(1);
|
||||||
tx.ins.length.should.equal(2);
|
tx.ins.length.should.equal(2);
|
||||||
tx.outs.length.should.equal(2);
|
tx.outs.length.should.equal(2);
|
||||||
|
|
||||||
util.valueToBigInt(tx.outs[0].v).cmp(8000000).should.equal(0);
|
util.valueToBigInt(tx.outs[0].v).cmp(8000000).should.equal(0);
|
||||||
// remainder is 0.0299 here because unspent select utxos in order
|
// remainder is 0.0299 here because unspent select utxos in order
|
||||||
util.valueToBigInt(tx.outs[1].v).cmp(2990000).should.equal(0);
|
util.valueToBigInt(tx.outs[1].v).cmp(2900000).should.equal(0);
|
||||||
|
tx.isComplete().should.equal(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('#create should fail if not enough inputs ', function() {
|
it('#create should fail if not enough inputs ', function() {
|
||||||
var utxos = Transaction.selectUnspent(testdata.dataUnspent,1);
|
var utxos =testdata.dataUnspent;
|
||||||
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:80}];
|
||||||
Transaction
|
Transaction
|
||||||
.create
|
.create
|
||||||
.bind(utxos, outs, opts)
|
.bind(utxos, outs, null, opts)
|
||||||
.should.throw();
|
.should.throw();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('#create should create same output as bitcoind createrawtransaction ', function() {
|
it('#create should create same output as bitcoind createrawtransaction ', function() {
|
||||||
var utxos = Transaction.selectUnspent(testdata.dataUnspent,0.1);
|
var utxos =testdata.dataUnspent;
|
||||||
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
||||||
var tx = Transaction.create(utxos, outs, opts);
|
var tx = Transaction.create(utxos, outs, null, opts);
|
||||||
|
|
||||||
|
|
||||||
// string output generated from: bitcoind createrawtransaction '[{"txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1","vout":1},{"txid":"2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc2","vout":0} ]' '{"mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE":0.08,"mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd":0.0299}'
|
// string output generated from: bitcoind createrawtransaction '[{"txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1","vout":1},{"txid":"2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc2","vout":0} ]' '{"mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE":0.08,"mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd":0.0299}'
|
||||||
tx.serialize().toString('hex').should.equal('0100000002c1cf12ab89729d19d3cdec8ae531b5038d56c741006a105d532b3a7afa65c12a0100000000ffffffffc2cf12ab89729d19d3cdec8ae531b5038d56c741006a105d532b3a7afa65c12a0000000000ffffffff0200127a00000000001976a914774e603bafb717bd3f070e68bbcccfd907c77d1388acb09f2d00000000001976a914b00127584485a7cff0949ef0f6bc5575f06ce00d88ac00000000');
|
tx.serialize().toString('hex').should.equal('0100000002c1cf12ab89729d19d3cdec8ae531b5038d56c741006a105d532b3a7afa65c12a0100000000ffffffffc2cf12ab89729d19d3cdec8ae531b5038d56c741006a105d532b3a7afa65c12a0000000000ffffffff0200127a00000000001976a914774e603bafb717bd3f070e68bbcccfd907c77d1388ac20402c00000000001976a914b00127584485a7cff0949ef0f6bc5575f06ce00d88ac00000000');
|
||||||
|
|
||||||
// no remainder
|
// no remainder
|
||||||
outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
||||||
tx = Transaction.create(utxos, outs, {fee:0.03} );
|
tx = Transaction.create(utxos, outs, null, {fee:0.03} );
|
||||||
|
|
||||||
// string output generated from: bitcoind createrawtransaction '[{"txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1","vout":1},{"txid":"2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc2","vout":0} ]' '{"mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE":0.08}'
|
// string output generated from: bitcoind createrawtransaction '[{"txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1","vout":1},{"txid":"2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc2","vout":0} ]' '{"mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE":0.08}'
|
||||||
//
|
//
|
||||||
|
@ -123,39 +128,40 @@ describe('Transaction', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('#sign should sign a tx', function() {
|
it('#sign should sign a tx', function() {
|
||||||
var utxos = Transaction.selectUnspent(testdata.dataUnspentSign.unspent,0.1);
|
var utxos =testdata.dataUnspentSign.unspent;
|
||||||
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
||||||
var tx = Transaction.create(utxos, outs, opts);
|
var tx = Transaction.create(utxos, outs, testdata.dataUnspentSign.keyStrings, opts);
|
||||||
tx.sign(testdata.dataUnspentSign.keyStrings).should.equal(true);
|
tx.isComplete().should.equal(true);
|
||||||
|
|
||||||
var utxos2 = Transaction.selectUnspent(testdata.dataUnspentSign.unspent,16, true);
|
var outs2 = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:16}];
|
||||||
var outs2 = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
var tx2 = Transaction.create(utxos, outs2, testdata.dataUnspentSign.keyStrings, opts);
|
||||||
var tx2 = Transaction.create(utxos2, outs2, opts);
|
tx2.isComplete().should.equal(true);
|
||||||
tx2.sign(testdata.dataUnspentSign.keyStrings).should.equal(true);
|
|
||||||
});
|
});
|
||||||
it('#sign should fail to sign a tx', function() {
|
|
||||||
var utxos = Transaction.selectUnspent(testdata.dataUnspentSign.unspent,0.1);
|
it('#sign should sign an incomplete tx ', function() {
|
||||||
|
var keys = ['cNpW8B7XPAzCdRR9RBWxZeveSNy3meXgHD8GuhcqUyDuy8ptCDzJ'];
|
||||||
|
var utxos =testdata.dataUnspentSign.unspent;
|
||||||
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
||||||
var tx = Transaction.create(utxos, outs, opts);
|
var tx = Transaction.create(utxos, outs, keys, opts);
|
||||||
tx.sign(['cNpW8B7XPAzCdRR9RBWxZeveSNy3meXgHD8GuhcqUyDuy8ptCDzJ']).should.equal(false);
|
tx.isComplete().should.equal(false);
|
||||||
});
|
});
|
||||||
it('#sign should sign a tx in multiple steps', function() {
|
it('#sign should sign a tx in multiple steps', function() {
|
||||||
var utxos = Transaction.selectUnspent(testdata.dataUnspentSign.unspent,13, true);
|
var utxos = Transaction.selectUnspent(testdata.dataUnspentSign.unspent,13, true);
|
||||||
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
var outs = [{address:'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE', amount:0.08}];
|
||||||
|
|
||||||
var tx = Transaction.create(utxos, outs, opts);
|
var tx = Transaction.prepare(utxos, outs, opts);
|
||||||
var k1 = testdata.dataUnspentSign.keyStrings.slice(0,1);
|
var k1 = testdata.dataUnspentSign.keyStrings.slice(0,1);
|
||||||
var k23 = testdata.dataUnspentSign.keyStrings.slice(1,3);
|
var k23 = testdata.dataUnspentSign.keyStrings.slice(1,3);
|
||||||
tx.sign(k1).should.equal(false);
|
tx.sign(utxos, k1).should.equal(false);
|
||||||
tx.sign(k23).should.equal(true);
|
tx.sign(utxos, k23).should.equal(true);
|
||||||
|
|
||||||
var tx2 = Transaction.create(utxos, outs, opts);
|
var tx2 = Transaction.prepare(utxos, outs, opts);
|
||||||
var k1 = testdata.dataUnspentSign.keyStrings.slice(0,1);
|
var k1 = testdata.dataUnspentSign.keyStrings.slice(0,1);
|
||||||
var k2 = testdata.dataUnspentSign.keyStrings.slice(1,2);
|
var k2 = testdata.dataUnspentSign.keyStrings.slice(1,2);
|
||||||
var k3 = testdata.dataUnspentSign.keyStrings.slice(2,3);
|
var k3 = testdata.dataUnspentSign.keyStrings.slice(2,3);
|
||||||
tx2.sign(k1).should.equal(false);
|
tx2.sign(utxos, k1).should.equal(false);
|
||||||
tx2.sign(k2).should.equal(false);
|
tx2.sign(utxos, k2).should.equal(false);
|
||||||
tx2.sign(k3).should.equal(true);
|
tx2.sign(utxos, k3).should.equal(true);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue