mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-03-03 18:47:38 +01:00
implementing OP_CHECKLOCKTIMEVERIFY script operation
This commit is contained in:
parent
d02f259bc0
commit
c0f709db37
2 changed files with 48 additions and 1 deletions
|
@ -2,6 +2,7 @@ package org.scalacoin.script.interpreter
|
||||||
|
|
||||||
import org.scalacoin.protocol.script.{ScriptSignature, ScriptPubKey}
|
import org.scalacoin.protocol.script.{ScriptSignature, ScriptPubKey}
|
||||||
import org.scalacoin.protocol.transaction.Transaction
|
import org.scalacoin.protocol.transaction.Transaction
|
||||||
|
import org.scalacoin.script.locktime.{OP_CHECKLOCKTIMEVERIFY, LockTimeInterpreter}
|
||||||
import org.scalacoin.script.splice.{SpliceInterpreter, OP_SIZE}
|
import org.scalacoin.script.splice.{SpliceInterpreter, OP_SIZE}
|
||||||
import org.scalacoin.script.{ScriptProgramImpl, ScriptProgram}
|
import org.scalacoin.script.{ScriptProgramImpl, ScriptProgram}
|
||||||
import org.scalacoin.script.arithmetic._
|
import org.scalacoin.script.arithmetic._
|
||||||
|
@ -19,7 +20,8 @@ import scala.annotation.tailrec
|
||||||
* Created by chris on 1/6/16.
|
* Created by chris on 1/6/16.
|
||||||
*/
|
*/
|
||||||
trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with ControlOperationsInterpreter
|
trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with ControlOperationsInterpreter
|
||||||
with BitwiseInterpreter with ConstantInterpreter with ArithmeticInterpreter with SpliceInterpreter {
|
with BitwiseInterpreter with ConstantInterpreter with ArithmeticInterpreter with SpliceInterpreter
|
||||||
|
with LockTimeInterpreter {
|
||||||
|
|
||||||
private def logger = LoggerFactory.getLogger(this.getClass().toString)
|
private def logger = LoggerFactory.getLogger(this.getClass().toString)
|
||||||
|
|
||||||
|
@ -132,6 +134,10 @@ trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with Con
|
||||||
|
|
||||||
//splice operations
|
//splice operations
|
||||||
case OP_SIZE :: t => loop(opSize(program))
|
case OP_SIZE :: t => loop(opSize(program))
|
||||||
|
|
||||||
|
//locktime operations
|
||||||
|
case OP_CHECKLOCKTIMEVERIFY :: t => loop(opCheckLockTimeVerify(program))
|
||||||
|
|
||||||
//no more script operations to run, True is represented by any representation of non-zero
|
//no more script operations to run, True is represented by any representation of non-zero
|
||||||
case Nil => program.stack.headOption != Some(ScriptFalse)
|
case Nil => program.stack.headOption != Some(ScriptFalse)
|
||||||
case h :: t => throw new RuntimeException(h + " was unmatched")
|
case h :: t => throw new RuntimeException(h + " was unmatched")
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package org.scalacoin.script.locktime
|
||||||
|
|
||||||
|
import org.scalacoin.script.constant.{ScriptNumberImpl, ScriptNumber}
|
||||||
|
import org.scalacoin.script.{ScriptProgramImpl, ScriptProgram}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by chris on 2/8/16.
|
||||||
|
*/
|
||||||
|
trait LockTimeInterpreter {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks transaction as invalid if the top stack item is greater than the transaction's nLockTime field,
|
||||||
|
* otherwise script evaluation continues as though an OP_NOP was executed. Transaction is also invalid if
|
||||||
|
* 1. the stack is empty; or
|
||||||
|
* 2. the top stack item is negative; or
|
||||||
|
* 3. the top stack item is greater than or equal to 500000000 while the transaction's nLockTime field is less than 500000000,
|
||||||
|
* or vice versa; or
|
||||||
|
* 4. the input's nSequence field is equal to 0xffffffff.
|
||||||
|
* The precise semantics are described in BIP 0065
|
||||||
|
* @param program
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
def opCheckLockTimeVerify(program : ScriptProgram) : ScriptProgram = {
|
||||||
|
require(program.script.headOption.isDefined && program.script.head == OP_CHECKLOCKTIMEVERIFY,
|
||||||
|
"Script top must be OP_CHECKLOCKTIMEVERIFY")
|
||||||
|
if (program.stack.size == 0) {
|
||||||
|
ScriptProgramImpl(program.stack, program.script.tail, program.transaction, program.altStack,false)
|
||||||
|
} else {
|
||||||
|
val isValid = program.stack.head match {
|
||||||
|
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 if (program.transaction.inputs.map(_.sequence == 0xffffffff).exists(_ == true)) => false
|
||||||
|
case _ => true
|
||||||
|
}
|
||||||
|
ScriptProgramImpl(program.stack, program.script.tail, program.transaction, program.altStack,isValid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue