multisign test for signing twice with same sig

This commit is contained in:
Matias Alejo Garcia 2014-03-31 15:16:30 -03:00
parent 2af6ab7650
commit 8acf093339
3 changed files with 84 additions and 17 deletions

View File

@ -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();

View File

@ -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) {

View File

@ -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);
});
});