7 changed files with 210 additions and 7 deletions
@ -1,4 +1,5 @@ |
|||
module.exports = require('./input'); |
|||
|
|||
module.exports.PublicKey = require('./publickey'); |
|||
module.exports.PublicKeyHash = require('./publickeyhash'); |
|||
module.exports.MultiSigScriptHash = require('./multisigscripthash.js'); |
|||
|
@ -0,0 +1,89 @@ |
|||
'use strict'; |
|||
|
|||
var inherits = require('inherits'); |
|||
|
|||
var $ = require('../../util/preconditions'); |
|||
var BufferUtil = require('../../util/buffer'); |
|||
|
|||
var Input = require('./input'); |
|||
var Output = require('../output'); |
|||
var Sighash = require('../sighash'); |
|||
var Script = require('../../script'); |
|||
var Signature = require('../../crypto/signature'); |
|||
var TransactionSignature = require('../signature'); |
|||
|
|||
/** |
|||
* Represents a special kind of input of PayToPublicKey kind. |
|||
* @constructor |
|||
*/ |
|||
function PublicKeyInput() { |
|||
Input.apply(this, arguments); |
|||
} |
|||
inherits(PublicKeyInput, Input); |
|||
|
|||
/** |
|||
* @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=} sigtype - the type of signature, defaults to Signature.SIGHASH_ALL |
|||
* @return {Array} of objects that can be |
|||
*/ |
|||
PublicKeyInput.prototype.getSignatures = function(transaction, privateKey, index, sigtype) { |
|||
$.checkState(this.output instanceof Output); |
|||
sigtype = sigtype || Signature.SIGHASH_ALL; |
|||
var publicKey = privateKey.toPublicKey(); |
|||
if (publicKey.toString() === this.output.script.getPublicKey().toString('hex')) { |
|||
return [new TransactionSignature({ |
|||
publicKey: publicKey, |
|||
prevTxId: this.prevTxId, |
|||
outputIndex: this.outputIndex, |
|||
inputIndex: index, |
|||
signature: Sighash.sign(transaction, privateKey, sigtype, index, this.output.script), |
|||
sigtype: sigtype |
|||
})]; |
|||
} |
|||
return []; |
|||
}; |
|||
|
|||
/** |
|||
* Add the provided signature |
|||
* |
|||
* @param {Object} signature |
|||
* @param {PublicKey} signature.publicKey |
|||
* @param {Signature} signature.signature |
|||
* @param {number=} signature.sigtype |
|||
* @return {PublicKeyInput} this, for chaining |
|||
*/ |
|||
PublicKeyInput.prototype.addSignature = function(transaction, signature) { |
|||
$.checkState(this.isValidSignature(transaction, signature), 'Signature is invalid'); |
|||
this.setScript(Script.buildPublicKeyIn( |
|||
signature.signature.toDER(), |
|||
signature.sigtype |
|||
)); |
|||
return this; |
|||
}; |
|||
|
|||
/** |
|||
* Clear the input's signature |
|||
* @return {PublicKeyHashInput} this, for chaining |
|||
*/ |
|||
PublicKeyInput.prototype.clearSignatures = function() { |
|||
this.setScript(Script.empty()); |
|||
return this; |
|||
}; |
|||
|
|||
/** |
|||
* Query whether the input is signed |
|||
* @return {boolean} |
|||
*/ |
|||
PublicKeyInput.prototype.isFullySigned = function() { |
|||
return this.script.isPublicKeyIn(); |
|||
}; |
|||
|
|||
PublicKeyInput.SCRIPT_MAX_SIZE = 73; // sigsize (1 + 72)
|
|||
|
|||
PublicKeyInput.prototype._estimateSize = function() { |
|||
return PublicKeyInput.SCRIPT_MAX_SIZE; |
|||
}; |
|||
|
|||
module.exports = PublicKeyInput; |
@ -0,0 +1,71 @@ |
|||
'use strict'; |
|||
|
|||
var should = require('chai').should(); |
|||
var bitcore = require('../../..'); |
|||
var Transaction = bitcore.Transaction; |
|||
var PrivateKey = bitcore.PrivateKey; |
|||
|
|||
describe('PublicKeyInput', function() { |
|||
|
|||
var utxo = { |
|||
txid: '7f3b688cb224ed83e12d9454145c26ac913687086a0a62f2ae0bc10934a4030f', |
|||
vout: 0, |
|||
address: 'n4McBrSkw42eYGX5YMACGpkGUJKL3jVSbo', |
|||
scriptPubKey: '2103c9594cb2ebfebcb0cfd29eacd40ba012606a197beef76f0269ed8c101e56ceddac', |
|||
amount: 50, |
|||
confirmations: 104, |
|||
spendable: true |
|||
}; |
|||
var privateKey = PrivateKey.fromWIF('cQ7tSSQDEwaxg9usnnP1Aztqvm9nCQVfNWz9kU2rdocDjknF2vd6'); |
|||
var address = privateKey.toAddress(); |
|||
utxo.address.should.equal(address.toString()); |
|||
|
|||
var destKey = new PrivateKey(); |
|||
|
|||
it('will correctly sign a publickey out transaction', function() { |
|||
var tx = new Transaction(); |
|||
tx.from(utxo); |
|||
tx.to(destKey.toAddress(), 10000); |
|||
tx.sign(privateKey); |
|||
tx.inputs[0].script.toBuffer().length.should.be.above(0); |
|||
}); |
|||
|
|||
it('count can count missing signatures', function() { |
|||
var tx = new Transaction(); |
|||
tx.from(utxo); |
|||
tx.to(destKey.toAddress(), 10000); |
|||
var input = tx.inputs[0]; |
|||
input.isFullySigned().should.equal(false); |
|||
tx.sign(privateKey); |
|||
input.isFullySigned().should.equal(true); |
|||
}); |
|||
|
|||
it('it\'s size can be estimated', function() { |
|||
var tx = new Transaction(); |
|||
tx.from(utxo); |
|||
tx.to(destKey.toAddress(), 10000); |
|||
var input = tx.inputs[0]; |
|||
input._estimateSize().should.equal(73); |
|||
}); |
|||
|
|||
it('it\'s signature can be removed', function() { |
|||
var tx = new Transaction(); |
|||
tx.from(utxo); |
|||
tx.to(destKey.toAddress(), 10000); |
|||
var input = tx.inputs[0]; |
|||
tx.sign(privateKey); |
|||
input.isFullySigned().should.equal(true); |
|||
input.clearSignatures(); |
|||
input.isFullySigned().should.equal(false); |
|||
}); |
|||
|
|||
it('returns an empty array if private key mismatches', function() { |
|||
var tx = new Transaction(); |
|||
tx.from(utxo); |
|||
tx.to(destKey.toAddress(), 10000); |
|||
var input = tx.inputs[0]; |
|||
var signatures = input.getSignatures(tx, new PrivateKey(), 0); |
|||
signatures.length.should.equal(0); |
|||
}); |
|||
|
|||
}); |
Loading…
Reference in new issue