Skip to content

Commit

Permalink
add byte function to determine default byte value of each HashType
Browse files Browse the repository at this point in the history
  • Loading branch information
TomMcCabe committed Aug 5, 2016
1 parent 32b1582 commit 9012e1a
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ trait TransactionSignatureChecker extends BitcoinSLogger {
logger.error("Signature did not have a low s value")
ScriptValidationFailureHighSValue
} else if (ScriptFlagUtil.requireStrictEncoding(flags) && signature.bytes.nonEmpty &&
!HashType.hashTypes.contains(HashType.fromNumber(Int32(signature.bytes.last)))) {
!HashType.hashTypes.contains(HashType(Int32(signature.bytes.last)))) {
logger.error("signature: " + signature.bytes)
logger.error("Hash type was not defined on the signature")
ScriptValidationFailureHashType
Expand Down Expand Up @@ -79,7 +79,7 @@ trait TransactionSignatureChecker extends BitcoinSLogger {
sigsRemoved
}
val hashTypeByte = if (signature.bytes.nonEmpty) signature.bytes.last else 0x00.toByte
val hashType = HashType.fromBytes(Seq(0.toByte, 0.toByte, 0.toByte, hashTypeByte))
val hashType = HashType(Seq(0.toByte, 0.toByte, 0.toByte, hashTypeByte))
val hashForSignature = TransactionSignatureSerializer.hashForSignature(txSignatureComponent.transaction,
txSignatureComponent.inputIndex,
sigsRemovedScript, hashType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,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(hashType)))
ECDigitalSignature(signature.bytes ++ Seq(hashType.byte))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ sealed trait ScriptSignature extends NetworkElement with BitcoinSLogger {
def hashType(digitalSignature: ECDigitalSignature) : HashType = {
digitalSignature match {
case EmptyDigitalSignature => SIGHASH_ALL(Int32.one)
case sig : ECDigitalSignature => HashType.fromBytes(Seq(digitalSignature.bytes.last))
case sig : ECDigitalSignature => HashType(Seq(digitalSignature.bytes.last))
}
}
}
Expand Down Expand Up @@ -100,7 +100,7 @@ trait P2PKHScriptSignature extends ScriptSignature {
*
* @return
*/
def hashType : HashType = HashType.fromBytes(Seq(signature.bytes.last))
def hashType : HashType = HashType(Seq(signature.bytes.last))

override def signatures : Seq[ECDigitalSignature] = {
Seq(ECDigitalSignature(asm(1).hex))
Expand Down Expand Up @@ -359,7 +359,7 @@ trait P2PKScriptSignature extends ScriptSignature {
*
* @return
*/
def hashType : HashType = HashType.fromBytes(Seq(signature.bytes.last))
def hashType : HashType = HashType(Seq(signature.bytes.last))

/**
* PubKey scriptSignatures only have one signature
Expand Down
22 changes: 15 additions & 7 deletions src/main/scala/org/bitcoins/core/script/crypto/HashType.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.bitcoins.core.util.Factory
*/
sealed trait HashType {
def num : Int32
def byte : Byte
}

object HashType extends Factory[HashType] {
Expand Down Expand Up @@ -77,70 +78,77 @@ object HashType extends Factory[HashType] {
*/

object SIGHASH_ALL extends Factory[SIGHASH_ALL] {
private case class SIGHASH_ALLImpl(num: Int32) extends SIGHASH_ALL {
private case class SIGHASH_ALLImpl(num: Int32, byte : Byte = 0x01.toByte) extends SIGHASH_ALL {
require(HashType.isSIGHASH_ALL(num), "SIGHASH_ALL acts as a 'catch-all' for undefined hashtypes, and has a default " +
"value of one. Your input was: " + num + ", which is of hashType: " + HashType(num))
}
def byte : Byte = HashType.byte(defaultValue)
def defaultValue : SIGHASH_ALL = SIGHASH_ALL(Int32.one)
def apply(num : Int32) : SIGHASH_ALL = SIGHASH_ALLImpl(num)
override def fromBytes (bytes : Seq[Byte]) : SIGHASH_ALL = SIGHASH_ALL(Int32(bytes))
}

object SIGHASH_NONE extends Factory[SIGHASH_NONE] {
private case class SIGHASH_NONEImpl(num : Int32) extends SIGHASH_NONE {
private case class SIGHASH_NONEImpl(num : Int32, byte : Byte = 0x02.toByte) extends SIGHASH_NONE {
require(HashType.isSIGHASH_NONE(num), "The bitwise AND of 'num & 0x1f' must be 2 for a hashtype of SIGHASH_NONE. " +
"Your input was: " + num + ", which is of hashType: " + HashType(num))
}
def byte : Byte = HashType.byte(defaultValue)
def defaultValue : SIGHASH_NONE = SIGHASH_NONE(Int32(2))
def apply(num : Int32) : SIGHASH_NONE = SIGHASH_NONEImpl(num)
override def fromBytes (bytes : Seq[Byte]) : SIGHASH_NONE = SIGHASH_NONE(Int32(bytes))
}

object SIGHASH_SINGLE extends Factory[SIGHASH_SINGLE] {
private case class SIGHASH_SINGLEImpl(num : Int32) extends SIGHASH_SINGLE {
private case class SIGHASH_SINGLEImpl(num : Int32, byte : Byte = 0x03.toByte) extends SIGHASH_SINGLE {
require(HashType.isSIGHASH_SINGLE(num), "The bitwise AND of 'num & 0x1f' must be 3 for a hashtype of SIGHASH_SINGLE." +
" Your input was: " + num + ", which is of hashType: " + HashType(num))
}
def byte : Byte = HashType.byte(defaultValue)
def defaultValue : SIGHASH_SINGLE = SIGHASH_SINGLE(Int32(3))
def apply(num : Int32) : SIGHASH_SINGLE = SIGHASH_SINGLEImpl(num)
override def fromBytes (bytes : Seq[Byte]) : SIGHASH_SINGLE = SIGHASH_SINGLE(Int32(bytes))
}

object SIGHASH_ANYONECANPAY extends Factory[SIGHASH_ANYONECANPAY] {
private case class SIGHASH_ANYONECANPAYImpl(num : Int32) extends SIGHASH_ANYONECANPAY {
private case class SIGHASH_ANYONECANPAYImpl(num : Int32, byte : Byte = 0x80.toByte) extends SIGHASH_ANYONECANPAY {
require(HashType.isSIGHASH_ANYONECANPAY(num) && HashType.isONLY_ANYONE_CANPAY(num), "The bitwise AND of 'num & 0x80' must be 0x80 (or 128) for a hashtype of " +
"SIGHASH_ANYONECANPAY. Your input was: " + num + ", which is of hashType: " + HashType(num))
}
def byte : Byte = HashType.byte(defaultValue)
def defaultValue : SIGHASH_ANYONECANPAY = SIGHASH_ANYONECANPAY(Int32(0x80))
def apply(num : Int32) : SIGHASH_ANYONECANPAY = SIGHASH_ANYONECANPAYImpl(num)
override def fromBytes (bytes : Seq[Byte]) : SIGHASH_ANYONECANPAY = SIGHASH_ANYONECANPAY(Int32(bytes))
}

object SIGHASH_ALL_ANYONECANPAY extends Factory[SIGHASH_ALL_ANYONECANPAY] {
private case class SIGHASH_ALL_ANYONECANPAYImpl(num : Int32) extends SIGHASH_ALL_ANYONECANPAY {
private case class SIGHASH_ALL_ANYONECANPAYImpl(num : Int32, byte : Byte = 0x81.toByte) extends SIGHASH_ALL_ANYONECANPAY {
require(HashType.isSIGHASH_ALL_ANYONECANPAY(num), "SIGHASH_ALL_ANYONECANPAY must be of both hashTypes: SIGHASH_ALL, and " +
"SIGHASH_ANYONECANPAY. Your input was: " + num + ", which is of hashType: " + HashType(num))
}
def byte : Byte = HashType.byte(defaultValue)
def defaultValue : SIGHASH_ALL_ANYONECANPAY = SIGHASH_ALL_ANYONECANPAY(SIGHASH_ANYONECANPAY.defaultValue.num | SIGHASH_ALL.defaultValue.num)
def apply(num : Int32) : SIGHASH_ALL_ANYONECANPAY = SIGHASH_ALL_ANYONECANPAYImpl(num)
override def fromBytes (bytes : Seq[Byte]) : SIGHASH_ALL_ANYONECANPAY = SIGHASH_ALL_ANYONECANPAY(Int32(bytes))
}

object SIGHASH_NONE_ANYONECANPAY extends Factory[SIGHASH_NONE_ANYONECANPAY] {
private case class SIGHASH_NONE_ANYONECANPAYImpl(num : Int32) extends SIGHASH_NONE_ANYONECANPAY {
private case class SIGHASH_NONE_ANYONECANPAYImpl(num : Int32, byte : Byte = 0x82.toByte) extends SIGHASH_NONE_ANYONECANPAY {
require(HashType.isSIGHASH_NONE_ANYONECANPAY(num), "SIGHASH_NONE_ANYONECANPAY must be of both hashTypes: SIGHASH_NONE, and " +
"SIGHASH_ANYONECANPAY. Your input was: " + num + ", which is of hashType: " + HashType(num))
}
def byte : Byte = HashType.byte(defaultValue)
def defaultValue : SIGHASH_NONE_ANYONECANPAY = SIGHASH_NONE_ANYONECANPAY(SIGHASH_ANYONECANPAY.defaultValue.num | SIGHASH_NONE.defaultValue.num)
def apply(num : Int32) : SIGHASH_NONE_ANYONECANPAY = SIGHASH_NONE_ANYONECANPAYImpl(num)
override def fromBytes (bytes : Seq[Byte]) : SIGHASH_NONE_ANYONECANPAY = SIGHASH_NONE_ANYONECANPAY(Int32(bytes))
}

object SIGHASH_SINGLE_ANYONECANPAY extends Factory[SIGHASH_SINGLE_ANYONECANPAY] {
private case class SIGHASH_SINGLE_ANYONECANPAYImpl(num : Int32) extends SIGHASH_SINGLE_ANYONECANPAY {
private case class SIGHASH_SINGLE_ANYONECANPAYImpl(num : Int32, byte : Byte = 0x83.toByte) extends SIGHASH_SINGLE_ANYONECANPAY {
require(HashType.isSIGHASH_SINGLE_ANYONECANPAY(num), "SIGHASH_SINGLE_ANYONECANPAY must be of both hashTypes: SIGHASH_SINGLE, " +
"and SIGHASH_ANYONECANPAY. Your input was: " + num + ", which is of hashType: " + HashType(num))
}
def byte : Byte = HashType.byte(defaultValue)
def defaultValue : SIGHASH_SINGLE_ANYONECANPAY = SIGHASH_SINGLE_ANYONECANPAY(SIGHASH_ANYONECANPAY.defaultValue.num | SIGHASH_SINGLE.defaultValue.num)
def apply(num : Int32) : SIGHASH_SINGLE_ANYONECANPAY = SIGHASH_SINGLE_ANYONECANPAYImpl(num)
override def fromBytes (bytes : Seq[Byte]) : SIGHASH_SINGLE_ANYONECANPAY = SIGHASH_SINGLE_ANYONECANPAY(Int32(bytes))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,4 @@ 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 ""
}
Loading

0 comments on commit 9012e1a

Please sign in to comment.