All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.acinq.bitcoin.ScriptElt.scala Maven / Gradle / Ivy

package fr.acinq.bitcoin

import fr.acinq.bitcoin.Crypto.PublicKey
import scodec.bits.ByteVector

// @formatter:off
abstract class ScriptElt
case object OP_0 extends ScriptElt
case object OP_PUSHDATA1 extends ScriptElt
case object OP_PUSHDATA2 extends ScriptElt
case object OP_PUSHDATA4 extends ScriptElt
case object OP_1NEGATE extends ScriptElt
case object OP_RESERVED extends ScriptElt
case object OP_1 extends ScriptElt
case object OP_2 extends ScriptElt
case object OP_3 extends ScriptElt
case object OP_4 extends ScriptElt
case object OP_5 extends ScriptElt
case object OP_6 extends ScriptElt
case object OP_7 extends ScriptElt
case object OP_8 extends ScriptElt
case object OP_9 extends ScriptElt
case object OP_10 extends ScriptElt
case object OP_11 extends ScriptElt
case object OP_12 extends ScriptElt
case object OP_13 extends ScriptElt
case object OP_14 extends ScriptElt
case object OP_15 extends ScriptElt
case object OP_16 extends ScriptElt
case object OP_NOP extends ScriptElt
case object OP_VER extends ScriptElt
case object OP_IF extends ScriptElt
case object OP_NOTIF extends ScriptElt
case object OP_VERIF extends ScriptElt
case object OP_VERNOTIF extends ScriptElt
case object OP_ELSE extends ScriptElt
case object OP_ENDIF extends ScriptElt
case object OP_VERIFY extends ScriptElt
case object OP_RETURN extends ScriptElt
case object OP_TOALTSTACK extends ScriptElt
case object OP_FROMALTSTACK extends ScriptElt
case object OP_2DROP extends ScriptElt
case object OP_2DUP extends ScriptElt
case object OP_3DUP extends ScriptElt
case object OP_2OVER extends ScriptElt
case object OP_2ROT extends ScriptElt
case object OP_2SWAP extends ScriptElt
case object OP_IFDUP extends ScriptElt
case object OP_DEPTH extends ScriptElt
case object OP_DROP extends ScriptElt
case object OP_DUP extends ScriptElt
case object OP_NIP extends ScriptElt
case object OP_OVER extends ScriptElt
case object OP_PICK extends ScriptElt
case object OP_ROLL extends ScriptElt
case object OP_ROT extends ScriptElt
case object OP_SWAP extends ScriptElt
case object OP_TUCK extends ScriptElt
case object OP_CAT extends ScriptElt
case object OP_SUBSTR extends ScriptElt
case object OP_LEFT extends ScriptElt
case object OP_RIGHT extends ScriptElt
case object OP_SIZE extends ScriptElt
case object OP_INVERT extends ScriptElt
case object OP_AND extends ScriptElt
case object OP_OR extends ScriptElt
case object OP_XOR extends ScriptElt
case object OP_EQUAL extends ScriptElt
case object OP_EQUALVERIFY extends ScriptElt
case object OP_RESERVED1 extends ScriptElt
case object OP_RESERVED2 extends ScriptElt
case object OP_1ADD extends ScriptElt
case object OP_1SUB extends ScriptElt
case object OP_2MUL extends ScriptElt
case object OP_2DIV extends ScriptElt
case object OP_NEGATE extends ScriptElt
case object OP_ABS extends ScriptElt
case object OP_NOT extends ScriptElt
case object OP_0NOTEQUAL extends ScriptElt
case object OP_ADD extends ScriptElt
case object OP_SUB extends ScriptElt
case object OP_MUL extends ScriptElt
case object OP_DIV extends ScriptElt
case object OP_MOD extends ScriptElt
case object OP_LSHIFT extends ScriptElt
case object OP_RSHIFT extends ScriptElt
case object OP_BOOLAND extends ScriptElt
case object OP_BOOLOR extends ScriptElt
case object OP_NUMEQUAL extends ScriptElt
case object OP_NUMEQUALVERIFY extends ScriptElt
case object OP_NUMNOTEQUAL extends ScriptElt
case object OP_LESSTHAN extends ScriptElt
case object OP_GREATERTHAN extends ScriptElt
case object OP_LESSTHANOREQUAL extends ScriptElt
case object OP_GREATERTHANOREQUAL extends ScriptElt
case object OP_MIN extends ScriptElt
case object OP_MAX extends ScriptElt
case object OP_WITHIN extends ScriptElt
case object OP_RIPEMD160 extends ScriptElt
case object OP_SHA1 extends ScriptElt
case object OP_SHA256 extends ScriptElt
case object OP_HASH160 extends ScriptElt
case object OP_HASH256 extends ScriptElt
case object OP_CODESEPARATOR extends ScriptElt
case object OP_CHECKSIG extends ScriptElt
case object OP_CHECKSIGVERIFY extends ScriptElt
case object OP_CHECKMULTISIG extends ScriptElt
case object OP_CHECKMULTISIGVERIFY extends ScriptElt
case object OP_NOP1 extends ScriptElt
case object OP_CHECKLOCKTIMEVERIFY extends ScriptElt
case object OP_CHECKSEQUENCEVERIFY extends ScriptElt
case object OP_NOP4 extends ScriptElt
case object OP_NOP5 extends ScriptElt
case object OP_NOP6 extends ScriptElt
case object OP_NOP7 extends ScriptElt
case object OP_NOP8 extends ScriptElt
case object OP_NOP9 extends ScriptElt
case object OP_NOP10 extends ScriptElt
case object OP_SMALLINTEGER extends ScriptElt
case object OP_INVALIDOPCODE extends ScriptElt
object OP_PUSHDATA {
  def apply(data: ByteVector) = if (data.length < 0x4c) new OP_PUSHDATA(data, data.size.toInt)
  else if (data.length < 0xff) new OP_PUSHDATA(data, 0x4c)
  else if (data.length < 0xffff) new OP_PUSHDATA(data, 0x4d)
  else if (data.length < 0xffffffff) new OP_PUSHDATA(data, 0x4e)
  else throw new IllegalArgumentException(s"data is ${data.length}, too big for OP_PUSHDATA")

  def apply(pub: PublicKey): OP_PUSHDATA = OP_PUSHDATA(pub.value)

  def isMinimal(data: ByteVector, code: Int): Boolean = if (data.length == 0) code == ScriptElt.elt2code(OP_0)
  else if (data.length == 1 && data(0) >= 1 && data(0) <= 16) code == ScriptElt.elt2code(OP_1) + (data(0) - 1)
  else if (data.length == 1 && data(0) == 0x81.toByte) code == ScriptElt.elt2code(OP_1NEGATE)
  else if (data.length <= 75) code == data.length
  else if (data.length <= 255) code == ScriptElt.elt2code(OP_PUSHDATA1)
  else if (data.length <= 65535) code == ScriptElt.elt2code(OP_PUSHDATA2)
  else true
}
case class OP_PUSHDATA(data: ByteVector, code: Int) extends ScriptElt {
  override def toString = data.toString
}
case class OP_INVALID(code: Int) extends ScriptElt
// @formatter:off

object ScriptElt {
  // code -> ScriptElt
  val code2elt: Map[Int, ScriptElt] = Map(
    0x00 -> OP_0,
    0x4c -> OP_PUSHDATA1,
    0x4d -> OP_PUSHDATA2,
    0x4e -> OP_PUSHDATA4,
    0x4f -> OP_1NEGATE,
    0x50 -> OP_RESERVED,
    0x51 -> OP_1,
    0x52 -> OP_2,
    0x53 -> OP_3,
    0x54 -> OP_4,
    0x55 -> OP_5,
    0x56 -> OP_6,
    0x57 -> OP_7,
    0x58 -> OP_8,
    0x59 -> OP_9,
    0x5a -> OP_10,
    0x5b -> OP_11,
    0x5c -> OP_12,
    0x5d -> OP_13,
    0x5e -> OP_14,
    0x5f -> OP_15,
    0x60 -> OP_16,
    0x61 -> OP_NOP,
    0x62 -> OP_VER,
    0x63 -> OP_IF,
    0x64 -> OP_NOTIF,
    0x65 -> OP_VERIF,
    0x66 -> OP_VERNOTIF,
    0x67 -> OP_ELSE,
    0x68 -> OP_ENDIF,
    0x69 -> OP_VERIFY,
    0x6a -> OP_RETURN,
    0x6b -> OP_TOALTSTACK,
    0x6c -> OP_FROMALTSTACK,
    0x6d -> OP_2DROP,
    0x6e -> OP_2DUP,
    0x6f -> OP_3DUP,
    0x70 -> OP_2OVER,
    0x71 -> OP_2ROT,
    0x72 -> OP_2SWAP,
    0x73 -> OP_IFDUP,
    0x74 -> OP_DEPTH,
    0x75 -> OP_DROP,
    0x76 -> OP_DUP,
    0x77 -> OP_NIP,
    0x78 -> OP_OVER,
    0x79 -> OP_PICK,
    0x7a -> OP_ROLL,
    0x7b -> OP_ROT,
    0x7c -> OP_SWAP,
    0x7d -> OP_TUCK,
    0x7e -> OP_CAT,
    0x7f -> OP_SUBSTR,
    0x80 -> OP_LEFT,
    0x81 -> OP_RIGHT,
    0x82 -> OP_SIZE,
    0x83 -> OP_INVERT,
    0x84 -> OP_AND,
    0x85 -> OP_OR,
    0x86 -> OP_XOR,
    0x87 -> OP_EQUAL,
    0x88 -> OP_EQUALVERIFY,
    0x89 -> OP_RESERVED1,
    0x8a -> OP_RESERVED2,
    0x8b -> OP_1ADD,
    0x8c -> OP_1SUB,
    0x8d -> OP_2MUL,
    0x8e -> OP_2DIV,
    0x8f -> OP_NEGATE,
    0x90 -> OP_ABS,
    0x91 -> OP_NOT,
    0x92 -> OP_0NOTEQUAL,
    0x93 -> OP_ADD,
    0x94 -> OP_SUB,
    0x95 -> OP_MUL,
    0x96 -> OP_DIV,
    0x97 -> OP_MOD,
    0x98 -> OP_LSHIFT,
    0x99 -> OP_RSHIFT,
    0x9a -> OP_BOOLAND,
    0x9b -> OP_BOOLOR,
    0x9c -> OP_NUMEQUAL,
    0x9d -> OP_NUMEQUALVERIFY,
    0x9e -> OP_NUMNOTEQUAL,
    0x9f -> OP_LESSTHAN,
    0xa0 -> OP_GREATERTHAN,
    0xa1 -> OP_LESSTHANOREQUAL,
    0xa2 -> OP_GREATERTHANOREQUAL,
    0xa3 -> OP_MIN,
    0xa4 -> OP_MAX,
    0xa5 -> OP_WITHIN,
    0xa6 -> OP_RIPEMD160,
    0xa7 -> OP_SHA1,
    0xa8 -> OP_SHA256,
    0xa9 -> OP_HASH160,
    0xaa -> OP_HASH256,
    0xab -> OP_CODESEPARATOR,
    0xac -> OP_CHECKSIG,
    0xad -> OP_CHECKSIGVERIFY,
    0xae -> OP_CHECKMULTISIG,
    0xaf -> OP_CHECKMULTISIGVERIFY,
    0xb0 -> OP_NOP1,
    0xb1 -> OP_CHECKLOCKTIMEVERIFY,
    0xb2 -> OP_CHECKSEQUENCEVERIFY,
    0xb3 -> OP_NOP4,
    0xb4 -> OP_NOP5,
    0xb5 -> OP_NOP6,
    0xb6 -> OP_NOP7,
    0xb7 -> OP_NOP8,
    0xb8 -> OP_NOP9,
    0xb9 -> OP_NOP10,
    0xfa -> OP_SMALLINTEGER,
    0xff -> OP_INVALIDOPCODE)

  // ScriptElt -> code
  val elt2code: Map[ScriptElt, Int] = code2elt.map(_.swap)

  // name -> code
  val name2code = code2elt.view.mapValues(_.asInstanceOf[Product].productPrefix.stripPrefix("OP_")).map(_.swap).toMap + ("NOP2" -> 0xb1) + ("NOP3" -> 0xb2)

  def isPush(op: ScriptElt, size: Int): Boolean = {
    op match {
      case OP_PUSHDATA(data, _) => data.length == size
      case _ => false
    }
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy