Merge pull request #1296 from braydonf/script-optimizations
Optimizations for `script.toAddress()`
This commit is contained in:
commit
1a809cbeec
@ -24,6 +24,12 @@ async.series([
|
|||||||
scripts.push(input.script);
|
scripts.push(input.script);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (var k = 0; k < tx.outputs.length; k++) {
|
||||||
|
var output = tx.outputs[k];
|
||||||
|
if (output.script) {
|
||||||
|
scripts.push(output.script);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPublicKeyHashIn() {
|
function isPublicKeyHashIn() {
|
||||||
|
|||||||
@ -7,7 +7,6 @@ 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');
|
var PublicKey = require('./publickey');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -505,3 +504,5 @@ Address.prototype.inspect = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.exports = Address;
|
module.exports = Address;
|
||||||
|
|
||||||
|
var Script = require('./script');
|
||||||
|
|||||||
@ -29,10 +29,19 @@ Hash.sha256sha256 = function(buf) {
|
|||||||
|
|
||||||
Hash.ripemd160 = function(buf) {
|
Hash.ripemd160 = function(buf) {
|
||||||
$.checkArgument(BufferUtil.isBuffer(buf));
|
$.checkArgument(BufferUtil.isBuffer(buf));
|
||||||
var hash = (new hashjs.ripemd160()).update(buf).digest();
|
return crypto.createHash('ripemd160').update(buf).digest();
|
||||||
return new Buffer(hash);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Node.js crypto ripemd160 hashes are not supported in a browser
|
||||||
|
// We'll replace with a (slower) version that does.
|
||||||
|
if (global.window) {
|
||||||
|
Hash.ripemd160 = function(buf) {
|
||||||
|
$.checkArgument(BufferUtil.isBuffer(buf));
|
||||||
|
var hash = (new hashjs.ripemd160()).update(buf).digest();
|
||||||
|
return new Buffer(hash);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Hash.sha256ripemd160 = function(buf) {
|
Hash.sha256ripemd160 = function(buf) {
|
||||||
$.checkArgument(BufferUtil.isBuffer(buf));
|
$.checkArgument(BufferUtil.isBuffer(buf));
|
||||||
return Hash.ripemd160(Hash.sha256(buf));
|
return Hash.ripemd160(Hash.sha256(buf));
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
var Address = require('../address');
|
||||||
var BufferReader = require('../encoding/bufferreader');
|
var BufferReader = require('../encoding/bufferreader');
|
||||||
var BufferWriter = require('../encoding/bufferwriter');
|
var BufferWriter = require('../encoding/bufferwriter');
|
||||||
var Hash = require('../crypto/hash');
|
var Hash = require('../crypto/hash');
|
||||||
@ -8,7 +8,6 @@ var Opcode = require('../opcode');
|
|||||||
var PublicKey = require('../publickey');
|
var PublicKey = require('../publickey');
|
||||||
var Signature = require('../crypto/signature');
|
var Signature = require('../crypto/signature');
|
||||||
var Networks = require('../networks');
|
var Networks = require('../networks');
|
||||||
|
|
||||||
var $ = require('../util/preconditions');
|
var $ = require('../util/preconditions');
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
var errors = require('../errors');
|
var errors = require('../errors');
|
||||||
@ -29,8 +28,6 @@ var Script = function Script(from) {
|
|||||||
if (!(this instanceof Script)) {
|
if (!(this instanceof Script)) {
|
||||||
return new Script(from);
|
return new Script(from);
|
||||||
}
|
}
|
||||||
var Address = require('../address');
|
|
||||||
|
|
||||||
this.chunks = [];
|
this.chunks = [];
|
||||||
|
|
||||||
if (BufferUtil.isBuffer(from)) {
|
if (BufferUtil.isBuffer(from)) {
|
||||||
@ -639,7 +636,6 @@ Script.buildP2SHMultisigIn = function(pubkeys, threshold, signatures, opts) {
|
|||||||
* @param {(Address|PublicKey)} to - destination address or public key
|
* @param {(Address|PublicKey)} to - destination address or public key
|
||||||
*/
|
*/
|
||||||
Script.buildPublicKeyHashOut = function(to) {
|
Script.buildPublicKeyHashOut = function(to) {
|
||||||
var Address = require('../address');
|
|
||||||
$.checkArgument(!_.isUndefined(to));
|
$.checkArgument(!_.isUndefined(to));
|
||||||
$.checkArgument(to instanceof PublicKey || to instanceof Address || _.isString(to));
|
$.checkArgument(to instanceof PublicKey || to instanceof Address || _.isString(to));
|
||||||
if (to instanceof PublicKey) {
|
if (to instanceof PublicKey) {
|
||||||
@ -692,7 +688,6 @@ Script.buildDataOut = function(data) {
|
|||||||
* @returns {Script} new pay to script hash script for given script
|
* @returns {Script} new pay to script hash script for given script
|
||||||
*/
|
*/
|
||||||
Script.buildScriptHashOut = function(script) {
|
Script.buildScriptHashOut = function(script) {
|
||||||
var Address = require('../address');
|
|
||||||
$.checkArgument(script instanceof Script ||
|
$.checkArgument(script instanceof Script ||
|
||||||
(script instanceof Address && script.isPayToScriptHash()));
|
(script instanceof Address && script.isPayToScriptHash()));
|
||||||
var s = new Script();
|
var s = new Script();
|
||||||
@ -745,7 +740,6 @@ Script.prototype.toScriptHashOut = function() {
|
|||||||
* @return {Script} an output script built from the address
|
* @return {Script} an output script built from the address
|
||||||
*/
|
*/
|
||||||
Script.fromAddress = function(address) {
|
Script.fromAddress = function(address) {
|
||||||
var Address = require('../address');
|
|
||||||
address = Address(address);
|
address = Address(address);
|
||||||
if (address.isPayToScriptHash()) {
|
if (address.isPayToScriptHash()) {
|
||||||
return Script.buildScriptHashOut(address);
|
return Script.buildScriptHashOut(address);
|
||||||
@ -756,12 +750,29 @@ Script.fromAddress = function(address) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Network=} network
|
* Will return the associated address information object
|
||||||
* @return {Address|boolean} the associated address information object
|
* @return {Address|boolean}
|
||||||
* for this script if any, or false
|
|
||||||
*/
|
*/
|
||||||
Script.prototype.getAddressInfo = function() {
|
Script.prototype.getAddressInfo = function(opts) {
|
||||||
var Address = require('../address');
|
if (this._isInput) {
|
||||||
|
return this._getInputAddressInfo();
|
||||||
|
} else if (this._isOutput) {
|
||||||
|
return this._getOutputAddressInfo();
|
||||||
|
} else {
|
||||||
|
var info = this._getOutputAddressInfo();
|
||||||
|
if (!info) {
|
||||||
|
return this._getInputAddressInfo();
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will return the associated output scriptPubKey address information object
|
||||||
|
* @return {Address|boolean}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Script.prototype._getOutputAddressInfo = function() {
|
||||||
var info = {};
|
var info = {};
|
||||||
if (this.isScriptHashOut()) {
|
if (this.isScriptHashOut()) {
|
||||||
info.hashBuffer = this.getData();
|
info.hashBuffer = this.getData();
|
||||||
@ -769,7 +780,20 @@ Script.prototype.getAddressInfo = function() {
|
|||||||
} else if (this.isPublicKeyHashOut()) {
|
} else if (this.isPublicKeyHashOut()) {
|
||||||
info.hashBuffer = this.getData();
|
info.hashBuffer = this.getData();
|
||||||
info.type = Address.PayToPublicKeyHash;
|
info.type = Address.PayToPublicKeyHash;
|
||||||
} else if (this.isPublicKeyHashIn()) {
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will return the associated input scriptSig address information object
|
||||||
|
* @return {Address|boolean}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Script.prototype._getInputAddressInfo = function() {
|
||||||
|
var info = {};
|
||||||
|
if (this.isPublicKeyHashIn()) {
|
||||||
// hash the publickey found in the scriptSig
|
// hash the publickey found in the scriptSig
|
||||||
info.hashBuffer = Hash.sha256ripemd160(this.chunks[1].buf);
|
info.hashBuffer = Hash.sha256ripemd160(this.chunks[1].buf);
|
||||||
info.type = Address.PayToPublicKeyHash;
|
info.type = Address.PayToPublicKeyHash;
|
||||||
@ -782,18 +806,17 @@ Script.prototype.getAddressInfo = function() {
|
|||||||
}
|
}
|
||||||
return info;
|
return info;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Network=} network
|
* @param {Network=} network
|
||||||
* @return {Address|boolean} the associated address for this script if possible, or false
|
* @return {Address|boolean} the associated address for this script if possible, or false
|
||||||
*/
|
*/
|
||||||
Script.prototype.toAddress = function(network) {
|
Script.prototype.toAddress = function(network) {
|
||||||
var Address = require('../address');
|
|
||||||
network = Networks.get(network) || this._network || Networks.defaultNetwork;
|
|
||||||
var info = this.getAddressInfo();
|
var info = this.getAddressInfo();
|
||||||
if (!info) {
|
if (!info) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
info.network = Networks.get(network) || Networks.defaultNetwork;
|
info.network = Networks.get(network) || this._network || Networks.defaultNetwork;
|
||||||
return new Address(info);
|
return new Address(info);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -34,6 +34,7 @@ Object.defineProperty(Input.prototype, 'script', {
|
|||||||
}
|
}
|
||||||
if (!this._script) {
|
if (!this._script) {
|
||||||
this._script = new Script(this._scriptBuffer);
|
this._script = new Script(this._scriptBuffer);
|
||||||
|
this._script._isInput = true;
|
||||||
}
|
}
|
||||||
return this._script;
|
return this._script;
|
||||||
}
|
}
|
||||||
@ -116,6 +117,7 @@ Input.prototype.setScript = function(script) {
|
|||||||
this._script = null;
|
this._script = null;
|
||||||
if (script instanceof Script) {
|
if (script instanceof Script) {
|
||||||
this._script = script;
|
this._script = script;
|
||||||
|
this._script._isInput = true;
|
||||||
this._scriptBuffer = script.toBuffer();
|
this._scriptBuffer = script.toBuffer();
|
||||||
} else if (JSUtil.isHexa(script)) {
|
} else if (JSUtil.isHexa(script)) {
|
||||||
// hex string script
|
// hex string script
|
||||||
@ -123,6 +125,7 @@ Input.prototype.setScript = function(script) {
|
|||||||
} else if (_.isString(script)) {
|
} else if (_.isString(script)) {
|
||||||
// human readable string script
|
// human readable string script
|
||||||
this._script = new Script(script);
|
this._script = new Script(script);
|
||||||
|
this._script._isInput = true;
|
||||||
this._scriptBuffer = this._script.toBuffer();
|
this._scriptBuffer = this._script.toBuffer();
|
||||||
} else if (BufferUtil.isBuffer(script)) {
|
} else if (BufferUtil.isBuffer(script)) {
|
||||||
// buffer script
|
// buffer script
|
||||||
|
|||||||
@ -113,6 +113,7 @@ Output.prototype.setScriptFromBuffer = function(buffer) {
|
|||||||
this._scriptBuffer = buffer;
|
this._scriptBuffer = buffer;
|
||||||
try {
|
try {
|
||||||
this._script = Script.fromBuffer(this._scriptBuffer);
|
this._script = Script.fromBuffer(this._scriptBuffer);
|
||||||
|
this._script._isOutput = true;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
if (e instanceof errors.Script.InvalidBuffer) {
|
if (e instanceof errors.Script.InvalidBuffer) {
|
||||||
this._script = null;
|
this._script = null;
|
||||||
@ -126,9 +127,11 @@ Output.prototype.setScript = function(script) {
|
|||||||
if (script instanceof Script) {
|
if (script instanceof Script) {
|
||||||
this._scriptBuffer = script.toBuffer();
|
this._scriptBuffer = script.toBuffer();
|
||||||
this._script = script;
|
this._script = script;
|
||||||
|
this._script._isOutput = true;
|
||||||
} else if (_.isString(script)) {
|
} else if (_.isString(script)) {
|
||||||
this._script = Script.fromString(script);
|
this._script = Script.fromString(script);
|
||||||
this._scriptBuffer = this._script.toBuffer();
|
this._scriptBuffer = this._script.toBuffer();
|
||||||
|
this._script._isOutput = true;
|
||||||
} else if (bufferUtil.isBuffer(script)) {
|
} else if (bufferUtil.isBuffer(script)) {
|
||||||
this.setScriptFromBuffer(script);
|
this.setScriptFromBuffer(script);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -202,7 +202,9 @@ describe('Transaction', function() {
|
|||||||
transaction.outputs[1].satoshis.should.equal(40000);
|
transaction.outputs[1].satoshis.should.equal(40000);
|
||||||
transaction.outputs[1].script.toString()
|
transaction.outputs[1].script.toString()
|
||||||
.should.equal(Script.fromAddress(changeAddress).toString());
|
.should.equal(Script.fromAddress(changeAddress).toString());
|
||||||
transaction.getChangeOutput().script.should.deep.equal(Script.fromAddress(changeAddress));
|
var actual = transaction.getChangeOutput().script.toString();
|
||||||
|
var expected = Script.fromAddress(changeAddress).toString();
|
||||||
|
actual.should.equal(expected);
|
||||||
});
|
});
|
||||||
it('accepts a P2SH address for change', function() {
|
it('accepts a P2SH address for change', function() {
|
||||||
var transaction = new Transaction()
|
var transaction = new Transaction()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user