multisign test for signing twice with same sig
This commit is contained in:
parent
2af6ab7650
commit
8acf093339
|
@ -58,7 +58,7 @@
|
|||
*
|
||||
* @opts
|
||||
* {
|
||||
* remainderAddress: null,
|
||||
* remainderOut: null,
|
||||
* fee: 0.001,
|
||||
* lockTime: null,
|
||||
* spendUnconfirmed: false,
|
||||
|
@ -67,8 +67,12 @@
|
|||
* 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 are remainder coins, the
|
||||
* first IN address will be used to return the coins. (TODO: is this is reasonable?)
|
||||
* If no remainderOut is given, and there are remainder coins, the
|
||||
* first IN out will be used to return the coins. remainderOut has the form:
|
||||
* remainderOut = { address: 1xxxxx}
|
||||
* or
|
||||
* remainderOut = { pubkeys: ['hex1','hex2',...} for multisig
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -101,7 +105,7 @@ function TransactionBuilder(opts) {
|
|||
if (opts.fee || opts.feeSat) {
|
||||
this.givenFeeSat = opts.fee ? opts.fee * util.COIN : opts.feeSat;
|
||||
}
|
||||
this.remainderAddress = opts.remainderAddress;
|
||||
this.remainderOut = opts.remainderOut;
|
||||
this.signhash = opts.signhash || Transaction.SIGHASH_ALL;
|
||||
|
||||
this.tx = {};
|
||||
|
@ -134,6 +138,31 @@ TransactionBuilder._scriptForAddress = function(addressString) {
|
|||
return script;
|
||||
};
|
||||
|
||||
|
||||
TransactionBuilder._scriptForPubkeys = function(out) {
|
||||
|
||||
var l = out.pubkeys.length;
|
||||
var pubKeyBuf=[];
|
||||
|
||||
for (var i=0; i<l; i++) {
|
||||
pubKeyBuf.push(new Buffer(out.pubkeys[i],'hex'));
|
||||
}
|
||||
|
||||
return Script.createMultisig(out.nreq, pubKeyBuf);
|
||||
};
|
||||
|
||||
TransactionBuilder._scriptForOut = function(out) {
|
||||
var ret;
|
||||
if (out.address)
|
||||
ret = this._scriptForAddress(out.address)
|
||||
else if (out.pubkeys || out.nreq || out.nreq > 1)
|
||||
ret = this._scriptForPubkeys(out);
|
||||
else
|
||||
throw new Error('unknow out type');
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
TransactionBuilder.prototype.setUnspent = function(utxos) {
|
||||
this.utxos = utxos;
|
||||
return this;
|
||||
|
@ -279,9 +308,9 @@ TransactionBuilder.prototype._setRemainder = function(remainderIndex) {
|
|||
}
|
||||
|
||||
if (remainderSat.cmp(0) > 0) {
|
||||
var remainderAddress = this.remainderAddress || this.selectedUtxos[0].address;
|
||||
var remainderOut = this.remainderOut || this.selectedUtxos[0];
|
||||
var value = util.bigIntToValue(remainderSat);
|
||||
var script = TransactionBuilder._scriptForAddress(remainderAddress);
|
||||
var script = TransactionBuilder._scriptForOut(remainderOut);
|
||||
var txout = {
|
||||
v: value,
|
||||
s: script.getBuffer(),
|
||||
|
@ -327,7 +356,7 @@ TransactionBuilder.prototype.setOutputs = function(outs) {
|
|||
for (var i = 0; i < l; i++) {
|
||||
var amountSat = outs[i].amountSat || util.parseValue(outs[i].amount);
|
||||
var value = util.bigIntToValue(amountSat);
|
||||
var script = TransactionBuilder._scriptForAddress(outs[i].address);
|
||||
var script = TransactionBuilder._scriptForOut(outs[i]);
|
||||
var txout = {
|
||||
v: value,
|
||||
s: script.getBuffer(),
|
||||
|
@ -552,15 +581,20 @@ TransactionBuilder.prototype._signMultiSig = function(walletKeyMap, input, txSig
|
|||
};
|
||||
};
|
||||
|
||||
TransactionBuilder.prototype._signScriptHash = function(walletKeyMap, input, txSigHash) {
|
||||
if (!this.hashToScriptMap)
|
||||
throw new Error('hashToScriptMap not set');
|
||||
|
||||
|
||||
throw new Error('TX_SCRIPTHASH not supported yet');
|
||||
};
|
||||
|
||||
|
||||
var fnToSign = {};
|
||||
fnToSign[Script.TX_PUBKEYHASH] = TransactionBuilder.prototype._signPubKeyHash;
|
||||
fnToSign[Script.TX_PUBKEY] = TransactionBuilder.prototype._signPubKey;
|
||||
fnToSign[Script.TX_MULTISIG] = TransactionBuilder.prototype._signMultiSig;
|
||||
fnToSign[Script.TX_SCRIPTHASH] = TransactionBuilder.prototype._signScriptHash;
|
||||
//if (!this.hashToScriptMap) throw new Error('hashToScriptMap not set');
|
||||
|
||||
TransactionBuilder.prototype.sign = function(keys) {
|
||||
this._checkTx();
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
|
||||
|
||||
var run = function() {
|
||||
// Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
|
||||
// replace '../bitcore' with 'bitcore' if you use this code elsewhere.
|
||||
var bitcore = require('../bitcore');
|
||||
var networks = require('../networks');
|
||||
var WalletKey = bitcore.WalletKey;
|
||||
|
||||
var opts = {network: networks.livenet};
|
||||
var opts = {network: networks.testnet};
|
||||
|
||||
function print(wk) {
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ describe('TransactionBuilder', function() {
|
|||
|
||||
var getBuilder2 = function (fee) {
|
||||
var opts = {
|
||||
remainderAddress: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd',
|
||||
remainderOut: {address: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd'},
|
||||
spendUnconfirmed: true,
|
||||
};
|
||||
|
||||
|
@ -134,7 +134,7 @@ describe('TransactionBuilder', function() {
|
|||
var utxos = testdata.dataUnspent;
|
||||
|
||||
var opts = {
|
||||
remainderAddress: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd',
|
||||
remainderOut: {address: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd'},
|
||||
spendUnconfirmed: true,
|
||||
};
|
||||
var outs = [{
|
||||
|
@ -211,7 +211,7 @@ describe('TransactionBuilder', function() {
|
|||
var getBuilder3 = function (outs) {
|
||||
|
||||
var opts = {
|
||||
remainderAddress: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd',
|
||||
remainderOut: {address: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd'},
|
||||
spendUnconfirmed: true,
|
||||
};
|
||||
|
||||
|
@ -397,7 +397,7 @@ describe('TransactionBuilder', function() {
|
|||
|
||||
it('should sign a p2pubkey tx', function() {
|
||||
var opts = {
|
||||
remainderAddress: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd',
|
||||
remainderOut: {address: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd'},
|
||||
};
|
||||
var outs = outs || [{
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
|
@ -419,7 +419,7 @@ describe('TransactionBuilder', function() {
|
|||
|
||||
it('should sign a multisig tx', function() {
|
||||
var opts = {
|
||||
remainderAddress: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd',
|
||||
remainderOut: {address: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd'},
|
||||
};
|
||||
var outs = outs || [{
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
|
@ -440,7 +440,7 @@ describe('TransactionBuilder', function() {
|
|||
|
||||
it('should sign a multisig tx in steps (3-5)', function() {
|
||||
var opts = {
|
||||
remainderAddress: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd',
|
||||
remainderOut: {address: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd'},
|
||||
};
|
||||
var outs = outs || [{
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
|
@ -470,7 +470,7 @@ describe('TransactionBuilder', function() {
|
|||
|
||||
it('should count multisig signs (3-5)', function() {
|
||||
var opts = {
|
||||
remainderAddress: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd',
|
||||
remainderOut: {address: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd'},
|
||||
};
|
||||
var outs = outs || [{
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
|
@ -494,7 +494,40 @@ describe('TransactionBuilder', function() {
|
|||
b.sign(k3);
|
||||
b.isFullySigned().should.equal(true);
|
||||
b.countInputMultiSig(0).should.equal(3);
|
||||
});
|
||||
|
||||
|
||||
it('should avoid siging with the same key twice multisig signs (3-5)', function() {
|
||||
var opts = {
|
||||
remainderOut: {address: 'mwZabyZXg8JzUtFX1pkGygsMJjnuqiNhgd'},
|
||||
};
|
||||
var outs = outs || [{
|
||||
address: 'mrPnbY1yKDBsdgbHbS7kJ8GVm8F66hWHLE',
|
||||
amount: 0.08
|
||||
}];
|
||||
var b = new TransactionBuilder(opts)
|
||||
.setUnspent(testdata.dataUnspentSign.unspentMulti)
|
||||
.setOutputs(outs);
|
||||
|
||||
var k1 = testdata.dataUnspentSign.keyStringsMulti.slice(0,1);
|
||||
var k23 = testdata.dataUnspentSign.keyStringsMulti.slice(1,3);
|
||||
|
||||
b.countInputMultiSig(0).should.equal(0);
|
||||
b.sign(k1);
|
||||
b.isFullySigned().should.equal(false);
|
||||
b.countInputMultiSig(0).should.equal(1);
|
||||
b.sign(k1);
|
||||
b.isFullySigned().should.equal(false);
|
||||
b.countInputMultiSig(0).should.equal(1);
|
||||
b.sign(k1);
|
||||
b.isFullySigned().should.equal(false);
|
||||
b.countInputMultiSig(0).should.equal(1);
|
||||
|
||||
|
||||
|
||||
|
||||
b.sign(k23);
|
||||
b.isFullySigned().should.equal(true);
|
||||
b.countInputMultiSig(0).should.equal(3);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue