mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-25 15:20:17 +01:00
Fixing bug with signature serialization - if we have more inputs than outputs & we are using SIGHASH_SINGLE the errorHash is signed
This commit is contained in:
parent
d957cb7a93
commit
dfc173c29d
3 changed files with 23 additions and 6 deletions
|
@ -47,6 +47,11 @@ trait TransactionSignatureSerializer extends RawBitcoinSerializerHelper with Bit
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
def serializeForSignature(spendingTransaction : Transaction, inputIndex : Int, script : ScriptPubKey, hashType : HashType) : Seq[Byte] = {
|
def serializeForSignature(spendingTransaction : Transaction, inputIndex : Int, script : ScriptPubKey, hashType : HashType) : Seq[Byte] = {
|
||||||
|
logger.debug("Serializing for signature")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Clear input scripts in preparation for signing. If we're signing a fresh
|
// Clear input scripts in preparation for signing. If we're signing a fresh
|
||||||
// transaction that step isn't very helpful, but it doesn't add much cost relative to the actual
|
// transaction that step isn't very helpful, but it doesn't add much cost relative to the actual
|
||||||
// EC math so we'll do it anyway.
|
// EC math so we'll do it anyway.
|
||||||
|
@ -147,9 +152,20 @@ trait TransactionSignatureSerializer extends RawBitcoinSerializerHelper with Bit
|
||||||
* @param hashType
|
* @param hashType
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
def hashForSignature(spendingTransction : Transaction, inputIndex : Int, script : ScriptPubKey, hashType : HashType) : Seq[Byte] = {
|
def hashForSignature(spendingTransaction : Transaction, inputIndex : Int, script : ScriptPubKey, hashType : HashType) : Seq[Byte] = {
|
||||||
val serializedTxForSignature = serializeForSignature(spendingTransction,inputIndex,script,hashType)
|
//these first two checks are in accordance with behavior in bitcoin core
|
||||||
CryptoUtil.doubleSHA256(serializedTxForSignature)
|
//https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L1112-L1123
|
||||||
|
if (inputIndex >= spendingTransaction.inputs.size ) {
|
||||||
|
logger.warn("Our inputIndex is out of the range of the inputs in the spending transaction")
|
||||||
|
errorHash
|
||||||
|
}
|
||||||
|
else if(hashType == SIGHASH_SINGLE && inputIndex >= spendingTransaction.outputs.size) {
|
||||||
|
logger.warn("When we have a SIGHASH_SINGLE we cannot have more inputs than outputs")
|
||||||
|
errorHash
|
||||||
|
} else {
|
||||||
|
val serializedTxForSignature = serializeForSignature(spendingTransaction,inputIndex,script,hashType)
|
||||||
|
CryptoUtil.doubleSHA256(serializedTxForSignature)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -49,14 +49,14 @@ class TransactionTest extends FlatSpec with MustMatchers with BitcoinSLogger {
|
||||||
|
|
||||||
|
|
||||||
//use this to represent a single test case from script_valid.json
|
//use this to represent a single test case from script_valid.json
|
||||||
/* val lines =
|
val lines =
|
||||||
"""
|
"""
|
||||||
|[
|
|[
|
||||||
|[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0xe52b482f2faa8ecbf0db344f93c84ac908557f33 EQUALVERIFY CHECKSIG"], ["0000000000000000000000000000000000000000000000000000000000000200", 0, "1"]],
|
|[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0xe52b482f2faa8ecbf0db344f93c84ac908557f33 EQUALVERIFY CHECKSIG"], ["0000000000000000000000000000000000000000000000000000000000000200", 0, "1"]],
|
||||||
|"01000000020002000000000000000000000000000000000000000000000000000000000000000000000151ffffffff0001000000000000000000000000000000000000000000000000000000000000000000006b483045022100c9cdd08798a28af9d1baf44a6c77bcc7e279f47dc487c8c899911bc48feaffcc0220503c5c50ae3998a733263c5c0f7061b483e2b56c4c41b456e7d2f5a78a74c077032102d5c25adb51b61339d2b05315791e21bbe80ea470a49db0135720983c905aace0ffffffff010000000000000000015100000000", "P2SH"]
|
|"01000000020002000000000000000000000000000000000000000000000000000000000000000000000151ffffffff0001000000000000000000000000000000000000000000000000000000000000000000006b483045022100c9cdd08798a28af9d1baf44a6c77bcc7e279f47dc487c8c899911bc48feaffcc0220503c5c50ae3998a733263c5c0f7061b483e2b56c4c41b456e7d2f5a78a74c077032102d5c25adb51b61339d2b05315791e21bbe80ea470a49db0135720983c905aace0ffffffff010000000000000000015100000000", "P2SH"]
|
||||||
|]
|
|]
|
||||||
""".stripMargin*/
|
""".stripMargin
|
||||||
val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
|
//val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
|
||||||
val json = lines.parseJson
|
val json = lines.parseJson
|
||||||
val testCasesOpt : Seq[Option[CoreTransactionTestCase]] = json.convertTo[Seq[Option[CoreTransactionTestCase]]]
|
val testCasesOpt : Seq[Option[CoreTransactionTestCase]] = json.convertTo[Seq[Option[CoreTransactionTestCase]]]
|
||||||
val testCases : Seq[CoreTransactionTestCase] = testCasesOpt.flatten
|
val testCases : Seq[CoreTransactionTestCase] = testCasesOpt.flatten
|
||||||
|
|
|
@ -17,6 +17,7 @@ trait CoreTransactionTestCase {
|
||||||
def scriptPubKeys : Seq[ScriptPubKey] = creditingTxsInfo.map(_._2)
|
def scriptPubKeys : Seq[ScriptPubKey] = creditingTxsInfo.map(_._2)
|
||||||
|
|
||||||
def creditingTxsInfo : Seq[(TransactionOutPoint, ScriptPubKey)]
|
def creditingTxsInfo : Seq[(TransactionOutPoint, ScriptPubKey)]
|
||||||
|
|
||||||
def spendingTx : Transaction
|
def spendingTx : Transaction
|
||||||
|
|
||||||
def flags : Seq[ScriptFlag]
|
def flags : Seq[ScriptFlag]
|
||||||
|
|
Loading…
Add table
Reference in a new issue