From 1535805f1ca65c376ccbaf17b1602eff2a3db714 Mon Sep 17 00:00:00 2001 From: Esteban Ordano Date: Thu, 11 Dec 2014 13:31:02 -0300 Subject: [PATCH] Add PublicKeyHashInput class --- lib/script.js | 6 +++ lib/transaction/input/publicKeyHash.js | 67 +++++++++++++++++++++++--- lib/transaction/input/scriptHash.js | 14 +----- 3 files changed, 68 insertions(+), 19 deletions(-) diff --git a/lib/script.js b/lib/script.js index 598f4b0..e14f982 100644 --- a/lib/script.js +++ b/lib/script.js @@ -9,6 +9,7 @@ var Opcode = require('./opcode'); var PublicKey = require('./publickey'); var Signature = require('./crypto/signature'); +var $ = require('./util/preconditions'); var _ = require('lodash'); var buffer = require('buffer'); var bufferUtil = require('./util/buffer'); @@ -225,6 +226,11 @@ Script.prototype.isPublicKeyHashIn = function() { PublicKey.isValid(this.chunks[1].buf); }; +Script.prototype.getPublicKeyHash = function() { + $.checkState(this.isPublicKeyHashOut(), 'Can\'t retrieve PublicKeyHash from a non-PKH output'); + return this.chunks[2].buf; +}; + /** * @returns true if this is a public key output script */ diff --git a/lib/transaction/input/publicKeyHash.js b/lib/transaction/input/publicKeyHash.js index 9e50418..a94b75c 100644 --- a/lib/transaction/input/publicKeyHash.js +++ b/lib/transaction/input/publicKeyHash.js @@ -1,22 +1,41 @@ '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 $ = require('../../util/preconditions'); var BufferUtil = require('../../util/buffer'); +var Hash = require('../../crypto/hash'); +var Input = require('./input'); +var Output = require('../output'); +var Sighash = require('../sighash'); +var Script = require('../../script'); +var Signature = require('../../crypto/signature'); + +/** + * Represents a special kind of input of PayToPublicKeyHash kind. + */ function PublicKeyHashInput() { + Input.apply(this, arguments); } inherits(PublicKeyHashInput, Input); +/* jshint maxparams: 5 */ +/** + * @param {Transaction} transaction - the transaction to be signed + * @param {PrivateKey} privateKey - the private key with which to sign the transaction + * @param {number} index - the index of the input in the transaction input vector + * @param {number=Singature.SIGHASH_ALL} sigtype - the type of signature + * @param {Buffer=} hashData - the precalculated hash of the public key associated with the privateKey provided + * @return {Array} of objects that can be + */ PublicKeyHashInput.prototype.getSignatures = function(transaction, privateKey, index, sigtype, hashData) { + $.checkState(this.output instanceof Output); hashData = hashData || Hash.sha256ripemd160(privateKey.publicKey.toBuffer()); sigtype = sigtype || Signature.SIGHASH_ALL; - if (BufferUtil.equals(hashData, this.output.script.address.hashData)) { + + if (BufferUtil.equals(hashData, this.output.script.getPublicKeyHash())) { return [{ - address: this.output.script.address, publicKey: privateKey.publicKey, prevTxId: this.txId, outputIndex: this.outputIndex, @@ -27,5 +46,41 @@ PublicKeyHashInput.prototype.getSignatures = function(transaction, privateKey, i } return []; }; +/* jshint maxparams: 3 */ + +/** + * Add the provided signature + * + * @param {Object} signature + * @param {PublicKey} signature.publicKey + * @param {Signature} signature.signature + * @param {number=Signature.SIGHASH_ALL} signature.sigtype + * @return {PublicKeyHashInput} this, for chaining + */ +PublicKeyHashInput.prototype.addSignature = function(signature) { + this.setScript(Script.buildPublicKeyHashIn( + signature.publicKey, + signature.signature.toDER(), + signature.sigtype + )); + return this; +}; + +/** + * Clear the input's signature + * @return {PublicKeyHashInput} this, for chaining + */ +PublicKeyHashInput.prototype.clearSignature = function() { + this.setScript(Script.empty()); + return this; +}; + +/** + * Query whether the input is signed + * @return {boolean} + */ +PublicKeyHashInput.prototype.isFullySigned = function() { + return this.script.isPublicKeyHashIn(); +}; module.exports = PublicKeyHashInput; diff --git a/lib/transaction/input/scriptHash.js b/lib/transaction/input/scriptHash.js index c7912b5..ad7cfae 100644 --- a/lib/transaction/input/scriptHash.js +++ b/lib/transaction/input/scriptHash.js @@ -8,23 +8,11 @@ var Sighash = require('../sighash'); var BufferUtil = require('../../util/buffer'); function ScriptHashInput() { + Input.apply(this, arguments); } 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 []; };