mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-25 07:17:32 +01:00
Removing script types from ScriptPubKey's - this was redundant
This commit is contained in:
parent
816205e5f5
commit
716758cd64
12 changed files with 97 additions and 35 deletions
|
@ -3,7 +3,6 @@ package org.scalacoin.crypto
|
||||||
import org.scalacoin.currency.CurrencyUnits
|
import org.scalacoin.currency.CurrencyUnits
|
||||||
import org.scalacoin.marshallers.RawBitcoinSerializerHelper
|
import org.scalacoin.marshallers.RawBitcoinSerializerHelper
|
||||||
import org.scalacoin.marshallers.transaction.RawTransactionOutputParser
|
import org.scalacoin.marshallers.transaction.RawTransactionOutputParser
|
||||||
import org.scalacoin.protocol.{MultiSignature, NonStandard, P2SH, P2PKH}
|
|
||||||
import org.scalacoin.protocol.script._
|
import org.scalacoin.protocol.script._
|
||||||
import org.scalacoin.protocol.transaction._
|
import org.scalacoin.protocol.transaction._
|
||||||
import org.scalacoin.script.constant.ScriptToken
|
import org.scalacoin.script.constant.ScriptToken
|
||||||
|
|
|
@ -23,7 +23,7 @@ sealed trait ScriptPubKey extends TransactionElement with BitcoinSLogger {
|
||||||
*/
|
*/
|
||||||
def asm : Seq[ScriptToken]
|
def asm : Seq[ScriptToken]
|
||||||
|
|
||||||
/**
|
/* /**
|
||||||
* Returns the script type of this scriptPubKey
|
* Returns the script type of this scriptPubKey
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@ -35,7 +35,7 @@ sealed trait ScriptPubKey extends TransactionElement with BitcoinSLogger {
|
||||||
case _ if (asm.last == OP_CHECKMULTISIG) => MultiSignature
|
case _ if (asm.last == OP_CHECKMULTISIG) => MultiSignature
|
||||||
case _ => NonStandard
|
case _ => NonStandard
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
//the addresses that the bitcoins correlated to the output
|
//the addresses that the bitcoins correlated to the output
|
||||||
def addresses : Seq[BitcoinAddress] = ???
|
def addresses : Seq[BitcoinAddress] = ???
|
||||||
|
|
|
@ -26,6 +26,7 @@ sealed trait Transaction extends TransactionElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
case object EmptyTransaction extends Transaction {
|
case object EmptyTransaction extends Transaction {
|
||||||
|
override def txId = "0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
override def version = TransactionConstants.version
|
override def version = TransactionConstants.version
|
||||||
override def inputs = Seq()
|
override def inputs = Seq()
|
||||||
override def outputs = Seq()
|
override def outputs = Seq()
|
||||||
|
|
|
@ -22,7 +22,7 @@ sealed trait TransactionOutput extends TransactionElement {
|
||||||
override def hex = RawTransactionOutputParser.write(Seq(this))
|
override def hex = RawTransactionOutputParser.write(Seq(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
case object TransactionOutput extends TransactionOutput {
|
case object EmptyTransactionOutput extends TransactionOutput {
|
||||||
override def value = CurrencyUnits.negativeSatoshi
|
override def value = CurrencyUnits.negativeSatoshi
|
||||||
override def scriptPubKey = ScriptPubKeyFactory.empty
|
override def scriptPubKey = ScriptPubKeyFactory.empty
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package org.scalacoin.script.locktime
|
package org.scalacoin.script.locktime
|
||||||
|
|
||||||
|
import org.scalacoin.protocol.transaction.TransactionConstants
|
||||||
import org.scalacoin.script.constant.{ScriptNumberImpl, ScriptNumber}
|
import org.scalacoin.script.constant.{ScriptNumberImpl, ScriptNumber}
|
||||||
import org.scalacoin.script.{ScriptProgramFactory, ScriptProgramImpl, ScriptProgram}
|
import org.scalacoin.script.{ScriptProgramFactory, ScriptProgramImpl, ScriptProgram}
|
||||||
|
import org.scalacoin.util.BitcoinSLogger
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by chris on 2/8/16.
|
* Created by chris on 2/8/16.
|
||||||
*/
|
*/
|
||||||
trait LockTimeInterpreter {
|
trait LockTimeInterpreter extends BitcoinSLogger {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,14 +27,18 @@ trait LockTimeInterpreter {
|
||||||
require(program.script.headOption.isDefined && program.script.head == OP_CHECKLOCKTIMEVERIFY,
|
require(program.script.headOption.isDefined && program.script.head == OP_CHECKLOCKTIMEVERIFY,
|
||||||
"Script top must be OP_CHECKLOCKTIMEVERIFY")
|
"Script top must be OP_CHECKLOCKTIMEVERIFY")
|
||||||
if (program.stack.size == 0) {
|
if (program.stack.size == 0) {
|
||||||
|
logger.warn("Transaction validation failing in OP_CHECKLOCKTIMEVERIFY because we have no stack items")
|
||||||
ScriptProgramFactory.factory(program, program.stack, program.script.tail, false)
|
ScriptProgramFactory.factory(program, program.stack, program.script.tail, false)
|
||||||
} else {
|
} else if (program.transaction.inputs(program.inputIndex).sequence == TransactionConstants.sequence) {
|
||||||
|
logger.warn("Transaction validation failing in OP_CHECKLOCKTIMEVERIFY because the sequence number is 0xffffffff")
|
||||||
|
ScriptProgramFactory.factory(program, program.stack, program.script.tail, false)
|
||||||
|
}
|
||||||
|
else {
|
||||||
val isValid = program.stack.head match {
|
val isValid = program.stack.head match {
|
||||||
case s : ScriptNumber if (s < ScriptNumberImpl(0)) => false
|
case s : ScriptNumber if (s < ScriptNumberImpl(0)) => false
|
||||||
case s : ScriptNumber if (s > ScriptNumberImpl(500000000) && program.transaction.lockTime < 500000000) => false
|
case s : ScriptNumber if (s > ScriptNumberImpl(500000000) && program.transaction.lockTime < 500000000) => false
|
||||||
case s : ScriptNumber if (s < ScriptNumberImpl(500000000) && program.transaction.lockTime > 500000000) => false
|
case s : ScriptNumber if (s < ScriptNumberImpl(500000000) && program.transaction.lockTime > 500000000) => false
|
||||||
case s if (program.transaction.inputs.map(_.sequence == 0xffffffff).exists(_ == true)) => false
|
case _ => false
|
||||||
case _ => true
|
|
||||||
}
|
}
|
||||||
ScriptProgramFactory.factory(program,program.stack, program.script.tail, isValid)
|
ScriptProgramFactory.factory(program,program.stack, program.script.tail, isValid)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package org.scalacoin.marshallers.transaction
|
package org.scalacoin.marshallers.transaction
|
||||||
|
|
||||||
import org.scalacoin.currency.{Satoshis, CurrencyUnits, Bitcoins}
|
import org.scalacoin.currency.{Satoshis, CurrencyUnits, Bitcoins}
|
||||||
import org.scalacoin.protocol.{P2PKH, P2SH}
|
|
||||||
import org.scalacoin.protocol.transaction.TransactionOutput
|
import org.scalacoin.protocol.transaction.TransactionOutput
|
||||||
import org.scalacoin.script.bitwise.OP_EQUAL
|
import org.scalacoin.script.bitwise.OP_EQUAL
|
||||||
import org.scalacoin.script.constant.{BytesToPushOntoStackImpl, ScriptConstantImpl}
|
import org.scalacoin.script.constant.{BytesToPushOntoStackImpl, ScriptConstantImpl}
|
||||||
|
@ -26,8 +25,6 @@ class RawTransactionOutputParserTest extends FlatSpec with MustMatchers with Raw
|
||||||
secondOutput.value must be (CurrencyUnits.toSatoshis(Bitcoins(0.02981145)))
|
secondOutput.value must be (CurrencyUnits.toSatoshis(Bitcoins(0.02981145)))
|
||||||
firstOutput.scriptPubKey.asm must be (Seq(OP_HASH160, BytesToPushOntoStackImpl(20),ScriptConstantImpl("eda8ae08b5c9f973f49543e90a7c292367b3337c"), OP_EQUAL))
|
firstOutput.scriptPubKey.asm must be (Seq(OP_HASH160, BytesToPushOntoStackImpl(20),ScriptConstantImpl("eda8ae08b5c9f973f49543e90a7c292367b3337c"), OP_EQUAL))
|
||||||
secondOutput.scriptPubKey.asm must be (Seq(OP_HASH160,BytesToPushOntoStackImpl(20), ScriptConstantImpl("be2319b9060429692ebeffaa3be38497dc5380c8"), OP_EQUAL))
|
secondOutput.scriptPubKey.asm must be (Seq(OP_HASH160,BytesToPushOntoStackImpl(20), ScriptConstantImpl("be2319b9060429692ebeffaa3be38497dc5380c8"), OP_EQUAL))
|
||||||
firstOutput.scriptPubKey.scriptType must be (P2SH)
|
|
||||||
secondOutput.scriptPubKey.scriptType must be (P2SH)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "seralialize a transaction output" in {
|
it must "seralialize a transaction output" in {
|
||||||
|
@ -54,7 +51,5 @@ class RawTransactionOutputParserTest extends FlatSpec with MustMatchers with Raw
|
||||||
val rawTwoOutputs = "026c405d05000000001976a91431a420903c05a0a7de2de40c9f02ebedbacdc17288ac809698000000000017a914af575bd77c5ce7eba3bd9ce6f89774713ae62c7987"
|
val rawTwoOutputs = "026c405d05000000001976a91431a420903c05a0a7de2de40c9f02ebedbacdc17288ac809698000000000017a914af575bd77c5ce7eba3bd9ce6f89774713ae62c7987"
|
||||||
val outputs = RawTransactionOutputParser.read(rawTwoOutputs)
|
val outputs = RawTransactionOutputParser.read(rawTwoOutputs)
|
||||||
outputs.size must be (2)
|
outputs.size must be (2)
|
||||||
outputs.head.scriptPubKey.scriptType must be (P2PKH)
|
|
||||||
outputs(1).scriptPubKey.scriptType must be (P2SH)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package org.scalacoin.protocol.script
|
package org.scalacoin.protocol.script
|
||||||
|
|
||||||
import org.scalacoin.crypto.ECFactory
|
import org.scalacoin.crypto.ECFactory
|
||||||
import org.scalacoin.protocol.{MultiSignature, P2SH, P2PKH}
|
|
||||||
import org.scalacoin.script.bitwise.OP_EQUALVERIFY
|
import org.scalacoin.script.bitwise.OP_EQUALVERIFY
|
||||||
import org.scalacoin.script.constant.{ScriptConstantImpl, BytesToPushOntoStackImpl, ScriptToken}
|
import org.scalacoin.script.constant.{ScriptConstantImpl, BytesToPushOntoStackImpl, ScriptToken}
|
||||||
import org.scalacoin.script.crypto.{OP_CHECKSIG, OP_HASH160, OP_CODESEPARATOR}
|
import org.scalacoin.script.crypto.{OP_CHECKSIG, OP_HASH160, OP_CODESEPARATOR}
|
||||||
|
@ -24,25 +23,4 @@ class ScriptPubKeyTest extends FlatSpec with MustMatchers {
|
||||||
scriptPubKey.asm must be (expectedAsm)
|
scriptPubKey.asm must be (expectedAsm)
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "derive a P2PKH script type from a scriptPubKey" in {
|
|
||||||
scriptPubKey.scriptType must be (P2PKH)
|
|
||||||
}
|
|
||||||
|
|
||||||
it must "derive a P2SH script type for a scriptPubKey" in {
|
|
||||||
|
|
||||||
TestUtil.p2shScriptPubKey.scriptType must be (P2SH)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
it must "derive a multisignature script type for a scriptPubKey" in {
|
|
||||||
val multiSigRawScriptPubKey = "5221025878e270211662a27181cf" +
|
|
||||||
"4d6ad4d2cf0e69a98a3815c086f587c7e9388d87182103fc85980e3fac1f3d" +
|
|
||||||
"8a5c3223c3ef5bffc1bd42d2cc42add8c3899cc66e7f1906210215b5bd0508" +
|
|
||||||
"69166a70a7341b4f216e268b7c6c7504576dcea2cce7d11cc9a35f53ae"
|
|
||||||
val multiSigScriptPubKey = ScriptPubKeyFactory.fromHex(multiSigRawScriptPubKey)
|
|
||||||
|
|
||||||
multiSigScriptPubKey.scriptType must be (MultiSignature)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package org.scalacoin.protocol.transaction
|
||||||
|
|
||||||
|
import org.scalacoin.protocol.script.EmptyScriptSignature
|
||||||
|
import org.scalatest.{FlatSpec, MustMatchers}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by chris on 3/30/16.
|
||||||
|
*/
|
||||||
|
class TransactionInputTest extends FlatSpec with MustMatchers {
|
||||||
|
|
||||||
|
|
||||||
|
"TransactionInput" must "define an empty transaction input" in {
|
||||||
|
EmptyTransactionInput.previousOutput must be (EmptyTransactionOutPoint)
|
||||||
|
EmptyTransactionInput.scriptSignature must be (EmptyScriptSignature)
|
||||||
|
EmptyTransactionInput.scriptSigCompactSizeUInt.num must be (0)
|
||||||
|
EmptyTransactionInput.scriptSigCompactSizeUInt.size must be (1)
|
||||||
|
EmptyTransactionInput.sequence must be (TransactionConstants.sequence)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package org.scalacoin.protocol.transaction
|
||||||
|
|
||||||
|
import org.scalatest.{FlatSpec, MustMatchers}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by chris on 3/30/16.
|
||||||
|
*/
|
||||||
|
class TransactionOutPointTest extends FlatSpec with MustMatchers {
|
||||||
|
"TransactionOutPoint" must "define an empty transaction outpoint" in {
|
||||||
|
EmptyTransactionOutPoint.txId must be ("")
|
||||||
|
EmptyTransactionOutPoint.vout must be (-1)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.scalacoin.protocol.transaction
|
||||||
|
|
||||||
|
import org.scalacoin.currency.CurrencyUnits
|
||||||
|
import org.scalacoin.protocol.script.EmptyScriptPubKey
|
||||||
|
import org.scalatest.{FlatSpec, MustMatchers}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by chris on 3/30/16.
|
||||||
|
*/
|
||||||
|
class TransactionOutputTest extends FlatSpec with MustMatchers {
|
||||||
|
|
||||||
|
"TransactionOutput" must "define an empty transaction output" in {
|
||||||
|
EmptyTransactionOutput.scriptPubKey must be (EmptyScriptPubKey)
|
||||||
|
EmptyTransactionOutput.value must be (CurrencyUnits.negativeSatoshi)
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,4 +16,11 @@ class TransactionTest extends FlatSpec with MustMatchers {
|
||||||
|
|
||||||
tx.txId must be ("cddda897b0e9322937ee1f4fd5d6147d60f04a0f4d3b461e4f87066ac3918f2a")
|
tx.txId must be ("cddda897b0e9322937ee1f4fd5d6147d60f04a0f4d3b461e4f87066ac3918f2a")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it must "have an empty transaction with the correct fields" in {
|
||||||
|
EmptyTransaction.inputs.isEmpty must be (true)
|
||||||
|
EmptyTransaction.outputs.isEmpty must be (true)
|
||||||
|
EmptyTransaction.lockTime must be (TransactionConstants.lockTime)
|
||||||
|
EmptyTransaction.txId must be ("0000000000000000000000000000000000000000000000000000000000000000")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package org.scalacoin.script.locktime
|
||||||
|
|
||||||
|
import org.scalacoin.script.ScriptProgramFactory
|
||||||
|
import org.scalacoin.script.constant.OP_0
|
||||||
|
import org.scalacoin.util.TestUtil
|
||||||
|
import org.scalatest.{MustMatchers, FlatSpec}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by chris on 3/30/16.
|
||||||
|
*/
|
||||||
|
class LockTimeInterpreterTest extends FlatSpec with MustMatchers with LockTimeInterpreter {
|
||||||
|
|
||||||
|
"LockTimeInterpreter" must "mark the transaction invalid if the stack is empty" in {
|
||||||
|
val stack = Seq()
|
||||||
|
val script = Seq(OP_CHECKLOCKTIMEVERIFY)
|
||||||
|
val program = ScriptProgramFactory.factory(TestUtil.testProgram,stack,script)
|
||||||
|
val newProgram = opCheckLockTimeVerify(program)
|
||||||
|
newProgram.isValid must be (false)
|
||||||
|
}
|
||||||
|
|
||||||
|
it must "mark the transaction invalid if the transaction's sequence number is set to the max" in {
|
||||||
|
val stack = Seq(OP_0)
|
||||||
|
val script = Seq(OP_CHECKLOCKTIMEVERIFY)
|
||||||
|
val program = ScriptProgramFactory.factory(TestUtil.testProgram,stack,script)
|
||||||
|
val newProgram = opCheckLockTimeVerify(program)
|
||||||
|
newProgram.isValid must be (false)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue