mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-24 23:08:31 +01:00
merge sighash_json branch into master
This commit is contained in:
commit
78c86c5fd7
20 changed files with 367 additions and 121 deletions
|
@ -1,6 +1,7 @@
|
|||
package org.bitcoins.core.crypto
|
||||
|
||||
import org.bitcoins.core.config.TestNet3
|
||||
import org.bitcoins.core.number.Int32
|
||||
import org.bitcoins.core.protocol.script._
|
||||
import org.bitcoins.core.protocol.transaction.{Transaction, TransactionInput}
|
||||
import org.bitcoins.core.script.ScriptProgram
|
||||
|
@ -23,6 +24,7 @@ trait TransactionSignatureChecker extends BitcoinSLogger {
|
|||
* Checks the signature of a scriptSig in the spending transaction against the
|
||||
* given scriptPubKey & explicitly given public key
|
||||
* This is useful for instances of non standard scriptSigs
|
||||
*
|
||||
* @param txSignatureComponent the relevant transaction information for signature checking
|
||||
* @param script the current script state inside the interpreter - this is needed in the case of OP_CODESEPARATORS
|
||||
* @param pubKey the public key the signature is being checked against
|
||||
|
@ -40,8 +42,9 @@ trait TransactionSignatureChecker extends BitcoinSLogger {
|
|||
} else if (ScriptFlagUtil.requireLowSValue(flags) && !DERSignatureUtil.isLowDerSignature(signature)) {
|
||||
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) {
|
||||
} else if (ScriptFlagUtil.requireStrictEncoding(flags) && signature.bytes.nonEmpty &&
|
||||
!HashTypeOperations.hashTypes.contains(HashTypeOperations.fromNumber(Int32(signature.bytes.last)))) {
|
||||
logger.error("signature: " + signature.bytes)
|
||||
logger.error("Hash type was not defined on the signature")
|
||||
ScriptValidationFailureHashType
|
||||
} else if (!pubKeyEncodedCorrectly) {
|
||||
|
@ -76,7 +79,7 @@ trait TransactionSignatureChecker extends BitcoinSLogger {
|
|||
sigsRemoved
|
||||
}
|
||||
val hashTypeByte = if (signature.bytes.nonEmpty) signature.bytes.last else 0x00.toByte
|
||||
val hashType = HashTypeFactory.fromByte(hashTypeByte)
|
||||
val hashType = HashTypeOperations.fromBytes(Seq(0.toByte, 0.toByte, 0.toByte, hashTypeByte))
|
||||
val hashForSignature = TransactionSignatureSerializer.hashForSignature(txSignatureComponent.transaction,
|
||||
txSignatureComponent.inputIndex,
|
||||
sigsRemovedScript, hashType)
|
||||
|
@ -90,6 +93,7 @@ trait TransactionSignatureChecker extends BitcoinSLogger {
|
|||
* This is a helper function to check digital signatures against public keys
|
||||
* if the signature does not match this public key, check it against the next
|
||||
* public key in the sequence
|
||||
*
|
||||
* @param txSignatureComponent the tx signature component that contains all relevant transaction information
|
||||
* @param script the script state this is needed in case there is an OP_CODESEPARATOR inside the script
|
||||
* @param sigs the signatures that are being checked for validity
|
||||
|
@ -116,7 +120,7 @@ trait TransactionSignatureChecker extends BitcoinSLogger {
|
|||
logger.info("We do not have enough sigs to meet the threshold of requireSigs in the multiSignatureScriptPubKey")
|
||||
SignatureValidationFailureSignatureCount
|
||||
}
|
||||
else if (!sigs.isEmpty && !pubKeys.isEmpty) {
|
||||
else if (sigs.nonEmpty && pubKeys.nonEmpty) {
|
||||
val sig = sigs.head
|
||||
val pubKey = pubKeys.head
|
||||
val result = checkSignature(txSignatureComponent,script,pubKey,sig,flags)
|
||||
|
@ -144,6 +148,7 @@ trait TransactionSignatureChecker extends BitcoinSLogger {
|
|||
|
||||
/**
|
||||
* Removes the given digital signature from the list of script tokens if it exists
|
||||
*
|
||||
* @param signature
|
||||
* @param script
|
||||
* @return
|
||||
|
@ -161,6 +166,7 @@ trait TransactionSignatureChecker extends BitcoinSLogger {
|
|||
|
||||
/**
|
||||
* Removes the list of digital signatures from the list of script tokens
|
||||
*
|
||||
* @param sigs
|
||||
* @param script
|
||||
* @return
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.bitcoins.core.crypto
|
||||
|
||||
import org.bitcoins.core.protocol.script.ScriptPubKey
|
||||
import org.bitcoins.core.script.crypto.HashType
|
||||
import org.bitcoins.core.script.crypto.{HashTypeOperations, HashType}
|
||||
|
||||
/**
|
||||
* Created by chris on 7/21/16.
|
||||
|
@ -10,6 +10,7 @@ trait TransactionSignatureCreator {
|
|||
|
||||
/**
|
||||
* Creates a signature from a tx signature component
|
||||
*
|
||||
* @param txSignatureComponent contains the tx, inputIndex which specify which input we are creating a sig for
|
||||
* @param privateKey the private key which we are signing the hash with
|
||||
* @param hashType the procedure to use for hashing to transaction
|
||||
|
@ -19,7 +20,7 @@ trait TransactionSignatureCreator {
|
|||
val hash = TransactionSignatureSerializer.hashForSignature(txSignatureComponent, hashType)
|
||||
val signature = privateKey.sign(hash)
|
||||
//append 1 byte hash type onto the end
|
||||
ECDigitalSignature(signature.bytes ++ Seq(hashType.byte))
|
||||
ECDigitalSignature(signature.bytes ++ Seq(HashTypeOperations.byte(hashType)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.bitcoins.core.crypto
|
||||
|
||||
import org.bitcoins.core.currency.CurrencyUnits
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.number.{Int32, UInt32}
|
||||
import org.bitcoins.core.serializers.RawBitcoinSerializerHelper
|
||||
import org.bitcoins.core.serializers.transaction.RawTransactionOutputParser
|
||||
import org.bitcoins.core.protocol.script._
|
||||
|
@ -74,22 +74,21 @@ trait TransactionSignatureSerializer extends RawBitcoinSerializerHelper with Bit
|
|||
val updatedInputs = for {
|
||||
(input,index) <- inputSigsRemoved.zipWithIndex
|
||||
} yield {
|
||||
if (UInt32(index) == inputIndex) inputWithConnectedScript
|
||||
if (UInt32(index) == inputIndex) {
|
||||
inputWithConnectedScript
|
||||
}
|
||||
else input
|
||||
}
|
||||
|
||||
val txWithInputSigsRemoved = Transaction(spendingTransaction,UpdateTransactionInputs(updatedInputs))
|
||||
|
||||
//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] = hashType.num.bytes.reverse.toList
|
||||
//check the hash type
|
||||
hashType match {
|
||||
case SIGHASH_NONE =>
|
||||
case _ : SIGHASH_NONE =>
|
||||
val sigHashNoneTx : Transaction = sigHashNone(txWithInputSigsRemoved,inputIndex)
|
||||
sigHashNoneTx.bytes ++ sigHashBytes
|
||||
|
||||
case SIGHASH_SINGLE =>
|
||||
case _ : SIGHASH_SINGLE =>
|
||||
if (inputIndex >= UInt32(spendingTransaction.outputs.size)) {
|
||||
// comment copied from bitcoinj
|
||||
// The input index is beyond the number of outputs, it's a buggy signature made by a broken
|
||||
|
@ -106,25 +105,25 @@ trait TransactionSignatureSerializer extends RawBitcoinSerializerHelper with Bit
|
|||
sigHashSingleTx.bytes ++ sigHashBytes
|
||||
}
|
||||
|
||||
case hash : SIGHASH_ALL =>
|
||||
case _ : SIGHASH_ALL =>
|
||||
val sigHashAllTx : Transaction = sigHashAll(txWithInputSigsRemoved,inputIndex)
|
||||
sigHashAllTx.bytes ++ sigHashBytes
|
||||
|
||||
case SIGHASH_ANYONECANPAY =>
|
||||
case _ : SIGHASH_ANYONECANPAY =>
|
||||
val txWithInputsRemoved = sigHashAnyoneCanPay(txWithInputSigsRemoved,inputWithConnectedScript)
|
||||
txWithInputsRemoved.bytes ++ sigHashBytes
|
||||
|
||||
case SIGHASH_ALL_ANYONECANPAY =>
|
||||
case _ : SIGHASH_ALL_ANYONECANPAY =>
|
||||
val sigHashAllTx = sigHashAll(txWithInputSigsRemoved,inputIndex)
|
||||
val sigHashAllAnyoneCanPayTx = sigHashAnyoneCanPay(sigHashAllTx,inputWithConnectedScript)
|
||||
sigHashAllAnyoneCanPayTx.bytes ++ sigHashBytes
|
||||
|
||||
case SIGHASH_NONE_ANYONECANPAY =>
|
||||
case _ : SIGHASH_NONE_ANYONECANPAY =>
|
||||
val sigHashNoneTx = sigHashNone(txWithInputSigsRemoved,inputIndex)
|
||||
val sigHashNoneAnyoneCanPay = sigHashAnyoneCanPay(sigHashNoneTx,inputWithConnectedScript)
|
||||
sigHashNoneAnyoneCanPay.bytes ++ sigHashBytes
|
||||
|
||||
case SIGHASH_SINGLE_ANYONECANPAY =>
|
||||
case _ : SIGHASH_SINGLE_ANYONECANPAY =>
|
||||
val sigHashSingleTx = sigHashSingle(txWithInputSigsRemoved,inputIndex)
|
||||
val sigHashSingleAnyoneCanPay = sigHashAnyoneCanPay(sigHashSingleTx,inputWithConnectedScript)
|
||||
sigHashSingleAnyoneCanPay.bytes ++ sigHashBytes
|
||||
|
@ -148,13 +147,13 @@ trait TransactionSignatureSerializer extends RawBitcoinSerializerHelper with Bit
|
|||
if (inputIndex >= UInt32(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 >= UInt32(spendingTransaction.outputs.size)) {
|
||||
} else if(HashTypeOperations.isSIGHASH_SINGLE(hashType.num) && inputIndex >= UInt32(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)
|
||||
logger.debug("Serialized tx for signature: " + BitcoinSUtil.encodeHex(serializedTxForSignature))
|
||||
logger.debug("HashType: " + hashType)
|
||||
logger.debug("HashType: " + hashType.num)
|
||||
CryptoUtil.doubleSHA256(serializedTxForSignature)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,6 +80,8 @@ sealed trait UInt32 extends UnsignedNumber with NumberOperations[UInt32] {
|
|||
|
||||
def | (num : UInt32) : UInt32 = UInt32(underlying | num.underlying)
|
||||
|
||||
def & (num : UInt32) : UInt32 = UInt32(underlying & num.underlying)
|
||||
|
||||
override def hex = BitcoinSUtil.encodeHex(underlying).slice(8,16)
|
||||
|
||||
override def toInt = {
|
||||
|
@ -133,6 +135,11 @@ sealed trait UInt64 extends UnsignedNumber with NumberOperations[UInt64] {
|
|||
|
||||
override def <= (num : UInt64): Boolean = underlying <= num.underlying
|
||||
|
||||
def | (num : UInt64) : UInt64 = UInt64(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 +207,13 @@ sealed trait Int32 extends SignedNumber with NumberOperations[Int32] {
|
|||
|
||||
override def <= (num : Int32): Boolean = underlying <= num.underlying
|
||||
|
||||
def | (num : Int32) : Int32 = Int32(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 +261,10 @@ sealed trait Int64 extends SignedNumber with NumberOperations[Int64] {
|
|||
|
||||
override def <= (num : Int64): Boolean = underlying <= num.underlying
|
||||
|
||||
def | (num : Int64) : Int64 = Int64(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.")
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package org.bitcoins.core.protocol.script
|
||||
|
||||
import org.bitcoins.core.crypto.{ECDigitalSignature, ECPublicKey, EmptyDigitalSignature}
|
||||
import org.bitcoins.core.number.Int32
|
||||
import org.bitcoins.core.protocol.NetworkElement
|
||||
import org.bitcoins.core.script.constant._
|
||||
import org.bitcoins.core.script.crypto.{HashType, HashTypeFactory, SIGHASH_ALL}
|
||||
import org.bitcoins.core.script.crypto.{HashTypeOperations, HashType, SIGHASH_ALL}
|
||||
import org.bitcoins.core.serializers.script.{RawScriptSignatureParser, ScriptParser}
|
||||
import org.bitcoins.core.util.{BitcoinSLogger, BitcoinSUtil, BitcoinScriptUtil, Factory}
|
||||
|
||||
|
@ -43,10 +44,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 EmptyDigitalSignature => SIGHASH_ALL(Int32.one)
|
||||
case sig : ECDigitalSignature => HashTypeOperations.fromBytes(Seq(digitalSignature.bytes.last))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +100,7 @@ trait P2PKHScriptSignature extends ScriptSignature {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
def hashType : HashType = HashTypeFactory.fromByte(signature.bytes.last)
|
||||
def hashType : HashType = HashTypeOperations.fromBytes(Seq(signature.bytes.last))
|
||||
|
||||
override def signatures : Seq[ECDigitalSignature] = {
|
||||
Seq(ECDigitalSignature(asm(1).hex))
|
||||
|
@ -358,7 +359,7 @@ trait P2PKScriptSignature extends ScriptSignature {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
def hashType = HashTypeFactory.fromByte(signature.bytes.last)
|
||||
def hashType : HashType = HashTypeOperations.fromBytes(Seq(signature.bytes.last))
|
||||
|
||||
/**
|
||||
* PubKey scriptSignatures only have one signature
|
||||
|
|
|
@ -1,47 +1,145 @@
|
|||
package org.bitcoins.core.script.crypto
|
||||
|
||||
import org.bitcoins.core.util.{BitcoinSUtil}
|
||||
import org.bitcoins.core.number.Int32
|
||||
import org.bitcoins.core.script.crypto.SIGHASH_ALL.SIGHASH_ALLImpl
|
||||
import org.bitcoins.core.util.{Factory, BitcoinSUtil}
|
||||
|
||||
/**
|
||||
* Created by chris on 1/18/16.
|
||||
*/
|
||||
sealed trait HashType {
|
||||
def byte : Byte
|
||||
def hex : String = BitcoinSUtil.encodeHex(byte)
|
||||
type HashType
|
||||
def num : Int32
|
||||
}
|
||||
|
||||
trait HashTypeOperations extends Factory[HashType] {
|
||||
def fromBytes(bytes : Seq[Byte]) : HashType = {
|
||||
val num = Int32(bytes)
|
||||
fromNumber(num)
|
||||
}
|
||||
|
||||
def fromNumber(num : Int32) : HashType = {
|
||||
if (isSIGHASH_NONE(num)) {
|
||||
if (isSIGHASH_NONE_ANYONECANPAY(num)) SIGHASH_NONE_ANYONECANPAY(num) else SIGHASH_NONE(num)
|
||||
}
|
||||
else if (isSIGHASH_SINGLE(num)) {
|
||||
if (isSIGHASH_SINGLE_ANYONECANPAY(num)) SIGHASH_SINGLE_ANYONECANPAY(num) else SIGHASH_SINGLE(num)
|
||||
}
|
||||
else if (isSIGHASH_ANYONECANPAY(num)) {
|
||||
if (isSIGHASH_ALL_ANYONECANPAY(num)) SIGHASH_ALL_ANYONECANPAY(num) else SIGHASH_ANYONECANPAY(num)
|
||||
}
|
||||
else {
|
||||
SIGHASH_ALL(num)
|
||||
}
|
||||
}
|
||||
|
||||
def byte (hashType : HashType) : Byte = hashType match {
|
||||
case zero if zero.num == Int32.zero => 0x00.toByte
|
||||
case _ : SIGHASH_ALL => 0x01.toByte
|
||||
case _ : SIGHASH_NONE => 0x02.toByte
|
||||
case _ : SIGHASH_SINGLE => 0x03.toByte
|
||||
case _ : SIGHASH_ANYONECANPAY => 0x80.toByte
|
||||
case _ : SIGHASH_ALL_ANYONECANPAY => 0x81.toByte
|
||||
case _ : SIGHASH_NONE_ANYONECANPAY => 0x82.toByte
|
||||
case _ : SIGHASH_SINGLE_ANYONECANPAY => 0x83.toByte
|
||||
}
|
||||
|
||||
def isSIGHASH_ALL_ONE(num : Int32) : Boolean = (num & Int32(0x1f)) == Int32(1)
|
||||
def isSIGHASH_NONE(num : Int32) : Boolean = (num & Int32(0x1f)) == Int32(2)
|
||||
def isSIGHASH_SINGLE(num : Int32) : Boolean = (num & Int32(0x1f)) == Int32(3)
|
||||
def isSIGHASH_ANYONECANPAY(num : Int32) : Boolean = (num & Int32(0x80)) == Int32(0x80)
|
||||
def isSIGHASH_ALL_ANYONECANPAY(num : Int32) : Boolean = isSIGHASH_ALL_ONE(num) && isSIGHASH_ANYONECANPAY(num)
|
||||
def isSIGHASH_NONE_ANYONECANPAY(num : Int32) : Boolean = isSIGHASH_NONE(num) && isSIGHASH_ANYONECANPAY(num)
|
||||
def isSIGHASH_SINGLE_ANYONECANPAY(num: Int32) : Boolean = isSIGHASH_SINGLE(num) && isSIGHASH_ANYONECANPAY(num)
|
||||
def isSIGHASH_ALL(num : Int32) : Boolean = {
|
||||
if (!(isSIGHASH_NONE(num) || isSIGHASH_SINGLE(num) || isSIGHASH_ANYONECANPAY(num) || isSIGHASH_ALL_ANYONECANPAY(num) ||
|
||||
isSIGHASH_SINGLE_ANYONECANPAY(num) || isSIGHASH_NONE_ANYONECANPAY(num))) true
|
||||
else false
|
||||
}
|
||||
|
||||
val hashTypes = Seq(SIGHASH_ALL.value, SIGHASH_NONE, SIGHASH_SINGLE, SIGHASH_ANYONECANPAY,
|
||||
SIGHASH_NONE_ANYONECANPAY, SIGHASH_ALL_ANYONECANPAY, SIGHASH_SINGLE_ANYONECANPAY)
|
||||
|
||||
}
|
||||
|
||||
object HashTypeOperations extends HashTypeOperations
|
||||
|
||||
/**
|
||||
* This seems strange, but it needs to take a parameter. This is because
|
||||
* SIGHASH_ALL is essentially a catch all if the none of the other hash types are matched.
|
||||
* 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
|
||||
*/
|
||||
case class SIGHASH_ALL(byte : Byte = 0x01.toByte) extends HashType
|
||||
|
||||
case object SIGHASH_NONE extends HashType {
|
||||
override def byte = 0x02.toByte
|
||||
object SIGHASH_ALL extends Factory[HashType] with HashTypeOperations {
|
||||
private case class SIGHASH_ALLImpl(num: Int32) extends SIGHASH_ALL {
|
||||
require(isSIGHASH_ALL(num), "SIGHASH_ALL acts as a 'catch-all' for undefined hashtypes, as well as the values of zero and one.")
|
||||
}
|
||||
def value : HashType = SIGHASH_ALL(Int32.one)
|
||||
def apply(num : Int32) : HashType = SIGHASH_ALLImpl(num)
|
||||
override def fromBytes (bytes : Seq[Byte]) : HashType = SIGHASH_ALL(bytes)
|
||||
}
|
||||
|
||||
case object SIGHASH_SINGLE extends HashType {
|
||||
override def byte = 0x03.toByte
|
||||
object SIGHASH_NONE extends Factory[HashType] with HashTypeOperations{
|
||||
private case class SIGHASH_NONEImpl(num : Int32) extends SIGHASH_NONE {
|
||||
require(isSIGHASH_NONE(num), "The bitwise AND of 'num & 0x1f' must be 2 for a hashtype of SIGHASH_NONE.")
|
||||
}
|
||||
def value : HashType= SIGHASH_NONE(Int32(2))
|
||||
def apply(num : Int32) : HashType = SIGHASH_NONEImpl(num)
|
||||
override def fromBytes (bytes : Seq[Byte]) : HashType = SIGHASH_NONE(bytes)
|
||||
}
|
||||
|
||||
case object SIGHASH_ANYONECANPAY extends HashType {
|
||||
override def byte = 0x80.toByte
|
||||
object SIGHASH_SINGLE extends Factory[HashType] with HashTypeOperations{
|
||||
private case class SIGHASH_SINGLEImpl(num : Int32) extends SIGHASH_SINGLE {
|
||||
require(isSIGHASH_SINGLE(num), "The bitwise AND of 'num & 0x1f' must be 3 for a hashtype of SIGHASH_SINGLE.")
|
||||
}
|
||||
def value : HashType = SIGHASH_SINGLE(Int32(3))
|
||||
def apply(num : Int32) : HashType = SIGHASH_SINGLEImpl(num)
|
||||
override def fromBytes (bytes : Seq[Byte]) : HashType = SIGHASH_SINGLE(bytes)
|
||||
}
|
||||
|
||||
case object SIGHASH_ALL_ANYONECANPAY extends HashType {
|
||||
override def byte = (SIGHASH_ANYONECANPAY.byte | 0x01.toByte).toByte
|
||||
object SIGHASH_ANYONECANPAY extends Factory[HashType] with HashTypeOperations{
|
||||
private case class SIGHASH_ANYONECANPAYImpl(num : Int32) extends SIGHASH_ANYONECANPAY {
|
||||
require(isSIGHASH_ANYONECANPAY(num), "The bitwise AND of 'num & 0x80' must be 0x80 (or 128) for a hashtype of SIGHASH_ANYONECANPAY.")
|
||||
}
|
||||
def value : HashType = SIGHASH_ANYONECANPAY(Int32(0x80))
|
||||
def apply(num : Int32) : HashType = SIGHASH_ANYONECANPAYImpl(num)
|
||||
override def fromBytes (bytes : Seq[Byte]) : HashType = SIGHASH_ANYONECANPAY(bytes)
|
||||
}
|
||||
|
||||
case object SIGHASH_NONE_ANYONECANPAY extends HashType {
|
||||
override def byte = (SIGHASH_ANYONECANPAY.byte | SIGHASH_NONE.byte).toByte
|
||||
object SIGHASH_ALL_ANYONECANPAY extends Factory[HashType] with HashTypeOperations{
|
||||
private case class SIGHASH_ALL_ANYONECANPAYImpl(num : Int32) extends SIGHASH_ALL_ANYONECANPAY {
|
||||
require(isSIGHASH_ALL_ANYONECANPAY(num), "SIGHASH_ALL_ANYONECANPAY must be of both hashTypes: SIGHASH_ALL, and SIGHASH_ANYONECANPAY.")
|
||||
}
|
||||
def value : HashType = SIGHASH_ALL_ANYONECANPAY(SIGHASH_ANYONECANPAY.value.num | SIGHASH_ALL.value.num)
|
||||
def apply(num : Int32) : HashType = SIGHASH_ALL_ANYONECANPAYImpl(num)
|
||||
override def fromBytes (bytes : Seq[Byte]) : HashType = SIGHASH_ALL_ANYONECANPAY(bytes)
|
||||
}
|
||||
|
||||
case object SIGHASH_SINGLE_ANYONECANPAY extends HashType {
|
||||
override def byte = (SIGHASH_ANYONECANPAY.byte | SIGHASH_SINGLE.byte).toByte
|
||||
object SIGHASH_NONE_ANYONECANPAY extends Factory[HashType] with HashTypeOperations{
|
||||
private case class SIGHASH_NONE_ANYONECANPAYImpl(num : Int32) extends SIGHASH_NONE_ANYONECANPAY {
|
||||
require(isSIGHASH_NONE_ANYONECANPAY(num), "SIGHASH_NONE_ANYONECANPAY must be of both hashTypes: SIGHASH_NONE, and SIGHASH_ANYONECANPAY.")
|
||||
}
|
||||
def value : HashType = SIGHASH_NONE_ANYONECANPAY(SIGHASH_ANYONECANPAY.value.num | SIGHASH_NONE.value.num)
|
||||
def apply(num : Int32) : HashType = SIGHASH_NONE_ANYONECANPAYImpl(num)
|
||||
override def fromBytes (bytes : Seq[Byte]) : HashType = SIGHASH_NONE_ANYONECANPAY(bytes)
|
||||
}
|
||||
|
||||
object SIGHASH_SINGLE_ANYONECANPAY extends Factory[HashType] with HashTypeOperations{
|
||||
private case class SIGHASH_SINGLE_ANYONECANPAYImpl(num : Int32) extends SIGHASH_SINGLE_ANYONECANPAY {
|
||||
require(isSIGHASH_SINGLE_ANYONECANPAY(num), "SIGHASH_SINGLE_ANYONECANPAY must be of both hashTypes: SIGHASH_SINGLE, and SIGHASH_ANYONECANPAY.")
|
||||
}
|
||||
def value : HashType = SIGHASH_SINGLE_ANYONECANPAY(SIGHASH_ANYONECANPAY.value.num | SIGHASH_SINGLE.value.num)
|
||||
def apply(num : Int32) : HashType = SIGHASH_SINGLE_ANYONECANPAYImpl(num)
|
||||
override def fromBytes (bytes : Seq[Byte]) : HashType = SIGHASH_SINGLE_ANYONECANPAY(bytes)
|
||||
}
|
||||
|
||||
|
||||
sealed trait SIGHASH_ALL extends HashType
|
||||
sealed trait SIGHASH_NONE extends HashType
|
||||
sealed trait SIGHASH_SINGLE extends HashType
|
||||
sealed trait SIGHASH_ANYONECANPAY extends HashType
|
||||
sealed trait SIGHASH_ALL_ANYONECANPAY extends HashType
|
||||
sealed trait SIGHASH_NONE_ANYONECANPAY extends HashType
|
||||
sealed trait SIGHASH_SINGLE_ANYONECANPAY extends 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 ""
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ class TransactionSignatureCreatorTest extends FlatSpec with MustMatchers with Bi
|
|||
val scriptPubKey = ScriptPubKey("76a914d7b4717a934386601ac3f980d01b48c83b8a0b4b88ac")
|
||||
val txSignatureComponent = TransactionSignatureComponent(transaction, UInt32.one, scriptPubKey, Policy.standardScriptVerifyFlags)
|
||||
val privateKey = ECPrivateKey.fromWIFToPrivateKey("cTPg4Zc5Jis2EZXy3NXShgbn487GWBTapbU63BerLDZM3w2hQSjC")
|
||||
val txSignature = TransactionSignatureCreator.createSig(txSignatureComponent, privateKey, SIGHASH_ALL())
|
||||
val txSignature = TransactionSignatureCreator.createSig(txSignatureComponent, privateKey, SIGHASH_ALL.value)
|
||||
txSignature.r must be (expectedSig.r)
|
||||
txSignature.s must be (expectedSig.s)
|
||||
txSignature.hex must be (expectedSig.hex)
|
||||
|
@ -41,7 +41,7 @@ class TransactionSignatureCreatorTest extends FlatSpec with MustMatchers with Bi
|
|||
val scriptPubKey = ScriptPubKey("76a914cd0385f813ec73f8fc340b7069daf566878a0d6b88ac")
|
||||
val txSignatureComponent = TransactionSignatureComponent(transaction, UInt32.zero, scriptPubKey, Policy.standardScriptVerifyFlags)
|
||||
val privateKey = ECPrivateKey.fromWIFToPrivateKey("cTTh7jNtZhg3vHTjvYK8zcHkLfsMAS8iqL7pfZ6eVAVHHF8fN1qy")
|
||||
val txSignature = TransactionSignatureCreator.createSig(txSignatureComponent, privateKey, SIGHASH_ALL())
|
||||
val txSignature = TransactionSignatureCreator.createSig(txSignatureComponent, privateKey, SIGHASH_ALL.value)
|
||||
txSignature.r must be (expectedSig.r)
|
||||
txSignature.s must be (expectedSig.s)
|
||||
txSignature.hex must be (expectedSig.hex)
|
||||
|
@ -55,7 +55,7 @@ class TransactionSignatureCreatorTest extends FlatSpec with MustMatchers with Bi
|
|||
val scriptSig = P2PKScriptSignature(EmptyDigitalSignature)
|
||||
val (spendingTx,inputIndex) = TransactionTestUtil.buildSpendingTransaction(creditingTx,scriptSig,outputIndex)
|
||||
val txSignatureComponent = TransactionSignatureComponent(spendingTx,inputIndex,scriptPubKey,Policy.standardScriptVerifyFlags)
|
||||
val txSignature = TransactionSignatureCreator.createSig(txSignatureComponent,privateKey,SIGHASH_ALL())
|
||||
val txSignature = TransactionSignatureCreator.createSig(txSignatureComponent,privateKey,SIGHASH_ALL.value)
|
||||
|
||||
//add the signature to the scriptSig instead of having an empty scriptSig
|
||||
val signedScriptSig = P2PKScriptSignature(txSignature)
|
||||
|
@ -78,7 +78,7 @@ class TransactionSignatureCreatorTest extends FlatSpec with MustMatchers with Bi
|
|||
val scriptSig = P2PKHScriptSignature(EmptyDigitalSignature,publicKey)
|
||||
val (spendingTx,inputIndex) = TransactionTestUtil.buildSpendingTransaction(creditingTx,scriptSig,outputIndex)
|
||||
val txSignatureComponent = TransactionSignatureComponent(spendingTx,inputIndex,scriptPubKey,Policy.standardScriptVerifyFlags)
|
||||
val txSignature = TransactionSignatureCreator.createSig(txSignatureComponent,privateKey, SIGHASH_ALL())
|
||||
val txSignature = TransactionSignatureCreator.createSig(txSignatureComponent,privateKey, SIGHASH_ALL.value)
|
||||
|
||||
//add the signature to the scriptSig instead of having an empty scriptSig
|
||||
val signedScriptSig = P2PKHScriptSignature(txSignature,publicKey)
|
||||
|
@ -101,7 +101,7 @@ class TransactionSignatureCreatorTest extends FlatSpec with MustMatchers with Bi
|
|||
val scriptSig = MultiSignatureScriptSignature(Seq(EmptyDigitalSignature))
|
||||
val (spendingTx,inputIndex) = TransactionTestUtil.buildSpendingTransaction(creditingTx,scriptSig,outputIndex)
|
||||
val txSignatureComponent = TransactionSignatureComponent(spendingTx,inputIndex,scriptPubKey,Policy.standardScriptVerifyFlags)
|
||||
val txSignature = TransactionSignatureCreator.createSig(txSignatureComponent,privateKey, SIGHASH_ALL())
|
||||
val txSignature = TransactionSignatureCreator.createSig(txSignatureComponent,privateKey, SIGHASH_ALL.value)
|
||||
|
||||
//add the signature to the scriptSig instead of having an empty scriptSig
|
||||
val signedScriptSig = MultiSignatureScriptSignature(Seq(txSignature))
|
||||
|
@ -126,7 +126,7 @@ class TransactionSignatureCreatorTest extends FlatSpec with MustMatchers with Bi
|
|||
|
||||
val (spendingTx,inputIndex) = TransactionTestUtil.buildSpendingTransaction(creditingTx,scriptSig,outputIndex)
|
||||
val txSignatureComponent = TransactionSignatureComponent(spendingTx,inputIndex,redeemScript,Policy.standardScriptVerifyFlags)
|
||||
val txSignature = TransactionSignatureCreator.createSig(txSignatureComponent, privateKey, SIGHASH_ALL())
|
||||
val txSignature = TransactionSignatureCreator.createSig(txSignatureComponent, privateKey, SIGHASH_ALL.value)
|
||||
|
||||
val signedScriptSig = MultiSignatureScriptSignature(Seq(txSignature))
|
||||
val p2shScriptSig = P2SHScriptSignature(signedScriptSig,redeemScript)
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.bitcoinj.core.{DumpedPrivateKey, Sha256Hash, Utils}
|
|||
import org.bitcoinj.core.Transaction.SigHash
|
||||
import org.bitcoinj.params.TestNet3Params
|
||||
import org.bitcoinj.script.{ScriptBuilder, ScriptChunk, ScriptOpCodes}
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.number.{Int32, UInt32}
|
||||
import org.bitcoins.core.serializers.script.ScriptParser
|
||||
import org.bitcoins.core.protocol.script._
|
||||
import org.bitcoins.core.protocol.transaction._
|
||||
|
@ -33,10 +33,10 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
|
||||
spendingTx.hex must be (BitcoinSUtil.encodeHex(BitcoinJTestUtil.multiSigTransaction.bitcoinSerialize()))
|
||||
|
||||
val sigBytes : Seq[Byte] = TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_ALL())
|
||||
val sigBytes : Seq[Byte] = TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_ALL.value)
|
||||
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)
|
||||
|
@ -47,9 +47,9 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
val spendingTx = Transaction(BitcoinJTestUtil.multiSigTransaction.bitcoinSerialize())
|
||||
spendingTx.hex must be (BitcoinSUtil.encodeHex(BitcoinJTestUtil.multiSigTransaction.bitcoinSerialize()))
|
||||
|
||||
val bitcoinsTxSigHash = TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_ALL())
|
||||
val bitcoinsTxSigHash = TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_ALL.value)
|
||||
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)
|
||||
}
|
||||
|
@ -60,10 +60,10 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
spendingTx.hex must be (BitcoinSUtil.encodeHex(BitcoinJTestUtil.multiSigTransaction.bitcoinSerialize()))
|
||||
|
||||
val serialiazedTxForSig : Seq[Byte] =
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_SINGLE)
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_SINGLE.value)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -73,10 +73,10 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
spendingTx.hex must be (BitcoinSUtil.encodeHex(BitcoinJTestUtil.multiSigTransaction.bitcoinSerialize()))
|
||||
|
||||
val hashedTxForSig =
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_SINGLE)
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_SINGLE.value)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -86,10 +86,10 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
spendingTx.hex must be (BitcoinSUtil.encodeHex(BitcoinJTestUtil.multiSigTransaction.bitcoinSerialize()))
|
||||
|
||||
val serialiazedTxForSig : Seq[Byte] =
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_NONE)
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_NONE.value)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -99,10 +99,10 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
spendingTx.hex must be (BitcoinSUtil.encodeHex(BitcoinJTestUtil.multiSigTransaction.bitcoinSerialize()))
|
||||
|
||||
val hashedTxForSig =
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_NONE)
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm,SIGHASH_NONE.value)
|
||||
|
||||
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)
|
||||
|
||||
}
|
||||
|
@ -113,9 +113,9 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
spendingTx.hex must be (BitcoinSUtil.encodeHex(BitcoinJTestUtil.multiSigTransaction.bitcoinSerialize()))
|
||||
|
||||
val serializedTxForSig : Seq[Byte] =
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_ANYONECANPAY)
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_ANYONECANPAY.value)
|
||||
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)
|
||||
|
||||
|
@ -127,9 +127,9 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
spendingTx.hex must be (BitcoinSUtil.encodeHex(BitcoinJTestUtil.multiSigTransaction.bitcoinSerialize()))
|
||||
|
||||
val hashedTxForSig =
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_ANYONECANPAY)
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_ANYONECANPAY.value)
|
||||
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)
|
||||
}
|
||||
|
@ -140,9 +140,9 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
spendingTx.hex must be (BitcoinSUtil.encodeHex(BitcoinJTestUtil.multiSigTransaction.bitcoinSerialize()))
|
||||
|
||||
val serializedTxForSig : Seq[Byte] =
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_ALL_ANYONECANPAY)
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_ALL_ANYONECANPAY.value)
|
||||
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)
|
||||
}
|
||||
|
@ -153,9 +153,9 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
spendingTx.hex must be (BitcoinSUtil.encodeHex(BitcoinJTestUtil.multiSigTransaction.bitcoinSerialize()))
|
||||
|
||||
val serializedTxForSig : Seq[Byte] =
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_SINGLE_ANYONECANPAY)
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_SINGLE_ANYONECANPAY.value)
|
||||
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)
|
||||
}
|
||||
|
@ -166,9 +166,9 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
spendingTx.hex must be (BitcoinSUtil.encodeHex(BitcoinJTestUtil.multiSigTransaction.bitcoinSerialize()))
|
||||
|
||||
val serializedTxForSig : Seq[Byte] =
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_NONE_ANYONECANPAY)
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_NONE_ANYONECANPAY.value)
|
||||
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)
|
||||
}
|
||||
|
@ -179,9 +179,9 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
spendingTx.hex must be (BitcoinSUtil.encodeHex(BitcoinJTestUtil.multiSigTransaction.bitcoinSerialize()))
|
||||
|
||||
val hashedTxForSig =
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_ALL_ANYONECANPAY)
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_ALL_ANYONECANPAY.value)
|
||||
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)
|
||||
}
|
||||
|
@ -192,9 +192,9 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
spendingTx.hex must be (BitcoinSUtil.encodeHex(BitcoinJTestUtil.multiSigTransaction.bitcoinSerialize()))
|
||||
|
||||
val hashedTxForSig =
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_SINGLE_ANYONECANPAY)
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_SINGLE_ANYONECANPAY.value)
|
||||
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)
|
||||
}
|
||||
|
@ -205,9 +205,9 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
spendingTx.hex must be (BitcoinSUtil.encodeHex(BitcoinJTestUtil.multiSigTransaction.bitcoinSerialize()))
|
||||
|
||||
val hashedTxForSig =
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_NONE_ANYONECANPAY)
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,UInt32.zero,scriptPubKey.asm, SIGHASH_NONE_ANYONECANPAY.value)
|
||||
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)
|
||||
}
|
||||
|
@ -233,13 +233,12 @@ 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))
|
||||
}
|
||||
|
||||
|
@ -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(
|
||||
|
@ -283,7 +282,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
val bitcoinjTx = BitcoinjConversions.transaction(spendingTx)
|
||||
val hashType = spendingInput.scriptSignature.hashType(spendingInput.scriptSignature.signatures.head)
|
||||
val bitcoinjHashForSig : Seq[Byte] = BitcoinJSignatureSerialization.serializeForSignature(
|
||||
bitcoinjTx, inputIndex.toInt, creditingOutput.scriptPubKey.bytes.toArray, hashType.byte
|
||||
bitcoinjTx, inputIndex.toInt, creditingOutput.scriptPubKey.bytes.toArray, spendingInput.scriptSignature.signatures.head.bytes.last
|
||||
)
|
||||
val hashedTxForSig : String = BitcoinSUtil.encodeHex(
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,inputIndex,creditingOutput.scriptPubKey.asm,hashType
|
||||
|
@ -304,7 +303,7 @@ class TransactionSignatureSerializerTest extends FlatSpec with MustMatchers with
|
|||
val bitcoinjTx = BitcoinjConversions.transaction(spendingTx)
|
||||
val hashType = spendingInput.scriptSignature.hashType(spendingInput.scriptSignature.signatures.head)
|
||||
val bitcoinjHashForSig : Seq[Byte] = BitcoinJSignatureSerialization.hashForSignature(
|
||||
bitcoinjTx, inputIndex.toInt, creditingOutput.scriptPubKey.bytes.toArray, hashType.byte
|
||||
bitcoinjTx, inputIndex.toInt, creditingOutput.scriptPubKey.bytes.toArray, spendingInput.scriptSignature.signatures.head.bytes.last
|
||||
)
|
||||
val hashedTxForSig =
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,inputIndex,creditingOutput.scriptPubKey.asm, hashType)
|
||||
|
@ -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.value)
|
||||
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.value
|
||||
))
|
||||
|
||||
//serialization is from bitcoin core
|
||||
|
@ -369,10 +368,10 @@ 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)
|
||||
TransactionSignatureSerializer.hashForSignature(spendingTx,inputIndex,scriptPubKey.asm,SIGHASH_ALL_ANYONECANPAY.value)
|
||||
//hash is from bitcoin core
|
||||
hashedTxForSig.hex must be ("57f5a54d548db73fa8ef7a43d011120f9935fe792f0a0630d28ee70b4c72a7e8")
|
||||
}
|
||||
|
@ -388,7 +387,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_SINGLE))
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,inputIndex,scriptPubKey.asm,SIGHASH_SINGLE.value))
|
||||
//serialization is from bitcoin core
|
||||
serializedTxForSig must be ("010000000370ac0a1ae588aaf284c308d67ca92c69a39e2db81337e563bf40c59da0a5cf63000000001976a914dcf72c4fd02f5a987cf9b02f2fabfcac3341a87d88acffffffff7d815b6447e35fbea097e00e028fb7dfbad4f3f0987b4734676c84f3fcd0e8040100000000000000003f1f097333e4d46d51f5e77b53264db8f7f5d2e18217e1099957d0f5af7713ee0100000000000000000180841e00000000001976a914bfb282c70c4191f45b5a6665cad1682f2c9cfdfb88ac0000000003000000")
|
||||
|
||||
|
@ -405,7 +404,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_SINGLE))
|
||||
TransactionSignatureSerializer.serializeForSignature(spendingTx,inputIndex,scriptPubKey.asm,SIGHASH_SINGLE.value))
|
||||
//serialization is from bitcoin core
|
||||
serializedTxForSig must be ("010000000370ac0a1ae588aaf284c308d67ca92c69a39e2db81337e563bf40c59da0a5cf630000000000000000007d815b6447e35fbea097e00e028fb7dfbad4f3f0987b4734676c84f3fcd0e8040100000000000000003f1f097333e4d46d51f5e77b53264db8f7f5d2e18217e1099957d0f5af7713ee010000001976a914dcf72c4fd02f5a987cf9b02f2fabfcac3341a87d88acffffffff03ffffffffffffffff00ffffffffffffffff00e0fd1c00000000001976a91443c52850606c872403c0601e69fa34b26f62db4a88ac0000000003000000")
|
||||
|
||||
|
@ -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.value))
|
||||
//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.value))
|
||||
serializedTxForSig must be ("01000000020001000000000000000000000000000000000000000000000000000000000000000000002321035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efcac01000000000200000000000000000000000000000000000000000000000000000000000000000000000100000001010000000000000001510000000001000000")
|
||||
|
||||
}
|
||||
|
|
|
@ -77,4 +77,13 @@ 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)
|
||||
}
|
||||
|
||||
property("&") =
|
||||
Prop.forAll(NumberGenerator.int32s, NumberGenerator.int32s) { (num1: Int32, num2: Int32) =>
|
||||
Int32(num1.underlying & num2.underlying) == (num1 & num2)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,9 +72,19 @@ 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)
|
||||
}
|
||||
|
||||
property("&") =
|
||||
Prop.forAll(NumberGenerator.int64s, NumberGenerator.int64s) { (num1: Int64, num2: Int64) =>
|
||||
Int64(num1.underlying & num2.underlying) == (num1 & num2)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,4 +77,5 @@ 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)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -92,6 +92,8 @@ 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,14 @@ 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)
|
||||
}
|
||||
|
||||
property("&") =
|
||||
Prop.forAll(NumberGenerator.uInt64s, NumberGenerator.uInt64s) { (num1: UInt64, num2: UInt64) =>
|
||||
UInt64(num1.underlying & num2.underlying) == (num1 & num2)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.bitcoins.core.protocol.script
|
||||
|
||||
import org.bitcoins.core.crypto.{ECDigitalSignature}
|
||||
import org.bitcoins.core.script.crypto.SIGHASH_ALL
|
||||
import org.bitcoins.core.crypto.ECDigitalSignature
|
||||
import org.bitcoins.core.script.crypto.{HashTypeOperations, HashType}
|
||||
import org.bitcoins.core.util.TestUtil
|
||||
import org.scalatest.{FlatSpec, MustMatchers}
|
||||
|
||||
|
@ -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 (HashTypeOperations.fromBytes(Seq(TestUtil.p2pkhScriptSig.signatures.head.bytes.last)))
|
||||
}
|
||||
|
||||
it must "be able to identify the signature in a p2pkh scriptSig" in {
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
package org.bitcoins.core.protocol.script
|
||||
|
||||
|
||||
import org.bitcoins.core.crypto.{ECDigitalSignature}
|
||||
import org.bitcoins.core.crypto.{DoubleSha256Digest, TransactionSignatureSerializer, ECDigitalSignature}
|
||||
import org.bitcoins.core.number.{Int32, UInt32}
|
||||
import org.bitcoins.core.protocol.script.testprotocol.SignatureHashTestCase
|
||||
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.{HashTypeOperations, HashType, 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.
|
||||
|
@ -20,7 +26,7 @@ class ScriptSignatureTest extends FlatSpec with MustMatchers {
|
|||
|
||||
|
||||
it must "derive the signature hash type from the signature" in {
|
||||
TestUtil.scriptSig.hashType(TestUtil.scriptSig.signatures.head) must be (SIGHASH_ALL())
|
||||
TestUtil.scriptSig.hashType(TestUtil.scriptSig.signatures.head) must be (HashTypeOperations.fromBytes(Seq(TestUtil.scriptSig.signatures.head.bytes.last)))
|
||||
}
|
||||
|
||||
|
||||
|
@ -49,19 +55,19 @@ class ScriptSignatureTest extends FlatSpec with MustMatchers {
|
|||
))
|
||||
}
|
||||
it must "find the hash type for a p2sh script signature" in {
|
||||
TestUtil.p2shInputScript.hashType(TestUtil.p2shInputScript2Of2.signatures.head) must be (SIGHASH_ALL())
|
||||
TestUtil.p2shInputScript.hashType(TestUtil.p2shInputScript2Of2.signatures.head) must be (HashTypeOperations.fromBytes(Seq(TestUtil.p2shInputScript2Of2.signatures.head.bytes.last)))
|
||||
}
|
||||
|
||||
it must "find the digital signature and hash type for a SIGHASH_SINGLE" in {
|
||||
TestUtil.p2shInputScriptSigHashSingle.signatures.head.hex must be ("3045022100dfcfafcea73d83e1c54d444a19fb30d17317f922c19e2ff92dcda65ad09cba24022001e7a805c5672c49b222c5f2f1e67bb01f87215fb69df184e7c16f66c1f87c2903")
|
||||
TestUtil.p2shInputScriptSigHashSingle.hashType(TestUtil.p2shInputScriptSigHashSingle.signatures.head) must be (SIGHASH_SINGLE)
|
||||
TestUtil.p2shInputScriptSigHashSingle.hashType(TestUtil.p2shInputScriptSigHashSingle.signatures.head) must be (SIGHASH_SINGLE.value)
|
||||
}
|
||||
|
||||
it must "find the hash type for the weird occurrence of hash type being 0 on the blockchain" in {
|
||||
//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 +94,30 @@ 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 {
|
||||
import org.bitcoins.core.protocol.script.testprotocol.SignatureHashTestCaseProtocol._
|
||||
//["raw_transaction, script, input_index, hashType, signature_hash (result)"],
|
||||
/* val lines =
|
||||
"""
|
||||
| [
|
||||
| ["4ddaa680026ec4d8060640304b86823f1ac760c260cef81d85bd847952863d629a3002b54b0200000008526365636a656aab65457861fc6c24bdc760c8b2e906b6656edaf9ed22b5f50e1fb29ec076ceadd9e8ebcb6b000000000152ffffffff033ff04f00000000000551526a00657a1d900300000000002153af040000000003006a6300000000", "ab526a53acabab", 0, 1055317633, "7f21b62267ed52462e371a917eb3542569a4049b9dfca2de3c75872b39510b26"]
|
||||
| ]
|
||||
|
|
||||
""".stripMargin*/
|
||||
|
||||
val source = Source.fromURL(this.getClass.getResource("/sighash.json"))
|
||||
val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
|
||||
val testCases : Seq[SignatureHashTestCase] = lines.parseJson.convertTo[Seq[SignatureHashTestCase]]
|
||||
|
||||
for {
|
||||
testCase <- testCases
|
||||
} yield {
|
||||
val hashForSig = TransactionSignatureSerializer.hashForSignature(testCase.transaction, testCase.inputIndex, testCase.script.asm, testCase.hashType)
|
||||
//the hash is returned with opposite endianness
|
||||
val flipHash = BitcoinSUtil.flipEndianess(testCase.hash.hex)
|
||||
hashForSig must be (DoubleSha256Digest(flipHash))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package org.bitcoins.core.protocol.script.testprotocol
|
||||
|
||||
import org.bitcoins.core.crypto.DoubleSha256Digest
|
||||
import org.bitcoins.core.number.{Int32, UInt32}
|
||||
import org.bitcoins.core.protocol.script.ScriptPubKey
|
||||
import org.bitcoins.core.protocol.transaction.Transaction
|
||||
import org.bitcoins.core.script.constant.{ScriptToken, ScriptConstant}
|
||||
import org.bitcoins.core.script.crypto.HashType
|
||||
|
||||
/**
|
||||
* Created by tom on 7/21/16.
|
||||
*/
|
||||
trait SignatureHashTestCase {
|
||||
def transaction : Transaction
|
||||
def script : ScriptPubKey
|
||||
def inputIndex : UInt32
|
||||
def hashTypeNum : Int32
|
||||
def hashType : HashType
|
||||
def hash : DoubleSha256Digest
|
||||
}
|
||||
|
||||
case class SignatureHashTestCaseImpl(transaction: Transaction, script : ScriptPubKey, inputIndex : UInt32, hashTypeNum: Int32, hashType : HashType,
|
||||
hash : DoubleSha256Digest) extends SignatureHashTestCase
|
|
@ -65,9 +65,9 @@ class TransactionTest extends FlatSpec with MustMatchers with BitcoinSLogger {
|
|||
/* 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*/
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.bitcoins.core.script.crypto
|
||||
|
||||
import org.bitcoins.core.number.Int32
|
||||
import org.scalatest.{FlatSpec, MustMatchers}
|
||||
|
||||
/**
|
||||
|
@ -7,9 +8,44 @@ 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)
|
||||
"HashType" must "combine hash types with SIGHASH_ANYONECANPAY" in {
|
||||
SIGHASH_ALL_ANYONECANPAY.value.num must be (Int32(0x81))
|
||||
SIGHASH_NONE_ANYONECANPAY.value.num must be (Int32(0x82))
|
||||
SIGHASH_SINGLE_ANYONECANPAY.value.num must be (Int32(0x83))
|
||||
}
|
||||
|
||||
it must "find a hash type by its hex value" in {
|
||||
HashTypeOperations("00000001") must be (SIGHASH_ALL.value)
|
||||
HashTypeOperations("00000002") must be (SIGHASH_NONE.value)
|
||||
HashTypeOperations("00000003") must be (SIGHASH_SINGLE.value)
|
||||
HashTypeOperations("00000080") must be (SIGHASH_ANYONECANPAY.value)
|
||||
}
|
||||
|
||||
it must "find a hash type by its byte value" in {
|
||||
|
||||
HashTypeOperations(Seq(0.toByte)) must be (SIGHASH_ALL(Int32.zero))
|
||||
HashTypeOperations(Seq(1.toByte)) must be (SIGHASH_ALL(Int32.one))
|
||||
HashTypeOperations(Seq(2.toByte)) must be (SIGHASH_NONE.value)
|
||||
HashTypeOperations(Seq(3.toByte)) must be (SIGHASH_SINGLE.value)
|
||||
HashTypeOperations(Int32(0x80).bytes) must be (SIGHASH_ANYONECANPAY.value)
|
||||
}
|
||||
|
||||
it must "default to SIGHASH_ALL if the given string/byte is not known" in {
|
||||
HashTypeOperations(Seq(0x124.toByte)) must be (SIGHASH_ALL(Int32(36)))
|
||||
}
|
||||
|
||||
it must "find hashType for number 1190874345" in {
|
||||
//1190874345 & 0x80 = 0x80
|
||||
val num = Int32(1190874345)
|
||||
HashTypeOperations.fromNumber(num) must be (SIGHASH_ANYONECANPAY(num))
|
||||
}
|
||||
|
||||
it must "determine if a given number is of hashType SIGHASH_ALL" in {
|
||||
HashTypeOperations.isSIGHASH_ALL(Int32.zero) must be (true)
|
||||
HashTypeOperations.isSIGHASH_ALL(Int32.one) must be (true)
|
||||
HashTypeOperations.isSIGHASH_ALL(Int32(5)) must be (true)
|
||||
|
||||
HashTypeOperations.isSIGHASH_ALL(SIGHASH_NONE.value.num) must be (false)
|
||||
HashTypeOperations.isSIGHASH_ALL(SIGHASH_SINGLE.value.num) must be (false)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,13 +22,15 @@ class ScriptInterpreterTest extends FlatSpec with MustMatchers with ScriptInterp
|
|||
|
||||
|
||||
//use this to represent a single test case from script_valid.json
|
||||
/*val lines =
|
||||
/* val lines =
|
||||
"""
|
||||
| [ ["1",
|
||||
"0x61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161",
|
||||
"P2SH,STRICTENC",
|
||||
"OP_COUNT",
|
||||
">201 opcodes executed. 0x61 is NOP"]]
|
||||
| [[
|
||||
| "0x47 0x304402204710a85181663b32d25c70ec2bbd14adff5ddfff6cb50d09e155ef5f541fc86c0220056b0cc949be9386ecc5f6c2ac0493269031dbb185781db90171b54ac127790281",
|
||||
| "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG",
|
||||
| "",
|
||||
| "OK",
|
||||
| "P2PK anyonecanpay"
|
||||
|]]
|
||||
""".stripMargin*/
|
||||
val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
|
||||
val json = lines.parseJson
|
||||
|
|
Loading…
Add table
Reference in a new issue