use bitcoin;
use elements::opcodes::all;
use elements::script;
pub trait CovOperations: Sized {
fn chk_size(self, len: usize) -> Self;
fn chk_amt(self) -> Self;
fn verify_cov(self, key: &bitcoin::PublicKey) -> Self;
fn post_codesep_script(self) -> Self;
}
impl CovOperations for script::Builder {
fn chk_size(self, len: usize) -> Self {
self.push_opcode(all::OP_SIZE)
.push_int(len as i64)
.push_opcode(all::OP_EQUALVERIFY)
}
fn chk_amt(self) -> Self {
let mut builder = self;
builder = builder.push_opcode(all::OP_DUP);
builder = builder.push_int(1).push_opcode(all::OP_LEFT);
builder = builder.push_int(1).push_opcode(all::OP_EQUAL);
builder = builder
.push_opcode(all::OP_IF)
.push_opcode(all::OP_SIZE)
.push_int(9)
.push_opcode(all::OP_EQUALVERIFY);
builder
.push_opcode(all::OP_ELSE)
.push_opcode(all::OP_SIZE)
.push_int(33)
.push_opcode(all::OP_EQUALVERIFY)
.push_opcode(all::OP_ENDIF)
}
#[rustfmt::skip]
fn verify_cov(self, key: &bitcoin::PublicKey) -> Self {
use elements::opcodes::all::{OP_CAT, OP_SWAP};
let mut builder = self;
builder = builder.push_verify();
builder = builder.push_int(11).push_opcode(all::OP_PICK);
builder = builder.push_int(11).push_opcode(all::OP_PICK);
builder = builder.push_int(1).push_opcode(all::OP_LEFT);
builder = builder.push_opcode(all::OP_CAT);
builder = builder.push_opcode(all::OP_TOALTSTACK);
builder = builder.chk_size(4).push_opcode(OP_SWAP); builder = builder.chk_size(32).push_opcode(OP_CAT).push_opcode(OP_SWAP); builder = builder.chk_size(32).push_opcode(OP_CAT).push_opcode(OP_SWAP); builder = builder.chk_size(32).push_opcode(OP_CAT).push_opcode(OP_SWAP); builder = builder.chk_size(36).push_opcode(OP_CAT).push_opcode(OP_SWAP); builder = builder.chk_size(3).push_opcode(OP_CAT).push_opcode(OP_SWAP); builder = builder.chk_amt().push_opcode(OP_CAT).push_opcode(OP_SWAP); builder = builder.chk_size(4).push_opcode(OP_CAT).push_opcode(OP_SWAP); builder = builder.chk_size(32).push_opcode(OP_CAT).push_opcode(OP_SWAP); builder = builder.chk_size(4).push_opcode(OP_CAT).push_opcode(OP_SWAP); builder = builder.chk_size(4).push_opcode(OP_CAT);
builder = builder.push_opcode(all::OP_SHA256);
builder = builder.push_key(key).push_opcode(all::OP_DUP);
builder = builder
.push_opcode(all::OP_FROMALTSTACK)
.push_opcode(all::OP_SWAP);
builder = builder.push_opcode(all::OP_CODESEPARATOR);
builder.post_codesep_script()
}
fn post_codesep_script(self) -> Self {
let builder = self;
builder
.push_opcode(all::OP_CHECKSIGVERIFY)
.push_opcode(all::OP_CHECKSIGFROMSTACK)
}
}