mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-03-03 10:46:42 +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.transaction.Transaction
|
||||
import org.scalacoin.script.locktime.{OP_CHECKLOCKTIMEVERIFY, LockTimeInterpreter}
|
||||
import org.scalacoin.script.splice.{SpliceInterpreter, OP_SIZE}
|
||||
import org.scalacoin.script.{ScriptProgramImpl, ScriptProgram}
|
||||
import org.scalacoin.script.arithmetic._
|
||||
|
@ -19,7 +20,8 @@ import scala.annotation.tailrec
|
|||
* Created by chris on 1/6/16.
|
||||
*/
|
||||
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)
|
||||
|
||||
|
@ -132,6 +134,10 @@ trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with Con
|
|||
|
||||
//splice operations
|
||||
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
|
||||
case Nil => program.stack.headOption != Some(ScriptFalse)
|
||||
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