|
@ -2,10 +2,13 @@ |
|
|
|
|
|
|
|
|
var _ = require('lodash'); |
|
|
var _ = require('lodash'); |
|
|
var $ = require('./util/preconditions'); |
|
|
var $ = require('./util/preconditions'); |
|
|
|
|
|
var errors = require('./errors'); |
|
|
var Base58Check = require('./encoding/base58check'); |
|
|
var Base58Check = require('./encoding/base58check'); |
|
|
var Networks = require('./networks'); |
|
|
var Networks = require('./networks'); |
|
|
var Hash = require('./crypto/hash'); |
|
|
var Hash = require('./crypto/hash'); |
|
|
var JSUtil = require('./util/js'); |
|
|
var JSUtil = require('./util/js'); |
|
|
|
|
|
var Script = require('./script'); |
|
|
|
|
|
var PublicKey = require('./publickey'); |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Instantiate an address from an address String or Buffer, a public key or script hash Buffer, |
|
|
* Instantiate an address from an address String or Buffer, a public key or script hash Buffer, |
|
@ -91,8 +94,6 @@ function Address(data, network, type) { |
|
|
* @returns {Object} An "info" object with "type", "network", and "hashBuffer" |
|
|
* @returns {Object} An "info" object with "type", "network", and "hashBuffer" |
|
|
*/ |
|
|
*/ |
|
|
Address.prototype._classifyArguments = function(data, network, type) { |
|
|
Address.prototype._classifyArguments = function(data, network, type) { |
|
|
var PublicKey = require('./publickey'); |
|
|
|
|
|
var Script = require('./script'); |
|
|
|
|
|
/* jshint maxcomplexity: 10 */ |
|
|
/* jshint maxcomplexity: 10 */ |
|
|
// transform and validate input data
|
|
|
// transform and validate input data
|
|
|
if ((data instanceof Buffer || data instanceof Uint8Array) && data.length === 20) { |
|
|
if ((data instanceof Buffer || data instanceof Uint8Array) && data.length === 20) { |
|
@ -122,7 +123,7 @@ Address.PayToScriptHash = 'scripthash'; |
|
|
* @returns {Object} An object with keys: hashBuffer |
|
|
* @returns {Object} An object with keys: hashBuffer |
|
|
* @private |
|
|
* @private |
|
|
*/ |
|
|
*/ |
|
|
Address._transformHash = function(hash){ |
|
|
Address._transformHash = function(hash) { |
|
|
var info = {}; |
|
|
var info = {}; |
|
|
if (!(hash instanceof Buffer) && !(hash instanceof Uint8Array)) { |
|
|
if (!(hash instanceof Buffer) && !(hash instanceof Uint8Array)) { |
|
|
throw new TypeError('Address supplied is not a buffer.'); |
|
|
throw new TypeError('Address supplied is not a buffer.'); |
|
@ -159,7 +160,7 @@ Address._transformObject = function(data) { |
|
|
* @returns {Object} An object with keys: network and type |
|
|
* @returns {Object} An object with keys: network and type |
|
|
* @private |
|
|
* @private |
|
|
*/ |
|
|
*/ |
|
|
Address._classifyFromVersion = function(buffer){ |
|
|
Address._classifyFromVersion = function(buffer) { |
|
|
var version = {}; |
|
|
var version = {}; |
|
|
version.network = Networks.get(buffer[0]); |
|
|
version.network = Networks.get(buffer[0]); |
|
|
switch (buffer[0]) { // the version byte
|
|
|
switch (buffer[0]) { // the version byte
|
|
@ -191,7 +192,7 @@ Address._classifyFromVersion = function(buffer){ |
|
|
* @returns {Object} An object with keys: hashBuffer, network and type |
|
|
* @returns {Object} An object with keys: hashBuffer, network and type |
|
|
* @private |
|
|
* @private |
|
|
*/ |
|
|
*/ |
|
|
Address._transformBuffer = function(buffer, network, type){ |
|
|
Address._transformBuffer = function(buffer, network, type) { |
|
|
/* jshint maxcomplexity: 9 */ |
|
|
/* jshint maxcomplexity: 9 */ |
|
|
var info = {}; |
|
|
var info = {}; |
|
|
if (!(buffer instanceof Buffer) && !(buffer instanceof Uint8Array)) { |
|
|
if (!(buffer instanceof Buffer) && !(buffer instanceof Uint8Array)) { |
|
@ -208,7 +209,7 @@ Address._transformBuffer = function(buffer, network, type){ |
|
|
throw new TypeError('Address has mismatched network type.'); |
|
|
throw new TypeError('Address has mismatched network type.'); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (!bufferVersion.type || ( type && type !== bufferVersion.type )) { |
|
|
if (!bufferVersion.type || (type && type !== bufferVersion.type)) { |
|
|
throw new TypeError('Address has mismatched type.'); |
|
|
throw new TypeError('Address has mismatched type.'); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -225,8 +226,7 @@ Address._transformBuffer = function(buffer, network, type){ |
|
|
* @returns {Object} An object with keys: hashBuffer, type |
|
|
* @returns {Object} An object with keys: hashBuffer, type |
|
|
* @private |
|
|
* @private |
|
|
*/ |
|
|
*/ |
|
|
Address._transformPublicKey = function(pubkey){ |
|
|
Address._transformPublicKey = function(pubkey) { |
|
|
var PublicKey = require('./publickey'); |
|
|
|
|
|
var info = {}; |
|
|
var info = {}; |
|
|
if (!(pubkey instanceof PublicKey)) { |
|
|
if (!(pubkey instanceof PublicKey)) { |
|
|
throw new TypeError('Address must be an instance of PublicKey.'); |
|
|
throw new TypeError('Address must be an instance of PublicKey.'); |
|
@ -243,11 +243,10 @@ Address._transformPublicKey = function(pubkey){ |
|
|
* @returns {Object} An object with keys: hashBuffer, type |
|
|
* @returns {Object} An object with keys: hashBuffer, type |
|
|
* @private |
|
|
* @private |
|
|
*/ |
|
|
*/ |
|
|
Address._transformScript = function(script, network){ |
|
|
Address._transformScript = function(script, network) { |
|
|
var Script = require('./script'); |
|
|
|
|
|
var info = {}; |
|
|
var info = {}; |
|
|
if (!(script instanceof Script)) { |
|
|
if (!(script instanceof Script)) { |
|
|
throw new TypeError('Address must be an instance of Script.'); |
|
|
throw new TypeError('script must be an instance of Script.'); |
|
|
} |
|
|
} |
|
|
if (script.isScriptHashOut()) { |
|
|
if (script.isScriptHashOut()) { |
|
|
info.hashBuffer = script.getData(); |
|
|
info.hashBuffer = script.getData(); |
|
@ -255,9 +254,16 @@ Address._transformScript = function(script, network){ |
|
|
} else if (script.isPublicKeyHashOut()) { |
|
|
} else if (script.isPublicKeyHashOut()) { |
|
|
info.hashBuffer = script.getData(); |
|
|
info.hashBuffer = script.getData(); |
|
|
info.type = Address.PayToPublicKeyHash; |
|
|
info.type = Address.PayToPublicKeyHash; |
|
|
} else { |
|
|
} else if (script.isScriptHashIn()) { |
|
|
info.hashBuffer = Hash.sha256ripemd160(script.toBuffer()); |
|
|
// hash the redeemscript found at the end of the scriptSig
|
|
|
|
|
|
info.hashBuffer = Hash.sha256ripemd160(script.chunks[script.chunks.length - 1].buf); |
|
|
info.type = Address.PayToScriptHash; |
|
|
info.type = Address.PayToScriptHash; |
|
|
|
|
|
} else if (script.isPublicKeyHashIn()) { |
|
|
|
|
|
// hash the publickey found in the scriptSig
|
|
|
|
|
|
info.hashBuffer = Hash.sha256ripemd160(script.chunks[1].buf); |
|
|
|
|
|
info.type = Address.PayToPublicKeyHash; |
|
|
|
|
|
} else { |
|
|
|
|
|
throw new errors.Script.CantDeriveAddress(script); |
|
|
} |
|
|
} |
|
|
info.network = Networks.get(network) || Networks.defaultNetwork; |
|
|
info.network = Networks.get(network) || Networks.defaultNetwork; |
|
|
return info; |
|
|
return info; |
|
@ -276,9 +282,8 @@ Address._transformScript = function(script, network){ |
|
|
* @return {Address} |
|
|
* @return {Address} |
|
|
*/ |
|
|
*/ |
|
|
Address.createMultisig = function(publicKeys, threshold, network) { |
|
|
Address.createMultisig = function(publicKeys, threshold, network) { |
|
|
var Script = require('./script'); |
|
|
network = network || publicKeys[0].network || Networks.defaultNetwork; |
|
|
network = network || publicKeys[0].network; |
|
|
return Address.payingTo(Script.buildMultisigOut(publicKeys, threshold), network); |
|
|
return new Address(Script.buildMultisigOut(publicKeys, threshold), network || Networks.defaultNetwork); |
|
|
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
@ -290,8 +295,8 @@ Address.createMultisig = function(publicKeys, threshold, network) { |
|
|
* @returns {Object} An object with keys: hashBuffer, network and type |
|
|
* @returns {Object} An object with keys: hashBuffer, network and type |
|
|
* @private |
|
|
* @private |
|
|
*/ |
|
|
*/ |
|
|
Address._transformString = function(data, network, type){ |
|
|
Address._transformString = function(data, network, type) { |
|
|
if( typeof(data) !== 'string' ) { |
|
|
if (typeof(data) !== 'string') { |
|
|
throw new TypeError('Address supplied is not a string.'); |
|
|
throw new TypeError('Address supplied is not a string.'); |
|
|
} |
|
|
} |
|
|
var addressBuffer = Base58Check.decode(data); |
|
|
var addressBuffer = Base58Check.decode(data); |
|
@ -306,7 +311,7 @@ Address._transformString = function(data, network, type){ |
|
|
* @param {String|Network} network - either a Network instance, 'livenet', or 'testnet' |
|
|
* @param {String|Network} network - either a Network instance, 'livenet', or 'testnet' |
|
|
* @returns {Address} A new valid and frozen instance of an Address |
|
|
* @returns {Address} A new valid and frozen instance of an Address |
|
|
*/ |
|
|
*/ |
|
|
Address.fromPublicKey = function(data, network){ |
|
|
Address.fromPublicKey = function(data, network) { |
|
|
var info = Address._transformPublicKey(data); |
|
|
var info = Address._transformPublicKey(data); |
|
|
network = network || Networks.defaultNetwork; |
|
|
network = network || Networks.defaultNetwork; |
|
|
return new Address(info.hashBuffer, network, info.type); |
|
|
return new Address(info.hashBuffer, network, info.type); |
|
@ -332,12 +337,35 @@ Address.fromPublicKeyHash = function(hash, network) { |
|
|
* @returns {Address} A new valid and frozen instance of an Address |
|
|
* @returns {Address} A new valid and frozen instance of an Address |
|
|
*/ |
|
|
*/ |
|
|
Address.fromScriptHash = function(hash, network) { |
|
|
Address.fromScriptHash = function(hash, network) { |
|
|
|
|
|
$.checkArgument(hash, 'hash parameter is required'); |
|
|
var info = Address._transformHash(hash); |
|
|
var info = Address._transformHash(hash); |
|
|
return new Address(info.hashBuffer, network, Address.PayToScriptHash); |
|
|
return new Address(info.hashBuffer, network, Address.PayToScriptHash); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Instantiate an address from a Script |
|
|
* Builds a p2sh address paying to script. This will hash the script and |
|
|
|
|
|
* use that to create the address. |
|
|
|
|
|
* If you want to extract an address associated with a script instead, |
|
|
|
|
|
* see {{Address#fromScript}} |
|
|
|
|
|
* |
|
|
|
|
|
* @param {Script} script - An instance of Script |
|
|
|
|
|
* @param {String|Network} network - either a Network instance, 'livenet', or 'testnet' |
|
|
|
|
|
* @returns {Address} A new valid and frozen instance of an Address |
|
|
|
|
|
*/ |
|
|
|
|
|
Address.payingTo = function(script, network) { |
|
|
|
|
|
$.checkArgument(script, 'script is required'); |
|
|
|
|
|
$.checkArgument(script instanceof Script, 'script must be instance of Script'); |
|
|
|
|
|
|
|
|
|
|
|
return Address.fromScriptHash(Hash.sha256ripemd160(script.toBuffer()), network); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Extract address from a Script. The script must be of one |
|
|
|
|
|
* of the following types: p2pkh input, p2pkh output, p2sh input |
|
|
|
|
|
* or p2sh output. |
|
|
|
|
|
* This will analyze the script and extract address information from it. |
|
|
|
|
|
* If you want to transform any script to a p2sh Address paying |
|
|
|
|
|
* to that script's hash instead, use {{Address#payingTo}} |
|
|
* |
|
|
* |
|
|
* @param {Script} script - An instance of Script |
|
|
* @param {Script} script - An instance of Script |
|
|
* @param {String|Network} network - either a Network instance, 'livenet', or 'testnet' |
|
|
* @param {String|Network} network - either a Network instance, 'livenet', or 'testnet' |
|
@ -494,7 +522,7 @@ Address.prototype.toString = function() { |
|
|
* @returns {string} Bitcoin address |
|
|
* @returns {string} Bitcoin address |
|
|
*/ |
|
|
*/ |
|
|
Address.prototype.inspect = function() { |
|
|
Address.prototype.inspect = function() { |
|
|
return '<Address: ' + this.toString() + ', type: '+this.type+', network: '+this.network+'>'; |
|
|
return '<Address: ' + this.toString() + ', type: ' + this.type + ', network: ' + this.network + '>'; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
module.exports = Address; |
|
|
module.exports = Address; |
|
|