mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-24 23:08:31 +01:00
first test in sighash.json working, but need to fix TransactionSignatureChecker
This commit is contained in:
parent
f0e9534657
commit
7c2ac02b81
17 changed files with 134 additions and 65 deletions
|
@ -41,7 +41,7 @@ trait TransactionSignatureChecker extends BitcoinSLogger {
|
|||
logger.error("Signature did not have a low s value")
|
||||
ScriptValidationFailureHighSValue
|
||||
} else if (ScriptFlagUtil.requireStrictEncoding(flags) && signature.bytes.size > 0 &&
|
||||
!HashTypeFactory.hashTypes.find(_.byte == signature.bytes.last).isDefined) {
|
||||
!HashTypeFactory.hashTypes.find(_.hashType == signature.bytes.last).isDefined) {
|
||||
logger.error("Hash type was not defined on the signature")
|
||||
ScriptValidationFailureHashType
|
||||
} else if (!pubKeyEncodedCorrectly) {
|
||||
|
@ -69,7 +69,10 @@ trait TransactionSignatureChecker extends BitcoinSLogger {
|
|||
sigsRemoved
|
||||
}
|
||||
val hashTypeByte = if (signature.bytes.nonEmpty) signature.bytes.last else 0x00.toByte
|
||||
val hashType = HashTypeFactory.fromByte(hashTypeByte)
|
||||
//val hashTypeNum = BigInt(signature.bytes.reverse.take(4).toArray)
|
||||
val hashType : HashType = HashTypeFactory.fromBytes(Seq(hashTypeByte))
|
||||
println("hashtypebyte: " + hashTypeByte)
|
||||
println("hashtype: " + hashType)
|
||||
val hashForSignature = TransactionSignatureSerializer.hashForSignature(txSignatureComponent.transaction,
|
||||
txSignatureComponent.inputIndex,
|
||||
sigsRemovedScript, hashType)
|
||||
|
|
|
@ -80,9 +80,12 @@ trait TransactionSignatureSerializer extends RawBitcoinSerializerHelper with Bit
|
|||
}
|
||||
|
||||
val txWithInputSigsRemoved = Transaction(spendingTransaction,UpdateTransactionInputs(updatedInputs))
|
||||
|
||||
println("txWithInputSigsRemoved: " + txWithInputSigsRemoved)
|
||||
//just need to add the hash type and hash the tx
|
||||
val sigHashBytes : List[Byte] = List(0x00.toByte, 0x00.toByte, 0x00.toByte, hashType.byte).reverse
|
||||
//val sigHashBytes : List[Byte] = List(0x00.toByte, 0x00.toByte, 0x00.toByte, hashType.byte)
|
||||
val sigHashHex = BitcoinSUtil.flipEndianess(hashType.hex) //flipEnd(encodeHex(BigInt(num)))
|
||||
val sigHashBytes : List[Byte] = BitcoinSUtil.decodeHex(sigHashHex).toList
|
||||
//val hashTypeByte : HashType = HashTypeFactory.fromBigInt(hashTypeNum)
|
||||
|
||||
//check the hash type
|
||||
hashType match {
|
||||
|
|
|
@ -133,6 +133,8 @@ sealed trait UInt64 extends UnsignedNumber with NumberOperations[UInt64] {
|
|||
|
||||
override def <= (num : UInt64): Boolean = underlying <= num.underlying
|
||||
|
||||
def | (num : UInt64) : UInt64 = UInt64(underlying | num.underlying)
|
||||
|
||||
override def toInt = {
|
||||
require(underlying <= Int.MaxValue, "Overflow error when casting " + this + " to an integer.")
|
||||
require(underlying >= 0, "Unsigned integer should not be cast to a number less than 0" + this)
|
||||
|
@ -200,9 +202,11 @@ sealed trait Int32 extends SignedNumber with NumberOperations[Int32] {
|
|||
|
||||
override def <= (num : Int32): Boolean = underlying <= num.underlying
|
||||
|
||||
def | (num : Int32) : Int32 = Int32(underlying | num.underlying)
|
||||
|
||||
override def toInt = {
|
||||
require(underlying <= Int.MaxValue, "Overflow error when casting " + this + " to an integer.")
|
||||
require(underlying >= Int.MinValue, "Overfolow error when casting " + this + " to an integer.")
|
||||
require(underlying >= Int.MinValue, "Overflow error when casting " + this + " to an integer.")
|
||||
underlying
|
||||
}
|
||||
|
||||
|
@ -250,6 +254,8 @@ sealed trait Int64 extends SignedNumber with NumberOperations[Int64] {
|
|||
|
||||
override def <= (num : Int64): Boolean = underlying <= num.underlying
|
||||
|
||||
def | (num : Int64) : Int64 = Int64(underlying | num.underlying)
|
||||
|
||||
override def toInt = {
|
||||
require(underlying <= Int.MaxValue, "Overflow error when casting " + this + " to an integer.")
|
||||
require(underlying >= Int.MinValue, "Overflow error when casting " + this + " to an integer.")
|
||||
|
|
|
@ -45,10 +45,10 @@ sealed trait ScriptSignature extends NetworkElement with BitcoinSLogger {
|
|||
* @param digitalSignature
|
||||
* @return
|
||||
*/
|
||||
def hashType(digitalSignature: ECDigitalSignature) = {
|
||||
def hashType(digitalSignature: ECDigitalSignature) : HashType = {
|
||||
digitalSignature match {
|
||||
case EmptyDigitalSignature => SIGHASH_ALL()
|
||||
case sig : ECDigitalSignature => HashTypeFactory.fromByte(digitalSignature.bytes.last)
|
||||
case sig : ECDigitalSignature => HashTypeFactory.fromBytes(Seq(digitalSignature.bytes.last))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ trait P2PKHScriptSignature extends ScriptSignature {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
def hashType : HashType = HashTypeFactory.fromByte(signature.bytes.last)
|
||||
def hashType : HashType = HashTypeFactory.fromBytes(Seq(signature.bytes.last))
|
||||
|
||||
override def signatures : Seq[ECDigitalSignature] = {
|
||||
Seq(ECDigitalSignature(asm(1).hex))
|
||||
|
@ -252,7 +252,7 @@ trait P2PKScriptSignature extends ScriptSignature {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
def hashType = HashTypeFactory.fromByte(signature.bytes.last)
|
||||
def hashType : HashType = HashTypeFactory.fromBytes(Seq(signature.bytes.last))
|
||||
|
||||
/**
|
||||
* PubKey scriptSignatures only have one signature
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
package org.bitcoins.core.script.crypto
|
||||
|
||||
import org.bitcoins.core.number.Int32
|
||||
import org.bitcoins.core.util.{BitcoinSUtil}
|
||||
|
||||
/**
|
||||
* Created by chris on 1/18/16.
|
||||
*/
|
||||
sealed trait HashType {
|
||||
def byte : Byte
|
||||
def hex : String = BitcoinSUtil.encodeHex(byte)
|
||||
def hashType : Int32
|
||||
def hex : String = hashType.hex
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,32 +17,32 @@ sealed trait HashType {
|
|||
* Therefore SIGHASH_ALL could be represented by the byte 0x05 since 0x05 does not match
|
||||
* any of the other hash types. The default byte for SIGHASH_ALL is 0x01
|
||||
*
|
||||
* @param byte
|
||||
* @param hashType
|
||||
*/
|
||||
case class SIGHASH_ALL(byte : Byte = 0x01.toByte) extends HashType
|
||||
case class SIGHASH_ALL(hashType: Int32 = Int32.one) extends HashType
|
||||
|
||||
case object SIGHASH_NONE extends HashType {
|
||||
override def byte = 0x02.toByte
|
||||
override def hashType = Int32(2)
|
||||
}
|
||||
|
||||
case object SIGHASH_SINGLE extends HashType {
|
||||
override def byte = 0x03.toByte
|
||||
override def hashType = Int32(3)
|
||||
}
|
||||
|
||||
case object SIGHASH_ANYONECANPAY extends HashType {
|
||||
override def byte = 0x80.toByte
|
||||
override def hashType = Int32(80)
|
||||
}
|
||||
|
||||
case object SIGHASH_ALL_ANYONECANPAY extends HashType {
|
||||
override def byte = (SIGHASH_ANYONECANPAY.byte | 0x01.toByte).toByte
|
||||
override def hashType = SIGHASH_ANYONECANPAY.hashType | Int32.one
|
||||
}
|
||||
|
||||
case object SIGHASH_NONE_ANYONECANPAY extends HashType {
|
||||
override def byte = (SIGHASH_ANYONECANPAY.byte | SIGHASH_NONE.byte).toByte
|
||||
override def hashType = SIGHASH_ANYONECANPAY.hashType | SIGHASH_NONE.hashType
|
||||
}
|
||||
|
||||
case object SIGHASH_SINGLE_ANYONECANPAY extends HashType {
|
||||
override def byte = (SIGHASH_ANYONECANPAY.byte | SIGHASH_SINGLE.byte).toByte
|
||||
override def hashType = SIGHASH_ANYONECANPAY.hashType | SIGHASH_SINGLE.hashType
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,4 +21,6 @@ class NetworkParametersTest extends FlatSpec with MustMatchers {
|
|||
it must "create the correct magic network bytes for regtest" in {
|
||||
BitcoinSUtil.encodeHex(RegTest.magicBytes) must be ("fabfb5da")
|
||||
}
|
||||
|
||||
it must ""
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
val sigBytes : Seq[Byte] = TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_ALL())
|
||||
val bitcoinjSerialization = BitcoinSUtil.encodeHex(
|
||||
BitcoinJSignatureSerialization.serializeForSignature(BitcoinJTestUtil.multiSigTransaction,0,
|
||||
BitcoinJTestUtil.multiSigScript.getProgram(),SIGHASH_ALL().byte)
|
||||
BitcoinJTestUtil.multiSigScript.getProgram(),0x01.toByte)
|
||||
)
|
||||
|
||||
BitcoinSUtil.encodeHex(sigBytes) must be (bitcoinjSerialization)
|
||||
|
@ -49,7 +49,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
|
||||
val bitcoinsTxSigHash = TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_ALL())
|
||||
val bitcoinjTxSigHash = BitcoinSUtil.encodeHex(
|
||||
BitcoinJSignatureSerialization.hashForSignature(BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram(),SIGHASH_ALL().byte)
|
||||
BitcoinJSignatureSerialization.hashForSignature(BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram(),0x01.toByte)
|
||||
)
|
||||
bitcoinsTxSigHash.hex must be (bitcoinjTxSigHash)
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_SINGLE)
|
||||
|
||||
val bitcoinjSigSerialization = BitcoinSUtil.encodeHex(BitcoinJSignatureSerialization.serializeForSignature(
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,SIGHASH_SINGLE.byte))
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,0x03.toByte))
|
||||
BitcoinSUtil.encodeHex(serialiazedTxForSig) must be (bitcoinjSigSerialization)
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_SINGLE)
|
||||
|
||||
val bitcoinjSigSerialization = BitcoinSUtil.encodeHex(BitcoinJSignatureSerialization.hashForSignature(
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,SIGHASH_SINGLE.byte))
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,0x03.toByte))
|
||||
hashedTxForSig.hex must be (bitcoinjSigSerialization)
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_NONE)
|
||||
|
||||
val bitcoinjSigSerialization = BitcoinSUtil.encodeHex(BitcoinJSignatureSerialization.serializeForSignature(
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,SIGHASH_NONE.byte))
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,0x02.toByte))
|
||||
BitcoinSUtil.encodeHex(serialiazedTxForSig) must be (bitcoinjSigSerialization)
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_NONE)
|
||||
|
||||
val bitcoinjSigSerialization = BitcoinSUtil.encodeHex(BitcoinJSignatureSerialization.hashForSignature(
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,SIGHASH_NONE.byte))
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,0x02.toByte))
|
||||
hashedTxForSig.hex must be (bitcoinjSigSerialization)
|
||||
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
val serializedTxForSig : Seq[Byte] =
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_ANYONECANPAY)
|
||||
val bitcoinjSigSerialization = BitcoinSUtil.encodeHex(BitcoinJSignatureSerialization.serializeForSignature(
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,SIGHASH_ANYONECANPAY.byte))
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,0x80.toByte))
|
||||
|
||||
BitcoinSUtil.encodeHex(serializedTxForSig) must be (bitcoinjSigSerialization)
|
||||
|
||||
|
@ -129,7 +129,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
val hashedTxForSig =
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_ANYONECANPAY)
|
||||
val bitcoinjSigSerialization = BitcoinSUtil.encodeHex(BitcoinJSignatureSerialization.hashForSignature(
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,SIGHASH_ANYONECANPAY.byte))
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,0x80.toByte))
|
||||
|
||||
hashedTxForSig.hex must be (bitcoinjSigSerialization)
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
val serializedTxForSig : Seq[Byte] =
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_ALL_ANYONECANPAY)
|
||||
val bitcoinjSigSerialization = BitcoinSUtil.encodeHex(BitcoinJSignatureSerialization.serializeForSignature(
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,SIGHASH_ALL_ANYONECANPAY.byte))
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,(0x80 | 0x01).toByte))
|
||||
|
||||
BitcoinSUtil.encodeHex(serializedTxForSig) must be (bitcoinjSigSerialization)
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
val serializedTxForSig : Seq[Byte] =
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_SINGLE_ANYONECANPAY)
|
||||
val bitcoinjSigSerialization = BitcoinSUtil.encodeHex(BitcoinJSignatureSerialization.serializeForSignature(
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,SIGHASH_SINGLE_ANYONECANPAY.byte))
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,(0x80 | 0x03).toByte))
|
||||
|
||||
BitcoinSUtil.encodeHex(serializedTxForSig) must be (bitcoinjSigSerialization)
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
val serializedTxForSig : Seq[Byte] =
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_NONE_ANYONECANPAY)
|
||||
val bitcoinjSigSerialization = BitcoinSUtil.encodeHex(BitcoinJSignatureSerialization.serializeForSignature(
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,SIGHASH_NONE_ANYONECANPAY.byte))
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,(0x80 | 0x02).toByte))
|
||||
|
||||
BitcoinSUtil.encodeHex(serializedTxForSig) must be (bitcoinjSigSerialization)
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
val hashedTxForSig =
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_ALL_ANYONECANPAY)
|
||||
val bitcoinjTxHashForSig = BitcoinSUtil.encodeHex(BitcoinJSignatureSerialization.hashForSignature(
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,SIGHASH_ALL_ANYONECANPAY.byte))
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,(0x80 | 0x01).toByte))
|
||||
|
||||
hashedTxForSig.hex must be (bitcoinjTxHashForSig)
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
val hashedTxForSig =
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_SINGLE_ANYONECANPAY)
|
||||
val bitcoinjTxHashForSig = BitcoinSUtil.encodeHex(BitcoinJSignatureSerialization.hashForSignature(
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,SIGHASH_SINGLE_ANYONECANPAY.byte))
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,(0x80 | 0x03).toByte))
|
||||
|
||||
hashedTxForSig.hex must be (bitcoinjTxHashForSig)
|
||||
}
|
||||
|
@ -207,13 +207,13 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
val hashedTxForSig =
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_NONE_ANYONECANPAY)
|
||||
val bitcoinjTxHashForSig = BitcoinSUtil.encodeHex(BitcoinJSignatureSerialization.hashForSignature(
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,SIGHASH_NONE_ANYONECANPAY.byte))
|
||||
BitcoinJTestUtil.multiSigTransaction,0,BitcoinJTestUtil.multiSigScript.getProgram,(0x80 | 0x02).toByte))
|
||||
|
||||
hashedTxForSig.hex must be (bitcoinjTxHashForSig)
|
||||
}
|
||||
|
||||
|
||||
it must "serialize a simple transaction with one p2pkh input for signing" in {
|
||||
/* it must "serialize a simple transaction with one p2pkh input for signing" in {
|
||||
val (spendingTx,spendingInput, inputIndex, creditingOutput) =
|
||||
TransactionTestUtil.transactionWithSpendingInputAndCreditingOutput
|
||||
|
||||
|
@ -233,15 +233,14 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
val signature : Array[Byte] = scriptSig.getChunks().get(0).data
|
||||
val bitcoinjSerializeForSig : Seq[Byte] =
|
||||
BitcoinJSignatureSerialization.serializeForSignature(bitcoinjTx,inputIndex.toInt,
|
||||
parentOutput.getScriptBytes, SIGHASH_ALL().byte)
|
||||
parentOutput.getScriptBytes, 0x01.toByte)
|
||||
|
||||
|
||||
val hashType = spendingInput.scriptSignature.hashType(spendingInput.scriptSignature.signatures.head)
|
||||
val serializedTxForSig : String = BitcoinSUtil.encodeHex(
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,inputIndex,creditingOutput.scriptPubKey.asm,hashType
|
||||
))
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,inputIndex,creditingOutput.scriptPubKey.asm,hashType))
|
||||
serializedTxForSig must be (BitcoinSUtil.encodeHex(bitcoinjSerializeForSig))
|
||||
}
|
||||
}*/
|
||||
|
||||
it must "hash a simple transaction with one input for signing" in {
|
||||
|
||||
|
@ -260,7 +259,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
|
||||
val bitcoinjSerializeForSig : Seq[Byte] =
|
||||
BitcoinJSignatureSerialization.serializeForSignature(bitcoinjTx,inputIndex.toInt,
|
||||
parentOutput.getScriptBytes, SIGHASH_ALL().byte)
|
||||
parentOutput.getScriptBytes, (0x01).toByte)
|
||||
|
||||
val hashType = spendingInput.scriptSignature.hashType(spendingInput.scriptSignature.signatures.head)
|
||||
val serializedTxForSig : String = BitcoinSUtil.encodeHex(
|
||||
|
@ -272,7 +271,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
}
|
||||
|
||||
|
||||
it must "serialize a transaction that has a p2sh input script" in {
|
||||
/* it must "serialize a transaction that has a p2sh input script" in {
|
||||
val (spendingTx,spendingInput,inputIndex,creditingOutput) =
|
||||
TransactionTestUtil.p2shTransactionWithSpendingInputAndCreditingOutput
|
||||
|
||||
|
@ -291,9 +290,9 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
hashedTxForSig must be (BitcoinSUtil.encodeHex(bitcoinjHashForSig))
|
||||
}
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
it must "hash a transaction that has p2sh input script" in {
|
||||
/* it must "hash a transaction that has p2sh input script" in {
|
||||
val (spendingTx,spendingInput,inputIndex,creditingOutput) =
|
||||
TransactionTestUtil.p2shTransactionWithSpendingInputAndCreditingOutput
|
||||
|
||||
|
@ -312,7 +311,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
}
|
||||
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
it must "hash a transaction that has script operations after OP_CHECKSIGVERIFY" in {
|
||||
|
@ -329,11 +328,11 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
|
||||
val bitcoinjTx = BitcoinjConversions.transaction(spendingTx)
|
||||
val bitcoinjHashForSig : Seq[Byte] = BitcoinJSignatureSerialization.hashForSignature(
|
||||
bitcoinjTx, inputIndex.toInt, scriptPubKey.bytes.toArray, SIGHASH_ALL(0x01).byte
|
||||
bitcoinjTx, inputIndex.toInt, scriptPubKey.bytes.toArray, 0x01.toByte
|
||||
)
|
||||
|
||||
val hashedTxForSig =
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,inputIndex,scriptPubKey.asm,SIGHASH_ALL(0x01))
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,inputIndex,scriptPubKey.asm,SIGHASH_ALL())
|
||||
hashedTxForSig.hex must be (BitcoinSUtil.encodeHex(bitcoinjHashForSig))
|
||||
|
||||
}
|
||||
|
@ -350,7 +349,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
val scriptPubKey = ScriptPubKey.fromAsm(scriptPubKeyFromString)
|
||||
|
||||
val serializedTxForSig : String = BitcoinSUtil.encodeHex(
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,inputIndex,scriptPubKey.asm, SIGHASH_ALL(0x01)
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,inputIndex,scriptPubKey.asm, SIGHASH_ALL()
|
||||
))
|
||||
|
||||
//serialization is from bitcoin core
|
||||
|
@ -369,7 +368,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
|
||||
val bitcoinjTx = BitcoinjConversions.transaction(spendingTx)
|
||||
val bitcoinjHashForSig : Seq[Byte] = BitcoinJSignatureSerialization.hashForSignature(
|
||||
bitcoinjTx, inputIndex.toInt, scriptPubKey.bytes.toArray, SIGHASH_ALL_ANYONECANPAY.byte
|
||||
bitcoinjTx, inputIndex.toInt, scriptPubKey.bytes.toArray, (0x80 | 0x01).toByte
|
||||
)
|
||||
val hashedTxForSig =
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,inputIndex,scriptPubKey.asm,SIGHASH_ALL_ANYONECANPAY)
|
||||
|
@ -420,7 +419,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
val scriptPubKeyFromString = ScriptParser.fromString("0x4c 0xae 0x606563686f2022553246736447566b58312b5a536e587574356542793066794778625456415675534a6c376a6a334878416945325364667657734f53474f36633338584d7439435c6e543249584967306a486956304f376e775236644546673d3d22203e20743b206f70656e73736c20656e63202d7061737320706173733a5b314a564d7751432d707269766b65792d6865785d202d64202d6165732d3235362d636263202d61202d696e207460 DROP DUP HASH160 0x14 0xbfd7436b6265aa9de506f8a994f881ff08cc2872 EQUALVERIFY CHECKSIG")
|
||||
val scriptPubKey = ScriptPubKey.fromAsm(scriptPubKeyFromString)
|
||||
val serializedTxForSig : String = BitcoinSUtil.encodeHex(
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,inputIndex,scriptPubKey.asm,SIGHASH_ALL(1.toByte)))
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,inputIndex,scriptPubKey.asm,SIGHASH_ALL()))
|
||||
//serialization is from bitcoin core
|
||||
serializedTxForSig must be ("0100000001482f7a028730a233ac9b48411a8edfb107b749e61faf7531f4257ad95d0a51c500000000ca4cae606563686f2022553246736447566b58312b5a536e587574356542793066794778625456415675534a6c376a6a334878416945325364667657734f53474f36633338584d7439435c6e543249584967306a486956304f376e775236644546673d3d22203e20743b206f70656e73736c20656e63202d7061737320706173733a5b314a564d7751432d707269766b65792d6865785d202d64202d6165732d3235362d636263202d61202d696e2074607576a914bfd7436b6265aa9de506f8a994f881ff08cc287288acffffffff0180969800000000001976a914e336d0017a9d28de99d16472f6ca6d5a3a8ebc9988ac0000000001000000")
|
||||
}
|
||||
|
@ -435,7 +434,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
val scriptPubKey = ScriptPubKey.fromAsm(scriptPubKeyFromString)
|
||||
|
||||
val serializedTxForSig : String = BitcoinSUtil.encodeHex(
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,inputIndex,scriptPubKey.asm,SIGHASH_ALL(1.toByte)))
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,inputIndex,scriptPubKey.asm,SIGHASH_ALL()))
|
||||
serializedTxForSig must be ("01000000020001000000000000000000000000000000000000000000000000000000000000000000002321035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efcac01000000000200000000000000000000000000000000000000000000000000000000000000000000000100000001010000000000000001510000000001000000")
|
||||
|
||||
}
|
||||
|
|
|
@ -77,4 +77,8 @@ class Int32Spec extends Properties("Int32Spec") {
|
|||
else num1 != num2
|
||||
}
|
||||
|
||||
property("|") =
|
||||
Prop.forAll(NumberGenerator.int32s, NumberGenerator.int32s) { (num1: Int32, num2: Int32) =>
|
||||
Int32(num1.underlying | num2.underlying) == (num1 | num2)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,4 +63,13 @@ class Int32Test extends FlatSpec with MustMatchers {
|
|||
it must "have the correct maximum number representation" in {
|
||||
Int32.max.underlying must be (2147483647)
|
||||
}
|
||||
|
||||
it must "intercept illegal argument exceptions when casting integer below minimum and above maximum values" in {
|
||||
intercept[IllegalArgumentException] {
|
||||
Int32(Int.MaxValue + 1)
|
||||
}
|
||||
intercept[IllegalArgumentException] {
|
||||
Int32(Int.MinValue - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,9 +72,14 @@ class Int64Spec extends Properties("Int64Spec") {
|
|||
}
|
||||
|
||||
property("== & !=") =
|
||||
Prop.forAll(NumberGenerator.int32s, NumberGenerator.int32s) { (num1 : Int32, num2 : Int32) =>
|
||||
Prop.forAll(NumberGenerator.int64s, NumberGenerator.int64s) { (num1 : Int64, num2 : Int64) =>
|
||||
if (num1.underlying == num2.underlying) num1 == num2
|
||||
else num1 != num2
|
||||
}
|
||||
|
||||
property("|") =
|
||||
Prop.forAll(NumberGenerator.int64s, NumberGenerator.int64s) { (num1: Int64, num2: Int64) =>
|
||||
Int64(num1.underlying | num2.underlying) == (num1 | num2)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,4 +77,6 @@ class Int64Test extends FlatSpec with MustMatchers {
|
|||
it must "have the correct number representation for the maximum number that can be stored in a Int64" in {
|
||||
Int64.max.underlying must be (9223372036854775807L)
|
||||
}
|
||||
|
||||
it must ""
|
||||
}
|
||||
|
|
|
@ -92,6 +92,9 @@ class UInt32Spec extends Properties("UInt32") with BitcoinSLogger {
|
|||
UInt32(num1.underlying | num2.underlying) == (num1 | num2)
|
||||
}
|
||||
|
||||
|
||||
property("|") =
|
||||
Prop.forAll(NumberGenerator.uInt32s, NumberGenerator.uInt32s) { (num1: UInt32, num2: UInt32) =>
|
||||
UInt32(num1.underlying | num2.underlying) == (num1 | num2)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -81,4 +81,9 @@ class UInt64Spec extends Properties("UInt64Spec") with BitcoinSLogger {
|
|||
if (num1.underlying == num2.underlying) num1 == num2
|
||||
else num1 != num2
|
||||
}
|
||||
|
||||
property("|") =
|
||||
Prop.forAll(NumberGenerator.uInt64s, NumberGenerator.uInt64s) { (num1: UInt64, num2: UInt64) =>
|
||||
UInt64(num1.underlying | num2.underlying) == (num1 | num2)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ class P2PKHScriptSignatureTest extends FlatSpec with MustMatchers {
|
|||
case s : P2PKHScriptSignature => s
|
||||
case _ => throw new RuntimeException("Must be p2pkh scriptSig")
|
||||
}
|
||||
p2pkhScriptSig.hashType must be (SIGHASH_ALL(1))
|
||||
p2pkhScriptSig.hashType must be (SIGHASH_ALL())
|
||||
}
|
||||
|
||||
it must "be able to identify the signature in a p2pkh scriptSig" in {
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
package org.bitcoins.core.protocol.script
|
||||
|
||||
|
||||
import org.bitcoins.core.crypto.{ECDigitalSignature}
|
||||
import org.bitcoins.core.crypto.{TransactionSignatureSerializer, ECDigitalSignature}
|
||||
import org.bitcoins.core.number.{Int32, UInt32}
|
||||
import org.bitcoins.core.protocol.transaction.Transaction
|
||||
import org.bitcoins.core.serializers.script.RawScriptSignatureParser
|
||||
import org.bitcoins.core.script.constant._
|
||||
import org.bitcoins.core.script.crypto.{SIGHASH_ALL, SIGHASH_SINGLE}
|
||||
import org.bitcoins.core.util.{BitcoinScriptUtil, TestUtil, TransactionTestUtil}
|
||||
import org.bitcoins.core.script.crypto.{HashTypeFactory, SIGHASH_ALL, SIGHASH_SINGLE}
|
||||
import org.bitcoins.core.util.{BitcoinSUtil, BitcoinScriptUtil, TestUtil, TransactionTestUtil}
|
||||
import org.scalatest.{FlatSpec, MustMatchers}
|
||||
import spray.json._
|
||||
|
||||
import scala.io.Source
|
||||
|
||||
/**
|
||||
* Created by chris on 2/17/16.
|
||||
|
@ -61,7 +66,7 @@ class ScriptSignatureTest extends FlatSpec with MustMatchers {
|
|||
//from this tx https://btc.blockr.io/api/v1/tx/raw/c99c49da4c38af669dea436d3e73780dfdb6c1ecf9958baa52960e8baee30e73
|
||||
val hex = "493046022100d23459d03ed7e9511a47d13292d3430a04627de6235b6e51a40f9cd386f2abe3022100e7d25b080f0bb8d8d5f878bba7d54ad2fda650ea8d158a33ee3cbd11768191fd004104b0e2c879e4daf7b9ab68350228c159766676a14f5815084ba166432aab46198d4cca98fa3e9981d0a90b2effc514b76279476550ba3663fdcaff94c38420e9d5"
|
||||
val scriptSig : ScriptSignature = RawScriptSignatureParser.read(hex)
|
||||
scriptSig.hashType(scriptSig.signatures.head) must be (SIGHASH_ALL(0))
|
||||
scriptSig.hashType(scriptSig.signatures.head) must be (SIGHASH_ALL(Int32.zero))
|
||||
}
|
||||
|
||||
it must "have an empty script signature" in {
|
||||
|
@ -88,4 +93,26 @@ class ScriptSignatureTest extends FlatSpec with MustMatchers {
|
|||
scriptSig.isInstanceOf[P2PKScriptSignature] must be (true)
|
||||
scriptSig.hex must be (TestUtil.p2pkScriptSig.hex)
|
||||
}
|
||||
|
||||
it must "read sighash.json and return result" in {
|
||||
//["raw_transaction, script, input_index, hashType, signature_hash (result)"],
|
||||
/* val str =
|
||||
"""
|
||||
| ["907c2bc503ade11cc3b04eb2918b6f547b0630ab569273824748c87ea14b0696526c66ba740200000004ab65ababfd1f9bdd4ef073c7afc4ae00da8a66f429c917a0081ad1e1dabce28d373eab81d8628de802000000096aab5253ab52000052ad042b5f25efb33beec9f3364e8a9139e8439d9d7e26529c3c30b6c3fd89f8684cfd68ea0200000009ab53526500636a52ab599ac2fe02a526ed040000000008535300516352515164370e010000000003006300ab2ec229", "", 2, 1864164639, "31af167a6cf3f9d5f6875caa4d31704ceb0eba078d132b78dab52c3b8997317e"],
|
||||
|
|
||||
""".stripMargin
|
||||
val json = str.parseJson*/
|
||||
|
||||
/* val source = Source.fromURL(getClass.getResource("/sighash.json"))
|
||||
val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
|
||||
val json = lines.parseJson*/
|
||||
|
||||
//TODO: MAKE SERIALIZER FOR JSON FILE TO READ/WRITE TESTS
|
||||
|
||||
val tx = Transaction("907c2bc503ade11cc3b04eb2918b6f547b0630ab569273824748c87ea14b0696526c66ba740200000004ab65ababfd1f9bdd4ef073c7afc4ae00da8a66f429c917a0081ad1e1dabce28d373eab81d8628de802000000096aab5253ab52000052ad042b5f25efb33beec9f3364e8a9139e8439d9d7e26529c3c30b6c3fd89f8684cfd68ea0200000009ab53526500636a52ab599ac2fe02a526ed040000000008535300516352515164370e010000000003006300ab2ec229")
|
||||
val input = tx.inputs(2)
|
||||
val serializedTxForSigning = TransactionSignatureSerializer.hashForSignature(tx, UInt32(2), Seq(), HashTypeFactory.fromBytes(Int32(1864164639).bytes))
|
||||
serializedTxForSigning.hex must be (BitcoinSUtil.flipEndianess("31af167a6cf3f9d5f6875caa4d31704ceb0eba078d132b78dab52c3b8997317e"))
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,16 +62,16 @@ class TransactionTest extends FlatSpec with MustMatchers with BitcoinSLogger {
|
|||
|
||||
|
||||
//use this to represent a single test case from script_valid.json
|
||||
/* val lines =
|
||||
val lines =
|
||||
"""
|
||||
|[
|
||||
|[[["ceafe58e0f6e7d67c0409fbbf673c84c166e3c5d3c24af58f7175b18df3bb3db", 0, "DUP HASH160 0x14 0xf6f365c40f0739b61de827a44751e5e99032ed8f EQUALVERIFY CHECKSIG"],
|
||||
| ["ceafe58e0f6e7d67c0409fbbf673c84c166e3c5d3c24af58f7175b18df3bb3db", 1, "2 0x48 0x3045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 3 CHECKMULTISIG"]],
|
||||
|"0100000002dbb33bdf185b17f758af243c5d3c6e164cc873f6bb9f40c0677d6e0f8ee5afce000000006b4830450221009627444320dc5ef8d7f68f35010b4c050a6ed0d96b67a84db99fda9c9de58b1e02203e4b4aaa019e012e65d69b487fdf8719df72f488fa91506a80c49a33929f1fd50121022b78b756e2258af13779c1a1f37ea6800259716ca4b7f0b87610e0bf3ab52a01ffffffffdbb33bdf185b17f758af243c5d3c6e164cc873f6bb9f40c0677d6e0f8ee5afce010000009300483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303ffffffff01a0860100000000001976a9149bc0bbdd3024da4d0c38ed1aecf5c68dd1d3fa1288ac00000000", "P2SH"]
|
||||
|[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x21 0x035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efc CHECKSIG"],
|
||||
| ["0000000000000000000000000000000000000000000000000000000000000200", 0, "0x21 0x035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efc CHECKSIG"]],
|
||||
| "010000000200010000000000000000000000000000000000000000000000000000000000000000000049483045022100d180fd2eb9140aeb4210c9204d3f358766eb53842b2a9473db687fa24b12a3cc022079781799cd4f038b85135bbe49ec2b57f306b2bb17101b17f71f000fcab2b6fb01ffffffff0002000000000000000000000000000000000000000000000000000000000000000000004847304402205f7530653eea9b38699e476320ab135b74771e1c48b81a5d041e2ca84b9be7a802200ac8d1f40fb026674fe5a5edd3dea715c27baa9baca51ed45ea750ac9dc0a55e81ffffffff010100000000000000015100000000", "P2SH"]
|
||||
|
|
||||
|]
|
||||
""".stripMargin*/
|
||||
val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
|
||||
""".stripMargin
|
||||
//val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
|
||||
val json = lines.parseJson
|
||||
val testCasesOpt : Seq[Option[CoreTransactionTestCase]] = json.convertTo[Seq[Option[CoreTransactionTestCase]]]
|
||||
val testCases : Seq[CoreTransactionTestCase] = testCasesOpt.flatten
|
||||
|
|
|
@ -8,8 +8,8 @@ import org.scalatest.{FlatSpec, MustMatchers}
|
|||
class HashTypeTest extends FlatSpec with MustMatchers {
|
||||
|
||||
"HashType" must "combine hash types with SIGHASH_ANYONCANPAY" in {
|
||||
SIGHASH_ALL_ANYONECANPAY.byte must be (0x81.toByte)
|
||||
SIGHASH_NONE_ANYONECANPAY.byte must be (0x82.toByte)
|
||||
SIGHASH_SINGLE_ANYONECANPAY.byte must be (0x83.toByte)
|
||||
SIGHASH_ALL_ANYONECANPAY.hashType.bytes.head must be (0x81.toByte)
|
||||
SIGHASH_NONE_ANYONECANPAY.hashType.bytes.head must be (0x82.toByte)
|
||||
SIGHASH_SINGLE_ANYONECANPAY.hashType.bytes.head must be (0x83.toByte)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue