From 921bc2ff170a74bc3a273376be5ce6b43f0e2646 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Thu, 3 Apr 2014 22:06:57 -0300 Subject: [PATCH 1/3] add sorting of pubkeys for multisig addr generation --- Script.js | 23 ++++++++++++++++++++++- test/data/unspentSign.json | 2 +- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Script.js b/Script.js index d104d98..fc93dbc 100644 --- a/Script.js +++ b/Script.js @@ -420,7 +420,28 @@ Script.createPubKeyHashOut = function(pubKeyHash) { return script; }; -Script.createMultisig = function(n_required, keys) { +Script._sortKeys = function(keys) { + return keys.sort(function(buf1, buf2) { + var len = buf1.length > buf1.length ? buf1.length : buf2.length; + for (var i = 0; i <= len; i++) { + if (buf1[i] === undefined) + return -1; //shorter strings come first + if (buf2[i] === undefined) + return 1; + if (buf1[i] < buf2[i]) + return -1; + if (buf1[i] > buf2[i]) + return 1; + else + continue; + } + return 0; + }); +}; + +Script.createMultisig = function(n_required, inKeys, opts) { + opts = opts || {}; + var keys = opts.noSorting ? i || inKeys : this._sortKeys(inKeys); var script = new Script(); script.writeN(n_required); keys.forEach(function(key) { diff --git a/test/data/unspentSign.json b/test/data/unspentSign.json index 19f9aac..e877c6c 100644 --- a/test/data/unspentSign.json +++ b/test/data/unspentSign.json @@ -68,7 +68,7 @@ ], "unspentP2sh": [ { - "address": "2Mwswt6Eih28xH8611fexpqKqJCLJMomveK", + "address": "2NDJbzwzsmRgD2o5HHXPhuq5g6tkKTjYkd6", "scriptPubKey": "a91432d272ce8a9b482b363408a0b1dd28123d59c63387", "txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1", "vout": 1, From 8ff1464b2c8d59b3fcde6fab8da973b2d48b107c Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Fri, 4 Apr 2014 09:44:16 -0300 Subject: [PATCH 2/3] add test imported from treasure --- test/test.Script.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/test/test.Script.js b/test/test.Script.js index 205192f..ee76eae 100644 --- a/test/test.Script.js +++ b/test/test.Script.js @@ -107,4 +107,27 @@ describe('Script', function() { }); }); + // Original test from https://github.com/ryanxcharles/treasure + var testPubKeysHex = [ + '02c525d65d18be8fb36ab50a21bee02ac9fdc2c176fa18791ac664ea4b95572ae0', + '02b937d54b550a3afdc2819772822d25869495f9e588b56a0205617d80514f0758', + '0266dd7664e65958f3cc67bf92ad6243bc495df5ab56691719263977104b635bea', + '02ee91377073b04d1d9d19597b81a7be3db6554bd7d16151cb5599a6107a589e70', + '02c8f63ad4822ef360b5c300f08488fa0fa24af2b2bebb6d6b602ca938ee5af793' + ]; + + describe('#_sortKeys', function() { + it('should get the pubkeys in properly sorted order', function() { + var pubs = testPubKeysHex.map( function(hex) { + return new Buffer(hex,'hex'); + }); + var sorted = Script._sortKeys(pubs); + sorted[0].toString('hex').should.equal(testPubKeysHex[2]); + sorted[1].toString('hex').should.equal(testPubKeysHex[1]); + sorted[2].toString('hex').should.equal(testPubKeysHex[0]); + sorted[3].toString('hex').should.equal(testPubKeysHex[4]); + sorted[4].toString('hex').should.equal(testPubKeysHex[3]); + }); + }); + }); From 56bed9b3f2e18a64e0276e137163f8445fe7190b Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Fri, 4 Apr 2014 10:37:32 -0300 Subject: [PATCH 3/3] fix noSorting, add testcase against bitcoind output --- Script.js | 2 +- test/test.Script.js | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Script.js b/Script.js index fc93dbc..52e1e84 100644 --- a/Script.js +++ b/Script.js @@ -441,7 +441,7 @@ Script._sortKeys = function(keys) { Script.createMultisig = function(n_required, inKeys, opts) { opts = opts || {}; - var keys = opts.noSorting ? i || inKeys : this._sortKeys(inKeys); + var keys = opts.noSorting ? inKeys : this._sortKeys(inKeys); var script = new Script(); script.writeN(n_required); keys.forEach(function(key) { diff --git a/test/test.Script.js b/test/test.Script.js index ee76eae..abf2c0d 100644 --- a/test/test.Script.js +++ b/test/test.Script.js @@ -130,4 +130,24 @@ describe('Script', function() { }); }); + describe('#createMultisig', function() { + it('should create ', function() { + var pubs = testPubKeysHex.map( function(hex) { + return new Buffer(hex,'hex'); + }); + var s1 = Script.createMultisig(3,pubs, {noSorting: true}); + + // test case generated with: bitcoind createmultisig 3 '["02c525d65d18be8fb36ab50a21bee02ac9fdc2c176fa18791ac664ea4b95572ae0", "02b937d54b550a3afdc2819772822d25869495f9e588b56a0205617d80514f0758", "0266dd7664e65958f3cc67bf92ad6243bc495df5ab56691719263977104b635bea","02ee91377073b04d1d9d19597b81a7be3db6554bd7d16151cb5599a6107a589e70", "02c8f63ad4822ef360b5c300f08488fa0fa24af2b2bebb6d6b602ca938ee5af793"]' + + s1.getBuffer().toString('hex').should.equal('532102c525d65d18be8fb36ab50a21bee02ac9fdc2c176fa18791ac664ea4b95572ae02102b937d54b550a3afdc2819772822d25869495f9e588b56a0205617d80514f0758210266dd7664e65958f3cc67bf92ad6243bc495df5ab56691719263977104b635bea2102ee91377073b04d1d9d19597b81a7be3db6554bd7d16151cb5599a6107a589e702102c8f63ad4822ef360b5c300f08488fa0fa24af2b2bebb6d6b602ca938ee5af79355ae'); + var s2 = Script.createMultisig(3,pubs); + + // test case generated with: bitcoind createmultisig 3 '["0266dd7664e65958f3cc67bf92ad6243bc495df5ab56691719263977104b635bea", "02b937d54b550a3afdc2819772822d25869495f9e588b56a0205617d80514f0758", "02c525d65d18be8fb36ab50a21bee02ac9fdc2c176fa18791ac664ea4b95572ae0", "02c8f63ad4822ef360b5c300f08488fa0fa24af2b2bebb6d6b602ca938ee5af793", "02ee91377073b04d1d9d19597b81a7be3db6554bd7d16151cb5599a6107a589e70"]' + s2.getBuffer().toString('hex').should.equal('53210266dd7664e65958f3cc67bf92ad6243bc495df5ab56691719263977104b635bea2102b937d54b550a3afdc2819772822d25869495f9e588b56a0205617d80514f07582102c525d65d18be8fb36ab50a21bee02ac9fdc2c176fa18791ac664ea4b95572ae02102c8f63ad4822ef360b5c300f08488fa0fa24af2b2bebb6d6b602ca938ee5af7932102ee91377073b04d1d9d19597b81a7be3db6554bd7d16151cb5599a6107a589e7055ae'); + + }); + }); + + + });