Transaction: refactor hashForSignature
Adds asserts to ensure only valid hashes are created (until the implementation is complete). Also uses `Script.without` to remove OP_CODESEPARATOR from the Scripts as required by the protocol.
This commit is contained in:
parent
7d94d1b068
commit
2f44628604
1 changed files with 17 additions and 32 deletions
|
@ -9,6 +9,7 @@ var convert = require('./convert')
|
||||||
var crypto = require('./crypto')
|
var crypto = require('./crypto')
|
||||||
var ECKey = require('./eckey')
|
var ECKey = require('./eckey')
|
||||||
var ecdsa = require('./ecdsa')
|
var ecdsa = require('./ecdsa')
|
||||||
|
var opcodes = require('./opcodes')
|
||||||
|
|
||||||
var DEFAULT_SEQUENCE = 0xffffffff
|
var DEFAULT_SEQUENCE = 0xffffffff
|
||||||
|
|
||||||
|
@ -196,49 +197,37 @@ var SIGHASH_ANYONECANPAY = 0x80
|
||||||
* hashType, serializes and finally hashes the result. This hash can then be
|
* hashType, serializes and finally hashes the result. This hash can then be
|
||||||
* used to sign the transaction input in question.
|
* used to sign the transaction input in question.
|
||||||
*/
|
*/
|
||||||
Transaction.prototype.hashForSignature =
|
Transaction.prototype.hashForSignature = function(scriptPubKey, inIndex, hashType) {
|
||||||
function (connectedScript, inIndex, hashType)
|
assert(inIndex >= 0, 'Invalid vin index')
|
||||||
{
|
assert(inIndex < this.ins.length, 'Invalid vin index')
|
||||||
var txTmp = this.clone()
|
assert(scriptPubKey instanceof Script, 'Invalid Script object')
|
||||||
|
|
||||||
// In case concatenating two scripts ends up with two codeseparators,
|
var txTmp = this.clone()
|
||||||
// or an extra one at the end, this prevents all those possible
|
var hashScript = scriptPubKey.without(opcodes.OP_CODESEPARATOR)
|
||||||
// incompatibilities.
|
|
||||||
/*scriptCode = scriptCode.filter(function (val) {
|
|
||||||
return val !== OP_CODESEPARATOR
|
|
||||||
});*/
|
|
||||||
|
|
||||||
// Blank out other inputs' signatures
|
// Blank out other inputs' signatures
|
||||||
txTmp.ins.forEach(function(txin) {
|
txTmp.ins.forEach(function(txin) {
|
||||||
txin.script = new Script()
|
txin.script = new Script()
|
||||||
})
|
})
|
||||||
|
txTmp.ins[inIndex].script = hashScript
|
||||||
|
|
||||||
txTmp.ins[inIndex].script = connectedScript
|
var hashTypeModifier = hashType & 0x1f
|
||||||
|
if (hashTypeModifier === SIGHASH_NONE) {
|
||||||
|
assert(false, 'SIGHASH_NONE not yet supported')
|
||||||
|
|
||||||
// Blank out some of the outputs
|
} else if (hashTypeModifier === SIGHASH_SINGLE) {
|
||||||
if ((hashType & 0x1f) == SIGHASH_NONE) {
|
assert(false, 'SIGHASH_SINGLE not yet supported')
|
||||||
txTmp.outs = []
|
|
||||||
|
|
||||||
// Let the others update at will
|
|
||||||
txTmp.ins.forEach(function(txin, i) {
|
|
||||||
if (i != inIndex) {
|
|
||||||
txTmp.ins[i].sequence = 0
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
} else if ((hashType & 0x1f) == SIGHASH_SINGLE) {
|
|
||||||
// TODO: Implement
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blank out other inputs completely, not recommended for open transactions
|
|
||||||
if (hashType & SIGHASH_ANYONECANPAY) {
|
if (hashType & SIGHASH_ANYONECANPAY) {
|
||||||
txTmp.ins = [txTmp.ins[inIndex]]
|
assert(false, 'SIGHASH_ANYONECANPAY not yet supported')
|
||||||
}
|
}
|
||||||
|
|
||||||
var htB = new Buffer(4)
|
var hashTypeBuffer = new Buffer(4)
|
||||||
htB.writeUInt32LE(hashType, 0)
|
hashTypeBuffer.writeInt32LE(hashType, 0)
|
||||||
|
|
||||||
var buffer = Buffer.concat([txTmp.toBuffer(), htB])
|
var buffer = Buffer.concat([txTmp.toBuffer(), hashTypeBuffer])
|
||||||
return crypto.hash256(buffer)
|
return crypto.hash256(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,11 +353,7 @@ Transaction.prototype.sign = function(index, key, type) {
|
||||||
|
|
||||||
Transaction.prototype.signScriptSig = function(index, scriptPubKey, key, type) {
|
Transaction.prototype.signScriptSig = function(index, scriptPubKey, key, type) {
|
||||||
type = type || SIGHASH_ALL
|
type = type || SIGHASH_ALL
|
||||||
|
|
||||||
assert((index >= 0), 'Invalid vin index')
|
|
||||||
assert(scriptPubKey instanceof Script, 'Invalid Script object')
|
|
||||||
assert(key instanceof ECKey, 'Invalid private key')
|
assert(key instanceof ECKey, 'Invalid private key')
|
||||||
// assert.equal(type & 0x7F, type, 'Invalid type') // TODO
|
|
||||||
|
|
||||||
var hash = this.hashForSignature(scriptPubKey, index, type)
|
var hash = this.hashForSignature(scriptPubKey, index, type)
|
||||||
var signature = key.sign(hash)
|
var signature = key.sign(hash)
|
||||||
|
|
Loading…
Reference in a new issue