use amplify::confinement::Confined;
use crate::opcodes::*;
use crate::{ScriptBytes, LIB_NAME_BITCOIN};
#[derive(Copy, Clone, Eq, PartialEq, Debug, Display)]
#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
#[strict_type(lib = LIB_NAME_BITCOIN, tags = repr, into_u8, try_from_u8)]
#[non_exhaustive]
#[repr(u8)]
pub enum OpCode {
#[display("OP_PUSH_BYTES0")]
PushBytes0 = OP_PUSHBYTES_0,
#[display("OP_PUSH_BYTES32")]
PushBytes32 = OP_PUSHBYTES_32,
Reserved = OP_RESERVED,
#[display("OP_RETURN")]
#[strict_type(dumb)]
Return = OP_RETURN,
#[display("OP_PUSH_DATA1")]
PushData1 = OP_PUSHDATA1,
#[display("OP_PUSH_DATA2")]
PushData2 = OP_PUSHDATA2,
#[display("OP_PUSH_DATA3")]
PushData4 = OP_PUSHDATA4,
#[display("OP_PUSHNUM_1")]
PushNum1 = OP_PUSHNUM_1,
}
#[derive(Wrapper, WrapperMut, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From, Default)]
#[wrapper(Deref, Index, RangeOps, BorrowSlice, LowerHex, UpperHex)]
#[wrapper_mut(DerefMut, IndexMut, RangeMut, BorrowSliceMut)]
#[derive(StrictType, StrictEncode, StrictDecode)]
#[strict_type(lib = LIB_NAME_BITCOIN)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", transparent)
)]
pub struct SigScript(
#[from]
#[from(Vec<u8>)]
ScriptBytes,
);
#[derive(Wrapper, WrapperMut, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From, Default)]
#[wrapper(Deref, Index, RangeOps, BorrowSlice, LowerHex, UpperHex)]
#[wrapper_mut(DerefMut, IndexMut, RangeMut, BorrowSliceMut)]
#[derive(StrictType, StrictEncode, StrictDecode)]
#[strict_type(lib = LIB_NAME_BITCOIN)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", transparent)
)]
pub struct ScriptPubkey(
#[from]
#[from(Vec<u8>)]
ScriptBytes,
);
impl ScriptPubkey {
pub fn new() -> Self { Self::default() }
pub fn with_capacity(capacity: usize) -> Self {
Self(ScriptBytes::from(Confined::with_capacity(capacity)))
}
pub fn op_return(data: &[u8]) -> Self {
let mut script = Self::with_capacity(ScriptBytes::len_for_slice(data.len()) + 1);
script.push_opcode(OpCode::Return);
script.0.push_slice(data);
script
}
pub fn is_op_return(&self) -> bool { self[0] == OpCode::Return as u8 }
pub fn push_opcode(&mut self, op_code: OpCode) {
self.0.push(op_code as u8).expect("script exceeds 4GB");
}
}