Add `PublicKeyHashInput` and `ScriptHashInput`.
Remove `_outpoints`, `_utxos` from Transaction, as that info can be efficiently retrieved from the inputs
This commit is contained in:
parent
264a239e5a
commit
af43228daf
|
@ -27,7 +27,10 @@ module.exports = [{
|
|||
message: format('Invalid network: must be "livenet" or "testnet", got {0}')
|
||||
}, {
|
||||
name: 'InvalidArgument',
|
||||
message: format('Invalid Argument {0}, {1}'),
|
||||
message: format('Invalid Argument {0}, {1}')
|
||||
}, {
|
||||
name: 'AbstractMethodInvoked',
|
||||
message: format('Abstract Method Invokation: {0}')
|
||||
}, {
|
||||
name: 'InvalidArgumentType',
|
||||
message: format('Invalid Argument for {2}, expected {1} but got ') + '+ typeof arguments[0]',
|
||||
|
|
|
@ -2,4 +2,7 @@
|
|||
|
||||
var Input = require('./input');
|
||||
|
||||
Input.PublicKeyHash = require('./publicKeyHash');
|
||||
Input.ScriptHash = require('./scriptHash');
|
||||
|
||||
module.exports = Input;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
var errors = require('../../errors');
|
||||
var BufferWriter = require('../../encoding/bufferwriter');
|
||||
var buffer = require('buffer');
|
||||
var bufferUtil = require('../../util/buffer');
|
||||
|
@ -31,6 +32,7 @@ Input.prototype._fromObject = function(params) {
|
|||
if (_.isString(params.prevTxId) && JSUtil.isHexa(params.prevTxId)) {
|
||||
params.prevTxId = new buffer.Buffer(params.prevTxId, 'hex');
|
||||
}
|
||||
this.output = params.output;
|
||||
this.prevTxId = params.prevTxId;
|
||||
this.outputIndex = params.outputIndex;
|
||||
this.sequenceNumber = params.sequenceNumber;
|
||||
|
@ -106,4 +108,19 @@ Input.prototype.setScript = function(script) {
|
|||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve signatures for the provided PrivateKey.
|
||||
*
|
||||
* @param {Transaction} transaction - the transaction to be signed
|
||||
* @param {PrivateKey} privateKey - the private key to use when signing
|
||||
* @param {number} inputIndex - the index of this input in the provided transaction
|
||||
* @param {number} sigType - defaults to Signature.SIGHASH_ALL
|
||||
* @param {Buffer} addressHash - if provided, don't calculate the hash of the
|
||||
* public key associated with the private key provided
|
||||
* @abstract
|
||||
*/
|
||||
Input.prototype.getSignatures = function() {
|
||||
throw new errors.AbstractMethodInvoked('Input#getSignatures');
|
||||
};
|
||||
|
||||
module.exports = Input;
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
'use strict';
|
||||
|
||||
var inherits = require('inherits');
|
||||
var Input = require('./input');
|
||||
var Hash = require('../../crypto/hash');
|
||||
var Signature = require('../../crypto/signature');
|
||||
var Sighash = require('../sighash');
|
||||
var BufferUtil = require('../../util/buffer');
|
||||
|
||||
function PublicKeyHashInput() {
|
||||
}
|
||||
inherits(PublicKeyHashInput, Input);
|
||||
|
||||
PublicKeyHashInput.prototype.getSignatures = function(transaction, privateKey, index, sigtype, hashData) {
|
||||
hashData = hashData || Hash.sha256ripemd160(privateKey.publicKey.toBuffer());
|
||||
sigtype = sigtype || Signature.SIGHASH_ALL;
|
||||
if (BufferUtil.equals(hashData, this.output.script.address.hashData)) {
|
||||
return [{
|
||||
address: this.output.script.address,
|
||||
publicKey: privateKey.publicKey,
|
||||
prevTxId: this.txId,
|
||||
outputIndex: this.outputIndex,
|
||||
inputIndex: index,
|
||||
signature: Sighash.sign(transaction, privateKey, sigtype, index, this.output.script),
|
||||
sigtype: sigtype
|
||||
}];
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
module.exports = PublicKeyHashInput;
|
|
@ -0,0 +1,31 @@
|
|||
'use strict';
|
||||
|
||||
var inherits = require('inherits');
|
||||
var Input = require('./input');
|
||||
var Hash = require('../../crypto/hash');
|
||||
var Signature = require('../../crypto/signature');
|
||||
var Sighash = require('../sighash');
|
||||
var BufferUtil = require('../../util/buffer');
|
||||
|
||||
function ScriptHashInput() {
|
||||
}
|
||||
inherits(ScriptHashInput, Input);
|
||||
|
||||
ScriptHashInput.prototype.getSignatures = function(transaction, privateKey, index, sigtype, hashData) {
|
||||
hashData = hashData || Hash.sha256ripemd160(privateKey.publicKey.toBuffer());
|
||||
sigtype = sigtype || Signature.SIGHASH_ALL;
|
||||
if (BufferUtil.equals(hashData, this.output.script.address.hashData)) {
|
||||
return [{
|
||||
address: this.output.script.address,
|
||||
publicKey: privateKey.publicKey,
|
||||
prevTxId: this.txId,
|
||||
outputIndex: this.outputIndex,
|
||||
inputIndex: index,
|
||||
signature: Sighash.sign(transaction, privateKey, sigtype, index, this.output.script),
|
||||
sigtype: sigtype
|
||||
}];
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
module.exports = ScriptHashInput;
|
|
@ -33,10 +33,8 @@ function Transaction(serialized) {
|
|||
this.inputs = [];
|
||||
this.outputs = [];
|
||||
this._outpoints = [];
|
||||
this._utxos = {};
|
||||
this._inputAmount = 0;
|
||||
this._outputAmount = 0;
|
||||
this._p2shMap = {};
|
||||
this._signatures = {};
|
||||
|
||||
if (serialized) {
|
||||
|
@ -228,12 +226,13 @@ Transaction._isNewUtxo = function(utxo) {
|
|||
};
|
||||
|
||||
Transaction.prototype._fromNewUtxo = function(utxo) {
|
||||
var outpoint = Transaction._makeOutpoint(utxo);
|
||||
utxo.address = utxo.address && new Address(utxo.address);
|
||||
utxo.script = new Script(util.isHexa(utxo.script) ? new buffer.Buffer(utxo.script, 'hex') : utxo.script);
|
||||
this._utxos[outpoint] = utxo;
|
||||
this._outpoints.push(outpoint);
|
||||
this.inputs.push(new Input({
|
||||
output: new Output({
|
||||
script: utxo.script,
|
||||
satoshis: utxo.satoshis
|
||||
}),
|
||||
prevTxId: utxo.txId,
|
||||
outputIndex: utxo.outputIndex,
|
||||
sequenceNumber: DEFAULT_SEQNUMBER,
|
||||
|
@ -254,9 +253,8 @@ Transaction._makeOutpoint = function(data) {
|
|||
};
|
||||
|
||||
Transaction.prototype.hasAllUtxoInfo = function() {
|
||||
var self = this;
|
||||
return _.all(this._outpoints.map(function(outpoint) {
|
||||
return !!self._utxos[outpoint];
|
||||
return _.all(this.inputs.map(function(input) {
|
||||
return !!input.output;
|
||||
}));
|
||||
};
|
||||
|
||||
|
@ -328,42 +326,22 @@ Transaction.prototype.sign = function(privKey) {
|
|||
return this;
|
||||
};
|
||||
|
||||
Transaction.prototype._getPrivateKeySignatures = function(privKey) {
|
||||
Transaction.prototype._getPrivateKeySignatures = function(privKey, sigtype) {
|
||||
privKey = new PrivateKey(privKey);
|
||||
sigtype = sigtype || Signature.SIGHASH_ALL;
|
||||
var transaction = this;
|
||||
var results = [];
|
||||
var hashData = Hash.sha256ripemd160(privKey.publicKey.toBuffer());
|
||||
_.each(this._outpoints, function forEachOutput(outpoint, index) {
|
||||
var utxo = transaction._utxos[outpoint];
|
||||
if ((utxo.address && utxo.address.isPayToPublicKeyHash()) || utxo.script.isPublicKeyHashOut()) {
|
||||
var address = new Address(utxo.address || utxo.script);
|
||||
if (bufferUtil.equals(hashData, address.hashBuffer)) {
|
||||
results.push({
|
||||
publicKey: privKey.publicKey,
|
||||
prevTxId: utxo.txId,
|
||||
outputIndex: utxo.outputIndex,
|
||||
inputIndex: index,
|
||||
signature: Sighash.sign(transaction, privKey, Signature.SIGHASH_ALL, index, utxo.script),
|
||||
sigtype: Signature.SIGHASH_ALL
|
||||
_.each(this.inputs, function forEachInput(input, index) {
|
||||
_.each(input.getSignatures(transaction, privKey, index, sigtype, hashData), function(signature) {
|
||||
results.push(signature);
|
||||
});
|
||||
} else {
|
||||
;
|
||||
}
|
||||
} else {
|
||||
;
|
||||
}
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
Transaction.prototype.applySignature = function(signature) {
|
||||
this.inputs[signature.inputIndex].setScript(
|
||||
Script.buildPublicKeyHashIn(
|
||||
signature.publicKey,
|
||||
signature.signature.toDER(),
|
||||
signature.sigtype
|
||||
)
|
||||
);
|
||||
this.inputs[signature.inputIndex].addSignature(signature);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue