-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added support for signing publickey inputs.
- Loading branch information
Braydon Fuller
committed
Jul 27, 2015
1 parent
f77da04
commit eb077eb
Showing
7 changed files
with
210 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
module.exports = require('./input'); | ||
|
||
module.exports.PublicKey = require('./publickey'); | ||
module.exports.PublicKeyHash = require('./publickeyhash'); | ||
module.exports.MultiSigScriptHash = require('./multisigscripthash.js'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
}); | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters