|
|
@ -22,15 +22,6 @@ var ENABLE_SIGHASH_FORKID = true; |
|
|
|
|
|
|
|
|
|
|
|
var sighashForForkId = function(transaction, sighashType, inputNumber, subscript, satoshisBN) { |
|
|
|
|
|
|
|
console.log('[sighash.js.56:SIGHASH_FORKID:]'); //TODO
|
|
|
|
console.log('[sighash.js.29:transaction:]', transaction); //TODO
|
|
|
|
console.log('[sighash.js.29:sighashType:]', sighashType); //TODO
|
|
|
|
console.log('[sighash.js.29:inputNumber:]', inputNumber); //TODO
|
|
|
|
console.log('[sighash.js.29:subscript:]', subscript); //TODO
|
|
|
|
console.log('[sighash.js.24:satoshisBN:]',satoshisBN); //TODO
|
|
|
|
console.log('========================================================'); |
|
|
|
|
|
|
|
var input = transaction.inputs[inputNumber]; |
|
|
|
$.checkArgument( |
|
|
|
satoshisBN instanceof BN || (input.output && input.output._satoshisBN), |
|
|
@ -43,32 +34,44 @@ console.log('========================================================'); |
|
|
|
return 0; // In the UAHF, a fork id of 0 is used (see [4] REQ-6-2 NOTE 4)
|
|
|
|
}; |
|
|
|
|
|
|
|
function GetPrevoutHash() { |
|
|
|
var buf = new BufferWriter() |
|
|
|
// for ( n = 0; n < txTo.vin.size(); n++) {
|
|
|
|
// ss << txTo.vin[n].prevout;
|
|
|
|
// }
|
|
|
|
return buf.GetHash(); |
|
|
|
} |
|
|
|
function GetPrevoutHash(tx) { |
|
|
|
var writer = new BufferWriter() |
|
|
|
|
|
|
|
function GetSequenceHash() { |
|
|
|
// CHashWriter ss(SER_GETHASH, 0);
|
|
|
|
// for ( n = 0; n < txTo.vin.size(); n++) {
|
|
|
|
// ss << txTo.vin[n].nSequence;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// return ss.GetHash();
|
|
|
|
_.each(tx.inputs, function(input) { |
|
|
|
writer.writeReverse(input.prevTxId); |
|
|
|
writer.writeUInt32LE(input.outputIndex); |
|
|
|
}); |
|
|
|
|
|
|
|
var buf = writer.toBuffer(); |
|
|
|
var ret = Hash.sha256sha256(buf); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
function GetOutputsHash(tx) { |
|
|
|
function GetSequenceHash(tx) { |
|
|
|
var writer = new BufferWriter() |
|
|
|
_.each(tx.outputs, function(output) { |
|
|
|
output.toBufferWriter(writer); |
|
|
|
|
|
|
|
_.each(tx.inputs, function(input) { |
|
|
|
writer.writeUInt32LE(input.sequenceNumber); |
|
|
|
}); |
|
|
|
|
|
|
|
var buf = writer.toBuffer(); |
|
|
|
var ret = Hash.sha256sha256(buf); |
|
|
|
console.log('[sighash.js.58:ret:]',ret); //TODO
|
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
function GetOutputsHash(tx, n) { |
|
|
|
var writer = new BufferWriter() |
|
|
|
|
|
|
|
if ( _.isUndefined(n)) { |
|
|
|
_.each(tx.outputs, function(output) { |
|
|
|
output.toBufferWriter(writer); |
|
|
|
}); |
|
|
|
} else { |
|
|
|
tx.outputs[n].toBufferWriter(writer); |
|
|
|
} |
|
|
|
|
|
|
|
var buf = writer.toBuffer(); |
|
|
|
var ret = Hash.sha256sha256(buf); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
@ -78,29 +81,19 @@ console.log('[sighash.js.58:ret:]',ret); //TODO |
|
|
|
var hashOutputs = BufferUtil.emptyBuffer(32); |
|
|
|
|
|
|
|
if (!(sighashType & Signature.SIGHASH_ANYONECANPAY)) { |
|
|
|
console.log('NOT [sighash.js.62:SIGHASH_ANYONECANPAY:]'); //TODO
|
|
|
|
// hashPrevouts = cache ? cache->hashPrevouts : GetPrevoutHash(txTo);
|
|
|
|
hashPrevouts = GetPrevoutHash(transaction); |
|
|
|
} |
|
|
|
|
|
|
|
if (!(sighashType & Signature.SIGHASH_ANYONECANPAY) && |
|
|
|
(sighashType & 31) != Signature.SIGHASH_SINGLE && |
|
|
|
(sighashType & 31) != Signature.SIGHASH_NONE) { |
|
|
|
console.log('NOT [sighash.js.62:SIGHASH_ANYONECANPAY:] & !SINGLE && !NONE'); //TODO
|
|
|
|
// hashSequence = cache ? cache->hashSequence : GetSequenceHash(txTo);
|
|
|
|
hashSequence = GetSequenceHash(transaction); |
|
|
|
} |
|
|
|
|
|
|
|
if ((sighashType & 31) != Signature.SIGHASH_SINGLE && |
|
|
|
(sighashType & 31) != Signature.SIGHASH_NONE) { |
|
|
|
console.log('!SINGLE && !NONE'); //TODO
|
|
|
|
if ((sighashType & 31) != Signature.SIGHASH_SINGLE && (sighashType & 31) != Signature.SIGHASH_NONE) { |
|
|
|
hashOutputs = GetOutputsHash(transaction); |
|
|
|
console.log('[sighash.js.94:hashOutputs:]',hashOutputs); //TODO
|
|
|
|
|
|
|
|
} else if ((sighashType & 31) == Signature.SIGHASH_SINGLE && |
|
|
|
nIn < txTo.vout.size()) { |
|
|
|
console.log('SINGLE'); //TODO
|
|
|
|
// CHashWriter ss(SER_GETHASH, 0);
|
|
|
|
// ss << txTo.vout[nIn];
|
|
|
|
// hashOutputs = ss.GetHash();
|
|
|
|
} else if ((sighashType & 31) == Signature.SIGHASH_SINGLE && inputNumber < transaction.outputs.length) { |
|
|
|
hashOutputs = GetOutputsHash(transaction, inputNumber); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -119,56 +112,38 @@ function getHash (w) { |
|
|
|
// Version
|
|
|
|
writer.writeInt32LE(transaction.version); |
|
|
|
|
|
|
|
|
|
|
|
// // Input prevouts/nSequence (none/all, depending on flags)
|
|
|
|
// Input prevouts/nSequence (none/all, depending on flags)
|
|
|
|
writer.write(hashPrevouts); |
|
|
|
writer.write(hashSequence); |
|
|
|
// OK
|
|
|
|
|
|
|
|
// outpoint (32-byte hash + 4-byte little endian)
|
|
|
|
writer.writeReverse(input.prevTxId); |
|
|
|
writer.writeUInt32LE(input.outputIndex); |
|
|
|
// OK
|
|
|
|
|
|
|
|
// scriptCode of the input (serialized as scripts inside CTxOuts)
|
|
|
|
writer.writeUInt8(subscript.toBuffer().length) |
|
|
|
writer.write(subscript.toBuffer()); |
|
|
|
// OK
|
|
|
|
|
|
|
|
// value of the output spent by this input (8-byte little endian)
|
|
|
|
writer.writeUInt64LEBN(satoshisBN); |
|
|
|
|
|
|
|
// OK
|
|
|
|
|
|
|
|
// nSequence of the input (4-byte little endian)
|
|
|
|
var sequenceNumber = input.sequenceNumber; |
|
|
|
writer.writeUInt32LE(sequenceNumber); |
|
|
|
//ok
|
|
|
|
|
|
|
|
// Outputs (none/one/all, depending on flags)
|
|
|
|
writer.write(hashOutputs); |
|
|
|
//Ok
|
|
|
|
|
|
|
|
// Locktime
|
|
|
|
writer.writeUInt32LE(transaction.nLockTime); |
|
|
|
//OK
|
|
|
|
|
|
|
|
// sighashType
|
|
|
|
//writer.writeUInt32LE((GetForkId() << 24) | (sighashType & 31));
|
|
|
|
console.log('[sighash.js.158:sighashType:]',sighashType); //TODO
|
|
|
|
writer.writeUInt32LE(sighashType >>>0); |
|
|
|
//OK!
|
|
|
|
|
|
|
|
var buf = writer.toBuffer(); |
|
|
|
var ret = Hash.sha256sha256(buf); |
|
|
|
ret = new BufferReader(ret).readReverse(); |
|
|
|
return ret; |
|
|
|
|
|
|
|
//
|
|
|
|
// writer.writeVarintNum(this.inputs.length);
|
|
|
|
// _.each(this.inputs, function(input) {
|
|
|
|
// input.toBufferWriter(writer);
|
|
|
|
// });
|
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@ -196,12 +171,9 @@ var sighash = function sighash(transaction, sighashType, inputNumber, subscript, |
|
|
|
subscript = new Script(subscript); |
|
|
|
|
|
|
|
|
|
|
|
console.log('[sighash.js.197] type, ', sighashType, Signature.SIGHASH_FORKID, sighashType & Signature.SIGHASH_FORKID ); //TODO
|
|
|
|
|
|
|
|
if ( ( sighashType & Signature.SIGHASH_FORKID) && ENABLE_SIGHASH_FORKID) { |
|
|
|
return sighashForForkId(txcopy, sighashType, inputNumber, subscript, opts.satoshisBN); |
|
|
|
} |
|
|
|
console.log('[sighash.js.200] NO FORKID'); //TODO
|
|
|
|
|
|
|
|
// For no ForkId sighash, separators need to be removed.
|
|
|
|
subscript.removeCodeseparators(); |
|
|
@ -249,7 +221,6 @@ console.log('[sighash.js.200] NO FORKID'); //TODO |
|
|
|
if (sighashType & Signature.SIGHASH_ANYONECANPAY) { |
|
|
|
txcopy.inputs = [txcopy.inputs[inputNumber]]; |
|
|
|
} |
|
|
|
console.log('[sighash.js.252:sighashType:]',sighashType); //TODO
|
|
|
|
|
|
|
|
var buf = new BufferWriter() |
|
|
|
.write(txcopy.toBuffer()) |
|
|
|