Add capability to instantiate an Address from public keys and a threshold
This commit is contained in:
parent
2d78d9697b
commit
5f5cf15241
|
@ -1,5 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('lodash');
|
||||||
var $ = require('./util/preconditions');
|
var $ = require('./util/preconditions');
|
||||||
var base58check = require('./encoding/base58check');
|
var base58check = require('./encoding/base58check');
|
||||||
var Networks = require('./networks');
|
var Networks = require('./networks');
|
||||||
|
@ -42,6 +43,10 @@ function Address(data, network, type) {
|
||||||
return new Address(data, network, type);
|
return new Address(data, network, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_.isArray(data) && _.isNumber(network)) {
|
||||||
|
return Address.createMultisig(data, network, type);
|
||||||
|
}
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
throw new TypeError('First argument is required, please include address data.');
|
throw new TypeError('First argument is required, please include address data.');
|
||||||
}
|
}
|
||||||
|
@ -225,6 +230,19 @@ Address._transformScript = function(script, network){
|
||||||
return info;
|
return info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a P2SH address from a set of public keys and a threshold.
|
||||||
|
*
|
||||||
|
* @param {Array} publicKeys
|
||||||
|
* @param {number} threshold
|
||||||
|
* @param {Network} network
|
||||||
|
* @return {Address}
|
||||||
|
*/
|
||||||
|
Address.createMultisig = function(publicKeys, threshold, network) {
|
||||||
|
var Script = require('./script');
|
||||||
|
return new Address(Script.buildMultisigOut(publicKeys, threshold), network || Networks.defaultNetwork);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal function to transform a bitcoin address string
|
* Internal function to transform a bitcoin address string
|
||||||
*
|
*
|
||||||
|
|
|
@ -516,32 +516,30 @@ Script.prototype.removeCodeseparators = function() {
|
||||||
/**
|
/**
|
||||||
* @returns a new Multisig output script for given public keys,
|
* @returns a new Multisig output script for given public keys,
|
||||||
* requiring m of those public keys to spend
|
* requiring m of those public keys to spend
|
||||||
* @param {PublicKey[]} pubkeys - list of all public keys controlling the output
|
* @param {PublicKey[]} publicKeys - list of all public keys controlling the output
|
||||||
* @param {number} m - amount of required signatures to spend the output
|
* @param {number} threshold - amount of required signatures to spend the output
|
||||||
* @param {Object} [opts] - Several options:
|
* @param {Object} [opts] - Several options:
|
||||||
* - noSorting: defaults to false, if true, don't sort the given
|
* - noSorting: defaults to false, if true, don't sort the given
|
||||||
* public keys before creating the script
|
* public keys before creating the script
|
||||||
*/
|
*/
|
||||||
Script.buildMultisigOut = function(pubkeys, m, opts) {
|
Script.buildMultisigOut = function(publicKeys, threshold, opts) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
var s = new Script();
|
var script = new Script();
|
||||||
s.add(Opcode.smallInt(m));
|
script.add(Opcode.smallInt(threshold));
|
||||||
pubkeys = _.map(pubkeys, function(pubkey) {
|
publicKeys = _.map(publicKeys, PublicKey);
|
||||||
return PublicKey(pubkey);
|
var sorted = publicKeys;
|
||||||
});
|
|
||||||
var sorted = pubkeys;
|
|
||||||
if (!opts.noSorting) {
|
if (!opts.noSorting) {
|
||||||
sorted = _.sortBy(pubkeys, function(pubkey) {
|
sorted = _.sortBy(publicKeys, function(publicKey) {
|
||||||
return pubkey.toString('hex');
|
return publicKey.toString('hex');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (var i = 0; i < sorted.length; i++) {
|
for (var i = 0; i < sorted.length; i++) {
|
||||||
var pubkey = sorted[i];
|
var publicKey = sorted[i];
|
||||||
s.add(pubkey.toBuffer());
|
script.add(publicKey.toBuffer());
|
||||||
}
|
}
|
||||||
s.add(Opcode.smallInt(pubkeys.length));
|
script.add(Opcode.smallInt(publicKeys.length));
|
||||||
s.add(Opcode.OP_CHECKMULTISIG);
|
script.add(Opcode.OP_CHECKMULTISIG);
|
||||||
return s;
|
return script;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -448,4 +448,28 @@ describe('Address', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('creating a P2SH address from public keys', function() {
|
||||||
|
|
||||||
|
var public1 = '02da5798ed0c055e31339eb9b5cef0d3c0ccdec84a62e2e255eb5c006d4f3e7f5b';
|
||||||
|
var public2 = '0272073bf0287c4469a2a011567361d42529cd1a72ab0d86aa104ecc89342ffeb0';
|
||||||
|
var public3 = '02738a516a78355db138e8119e58934864ce222c553a5407cf92b9c1527e03c1a2';
|
||||||
|
var publics = [public1, public2, public3];
|
||||||
|
|
||||||
|
it('can create an address from a set of public keys', function() {
|
||||||
|
var address = new Address(publics, 2);
|
||||||
|
address.toString().should.equal('3FtqPRirhPvrf7mVUSkygyZ5UuoAYrTW3y');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works on testnet also', function() {
|
||||||
|
var address = new Address(publics, 2, Networks.testnet);
|
||||||
|
address.toString().should.equal('2N7T3TAetJrSCruQ39aNrJvYLhG1LJosujf');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can also be created by Address.createMultisig', function() {
|
||||||
|
var address = Address.createMultisig(publics, 2);
|
||||||
|
var address2 = Address.createMultisig(publics, 2);
|
||||||
|
address.toString().should.equal(address2.toString());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue