mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-24 06:57:51 +01:00
Refactoring WitnessTransactionSignatureComponent to take in a 'Transaction' type instead of a 'WitnessTransaction' type -- this is needed for the case of trying to spend a witness scriptPubKey with a base transaction. This won't succeed, but should be possible to try and run through the interpreter
This commit is contained in:
parent
df18ddec51
commit
27d23b1ca9
6 changed files with 28 additions and 36 deletions
|
@ -3,7 +3,7 @@ package org.bitcoins.core.crypto
|
|||
import org.bitcoins.core.currency.CurrencyUnit
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.script._
|
||||
import org.bitcoins.core.protocol.transaction.{Transaction, TransactionOutput, WitnessTransaction}
|
||||
import org.bitcoins.core.protocol.transaction.{BaseTransaction, Transaction, TransactionOutput, WitnessTransaction}
|
||||
import org.bitcoins.core.script.flag.ScriptFlag
|
||||
|
||||
/**
|
||||
|
@ -44,9 +44,10 @@ sealed trait BaseTransactionSignatureComponent extends TransactionSignatureCompo
|
|||
*/
|
||||
sealed trait WitnessV0TransactionSignatureComponent extends TransactionSignatureComponent {
|
||||
|
||||
override def transaction: WitnessTransaction
|
||||
|
||||
def witness: ScriptWitness = transaction.witness.witnesses(inputIndex.toInt)
|
||||
def witness: ScriptWitness = transaction match {
|
||||
case wtx: WitnessTransaction => wtx.witness.witnesses(inputIndex.toInt)
|
||||
case btx: BaseTransaction => EmptyScriptWitness
|
||||
}
|
||||
|
||||
/** The amount of [[CurrencyUnit]] this input is spending */
|
||||
def amount: CurrencyUnit
|
||||
|
@ -60,7 +61,7 @@ object TransactionSignatureComponent {
|
|||
scriptPubKey : ScriptPubKey, flags : Seq[ScriptFlag]) extends BaseTransactionSignatureComponent
|
||||
|
||||
|
||||
def apply(transaction : WitnessTransaction, inputIndex : UInt32, scriptPubKey : ScriptPubKey,
|
||||
def apply(transaction : Transaction, inputIndex : UInt32, scriptPubKey : ScriptPubKey,
|
||||
flags : Seq[ScriptFlag], amount: CurrencyUnit, signatureVersion: SignatureVersion) : TransactionSignatureComponent = {
|
||||
signatureVersion match {
|
||||
case SigVersionBase =>
|
||||
|
@ -88,19 +89,19 @@ object TransactionSignatureComponent {
|
|||
}
|
||||
|
||||
object WitnessV0TransactionSignatureComponent {
|
||||
private case class WitnessV0TransactionSignatureComponentImpl(transaction : WitnessTransaction, inputIndex : UInt32,
|
||||
private case class WitnessV0TransactionSignatureComponentImpl(transaction : Transaction, inputIndex : UInt32,
|
||||
scriptPubKey : ScriptPubKey, flags : Seq[ScriptFlag],
|
||||
amount: CurrencyUnit, sigVersion: SignatureVersion) extends WitnessV0TransactionSignatureComponent
|
||||
|
||||
|
||||
def apply(transaction : WitnessTransaction, inputIndex : UInt32, scriptPubKey : ScriptPubKey,
|
||||
def apply(transaction : Transaction, inputIndex : UInt32, scriptPubKey : ScriptPubKey,
|
||||
flags : Seq[ScriptFlag], amount: CurrencyUnit, sigVersion: SignatureVersion) : WitnessV0TransactionSignatureComponent = {
|
||||
WitnessV0TransactionSignatureComponentImpl(transaction,inputIndex, scriptPubKey, flags, amount,sigVersion)
|
||||
}
|
||||
|
||||
/** Note: The output passed here is the output we are spending,
|
||||
* we use the [[CurrencyUnit]] and [[ScriptPubKey]] in that output for signing */
|
||||
def apply(transaction : WitnessTransaction, inputIndex : UInt32, output : TransactionOutput,
|
||||
def apply(transaction : Transaction, inputIndex : UInt32, output : TransactionOutput,
|
||||
flags : Seq[ScriptFlag], sigVersion: SignatureVersion): WitnessV0TransactionSignatureComponent = {
|
||||
WitnessV0TransactionSignatureComponent(transaction,inputIndex,output.scriptPubKey,flags,output.value, sigVersion)
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ trait TransactionSignatureSerializer extends RawBitcoinSerializerHelper with Bit
|
|||
* [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki]]
|
||||
* [[https://github.com/bitcoin/bitcoin/blob/f8528134fc188abc5c7175a19680206964a8fade/src/script/interpreter.cpp#L1113]]
|
||||
*/
|
||||
def serializeForSignature(spendingTx: WitnessTransaction, inputIndex: UInt32, script: Seq[ScriptToken], hashType: HashType,
|
||||
def serializeForSignature(spendingTx: Transaction, inputIndex: UInt32, script: Seq[ScriptToken], hashType: HashType,
|
||||
amount: CurrencyUnit, signatureVersion: SignatureVersion): Seq[Byte] = signatureVersion match {
|
||||
case SigVersionBase =>
|
||||
serializeForSignature(spendingTx,inputIndex,script,hashType)
|
||||
|
@ -216,7 +216,7 @@ trait TransactionSignatureSerializer extends RawBitcoinSerializerHelper with Bit
|
|||
* [[https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki]]
|
||||
* NOTE: This covers the amount of [[CurrencyUnit]] we are spending in the output
|
||||
* */
|
||||
def hashForSignature(spendingTx: WitnessTransaction, inputIndex: UInt32, script: Seq[ScriptToken], hashType: HashType,
|
||||
def hashForSignature(spendingTx: Transaction, inputIndex: UInt32, script: Seq[ScriptToken], hashType: HashType,
|
||||
amount: CurrencyUnit, sigVersion: SignatureVersion): DoubleSha256Digest = {
|
||||
|
||||
val serialization = serializeForSignature(spendingTx,inputIndex,script,hashType,amount,sigVersion)
|
||||
|
|
|
@ -21,6 +21,12 @@ sealed trait ScriptWitness extends NetworkElement {
|
|||
override def hex = RawScriptWitnessParser.write(this)
|
||||
}
|
||||
|
||||
case object EmptyScriptWitness extends ScriptWitness {
|
||||
override def stack = Nil
|
||||
|
||||
override def hex = "00"
|
||||
}
|
||||
|
||||
object ScriptWitness extends Factory[ScriptWitness] {
|
||||
private case class ScriptWitnessImpl(stack: Seq[Seq[Byte]]) extends ScriptWitness
|
||||
|
||||
|
@ -28,10 +34,6 @@ object ScriptWitness extends Factory[ScriptWitness] {
|
|||
|
||||
override def fromBytes(bytes: Seq[Byte]): ScriptWitness = RawScriptWitnessParser.read(bytes)
|
||||
|
||||
/*
|
||||
def fromHex(stack: Seq[Seq[String]]): ScriptWitness = ScriptWitness(stack.flatMap(_.map(BitcoinSUtil.decodeHex(_))))
|
||||
*/
|
||||
|
||||
def apply(signature: ECDigitalSignature, publicKey: ECPublicKey): ScriptWitness = {
|
||||
val sigConstant = signature.bytes
|
||||
val pubKeyConstant = publicKey.bytes
|
||||
|
|
|
@ -233,7 +233,7 @@ object ScriptProgram {
|
|||
* @param amount the amount of [[CurrencyUnit]] we are spending in this input
|
||||
* @return the script program representing all of this information
|
||||
*/
|
||||
def apply(transaction: WitnessTransaction, scriptPubKey : ScriptPubKey, inputIndex : UInt32,
|
||||
def apply(transaction: Transaction, scriptPubKey : ScriptPubKey, inputIndex : UInt32,
|
||||
flags : Seq[ScriptFlag],
|
||||
amount: CurrencyUnit) : PreExecutionScriptProgram = {
|
||||
val script = transaction.inputs(inputIndex.toInt).scriptSignature.asm
|
||||
|
@ -246,13 +246,13 @@ object ScriptProgram {
|
|||
ScriptProgram(p,stack,script)
|
||||
}
|
||||
|
||||
def apply(transaction: WitnessTransaction, scriptPubKey : ScriptPubKey, inputIndex : UInt32, script : Seq[ScriptToken],
|
||||
def apply(transaction: Transaction, scriptPubKey : ScriptPubKey, inputIndex : UInt32, script : Seq[ScriptToken],
|
||||
flags : Seq[ScriptFlag], amount: CurrencyUnit) : PreExecutionScriptProgram = {
|
||||
val sigVersion = BitcoinScriptUtil.parseSigVersion(transaction,scriptPubKey,inputIndex)
|
||||
ScriptProgram(transaction,scriptPubKey,inputIndex,Nil,script,script,Nil,flags,sigVersion,amount)
|
||||
}
|
||||
|
||||
def apply(transaction: WitnessTransaction, scriptPubKey : ScriptPubKey, inputIndex : UInt32, stack : Seq[ScriptToken],
|
||||
def apply(transaction: Transaction, scriptPubKey : ScriptPubKey, inputIndex : UInt32, stack : Seq[ScriptToken],
|
||||
script : Seq[ScriptToken], flags : Seq[ScriptFlag], witness: ScriptWitness,
|
||||
amount: CurrencyUnit) : ScriptProgram = {
|
||||
val program = ScriptProgram(transaction,scriptPubKey,inputIndex,flags, amount)
|
||||
|
@ -290,7 +290,7 @@ object ScriptProgram {
|
|||
}
|
||||
|
||||
/** Creates a fresh [[PreExecutionScriptProgram]] */
|
||||
def apply(transaction: WitnessTransaction, scriptPubKey: ScriptPubKey, inputIndex: UInt32, stack: Seq[ScriptToken],
|
||||
def apply(transaction: Transaction, scriptPubKey: ScriptPubKey, inputIndex: UInt32, stack: Seq[ScriptToken],
|
||||
script: Seq[ScriptToken], originalScript: Seq[ScriptToken], altStack: Seq[ScriptToken],
|
||||
flags: Seq[ScriptFlag], sigVersion: SignatureVersion,
|
||||
amount: CurrencyUnit): PreExecutionScriptProgram = {
|
||||
|
|
|
@ -4,7 +4,7 @@ import org.bitcoins.core.crypto._
|
|||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.CompactSizeUInt
|
||||
import org.bitcoins.core.protocol.script.{CLTVScriptPubKey, CSVScriptPubKey, EmptyScriptPubKey, _}
|
||||
import org.bitcoins.core.protocol.transaction.WitnessTransaction
|
||||
import org.bitcoins.core.protocol.transaction.{Transaction, WitnessTransaction}
|
||||
import org.bitcoins.core.script.ScriptProgram.PreExecutionScriptProgramImpl
|
||||
import org.bitcoins.core.script.constant._
|
||||
import org.bitcoins.core.script.crypto.{OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY, OP_CHECKSIG, OP_CHECKSIGVERIFY}
|
||||
|
@ -382,14 +382,14 @@ trait BitcoinScriptUtil extends BitcoinSLogger {
|
|||
}
|
||||
|
||||
/** Given a tx, scriptPubKey and the input index we are checking the tx, it derives the appropriate [[SignatureVersion]] to use */
|
||||
def parseSigVersion(wtx: WitnessTransaction, scriptPubKey: ScriptPubKey, inputIndex: UInt32): SignatureVersion = scriptPubKey match {
|
||||
def parseSigVersion(tx: Transaction, scriptPubKey: ScriptPubKey, inputIndex: UInt32): SignatureVersion = scriptPubKey match {
|
||||
case _ : WitnessScriptPubKeyV0 | _: UnassignedWitnessScriptPubKey =>
|
||||
SigVersionWitnessV0
|
||||
case _: P2SHScriptPubKey =>
|
||||
val scriptSig = wtx.inputs(inputIndex.toInt).scriptSignature
|
||||
val scriptSig = tx.inputs(inputIndex.toInt).scriptSignature
|
||||
scriptSig match {
|
||||
case s : P2SHScriptSignature =>
|
||||
parseSigVersion(wtx,s.redeemScript,inputIndex)
|
||||
parseSigVersion(tx,s.redeemScript,inputIndex)
|
||||
case _ : P2PKScriptSignature | _: P2PKHScriptSignature | _:MultiSignatureScriptSignature | _: NonStandardScriptSignature
|
||||
| _: CLTVScriptSignature | _: CSVScriptSignature | EmptyScriptSignature => SigVersionBase
|
||||
}
|
||||
|
|
|
@ -66,19 +66,8 @@ class TransactionTest extends FlatSpec with MustMatchers with BitcoinSLogger {
|
|||
//use this to represent a single test case from script_valid.json
|
||||
/* val lines =
|
||||
"""
|
||||
|[ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000],
|
||||
| ["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1001],
|
||||
| ["0000000000000000000000000000000000000000000000000000000000000100", 2, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1002],
|
||||
| ["0000000000000000000000000000000000000000000000000000000000000100", 3, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1003],
|
||||
| ["0000000000000000000000000000000000000000000000000000000000000100", 4, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1004],
|
||||
| ["0000000000000000000000000000000000000000000000000000000000000100", 5, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1005],
|
||||
| ["0000000000000000000000000000000000000000000000000000000000000100", 6, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1006],
|
||||
| ["0000000000000000000000000000000000000000000000000000000000000100", 7, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1007],
|
||||
| ["0000000000000000000000000000000000000000000000000000000000000100", 8, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1008],
|
||||
| ["0000000000000000000000000000000000000000000000000000000000000100", 9, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1009],
|
||||
| ["0000000000000000000000000000000000000000000000000000000000000100", 10, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1010],
|
||||
| ["0000000000000000000000000000000000000000000000000000000000000100", 11, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1011]],
|
||||
| "0100000000010c00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff0001000000000000000000000000000000000000000000000000000000000000020000006a473044022026c2e65b33fcd03b2a3b0f25030f0244bd23cc45ae4dec0f48ae62255b1998a00220463aa3982b718d593a6b9e0044513fd67a5009c2fdccc59992cffc2b167889f4012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000030000006a4730440220008bd8382911218dcb4c9f2e75bf5c5c3635f2f2df49b36994fde85b0be21a1a02205a539ef10fb4c778b522c1be852352ea06c67ab74200977c722b0bc68972575a012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000040000006b483045022100d9436c32ff065127d71e1a20e319e4fe0a103ba0272743dbd8580be4659ab5d302203fd62571ee1fe790b182d078ecfd092a509eac112bea558d122974ef9cc012c7012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000050000006a47304402200e2c149b114ec546015c13b2b464bbcb0cdc5872e6775787527af6cbc4830b6c02207e9396c6979fb15a9a2b96ca08a633866eaf20dc0ff3c03e512c1d5a1654f148012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000060000006b483045022100b20e70d897dc15420bccb5e0d3e208d27bdd676af109abbd3f88dbdb7721e6d6022005836e663173fbdfe069f54cde3c2decd3d0ea84378092a5d9d85ec8642e8a41012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff00010000000000000000000000000000000000000000000000000000000000000700000000ffffffff00010000000000000000000000000000000000000000000000000000000000000800000000ffffffff00010000000000000000000000000000000000000000000000000000000000000900000000ffffffff00010000000000000000000000000000000000000000000000000000000000000a00000000ffffffff00010000000000000000000000000000000000000000000000000000000000000b0000006a47304402206639c6e05e3b9d2675a7f3876286bdf7584fe2bbd15e0ce52dd4e02c0092cdc60220757d60b0a61fc95ada79d23746744c72bac1545a75ff6c2c7cdb6ae04e7e9592012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0ce8030000000000000151e9030000000000000151ea030000000000000151eb030000000000000151ec030000000000000151ed030000000000000151ee030000000000000151ef030000000000000151f0030000000000000151f1030000000000000151f2030000000000000151f30300000000000001510248304502210082219a54f61bf126bfc3fa068c6e33831222d1d7138c6faa9d33ca87fd4202d6022063f9902519624254d7c2c8ea7ba2d66ae975e4e229ae38043973ec707d5d4a83012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7102473044022017fb58502475848c1b09f162cb1688d0920ff7f142bed0ef904da2ccc88b168f02201798afa61850c65e77889cbcd648a5703b487895517c88f85cdd18b021ee246a012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000000247304402202830b7926e488da75782c81a54cd281720890d1af064629ebf2e31bf9f5435f30220089afaa8b455bbeb7d9b9c3fe1ed37d07685ade8455c76472cda424d93e4074a012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7102473044022026326fcdae9207b596c2b05921dbac11d81040c4d40378513670f19d9f4af893022034ecd7a282c0163b89aaa62c22ec202cef4736c58cd251649bad0d8139bcbf55012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71024730440220214978daeb2f38cd426ee6e2f44131a33d6b191af1c216247f1dd7d74c16d84a02205fdc05529b0bc0c430b4d5987264d9d075351c4f4484c16e91662e90a72aab24012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710247304402204a6e9f199dc9672cf2ff8094aaa784363be1eb62b679f7ff2df361124f1dca3302205eeb11f70fab5355c9c8ad1a0700ea355d315e334822fa182227e9815308ee8f012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"]
|
||||
|[ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000]],
|
||||
| "010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS"]
|
||||
|]
|
||||
""".stripMargin*/
|
||||
val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
|
||||
|
@ -102,7 +91,7 @@ class TransactionTest extends FlatSpec with MustMatchers with BitcoinSLogger {
|
|||
"OutPoint txId not the same as input prevout txid\noutPoint.txId: " + outPoint.txId + "\n" +
|
||||
"input prevout txid: " + input.previousOutput.txId)
|
||||
val program = amountOpt match {
|
||||
case Some(amount) => ScriptProgram(tx.asInstanceOf[WitnessTransaction],scriptPubKey,UInt32(inputIndex),testCase.flags,amount)
|
||||
case Some(amount) => ScriptProgram(tx,scriptPubKey,UInt32(inputIndex),testCase.flags,amount)
|
||||
case None => ScriptProgram(tx,scriptPubKey,UInt32(inputIndex),testCase.flags)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue