1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use super::{op::*, Script};
use crate::constants::MAX_SCRIPT_BYTE_SIZE;
#[derive(Clone, Debug, Default)]
pub struct Builder {
byte_code: Vec<u8>,
}
impl Builder {
pub fn new() -> Builder {
Builder {
byte_code: Vec::with_capacity(MAX_SCRIPT_BYTE_SIZE),
}
}
pub fn build(self) -> Script {
self.byte_code.into()
}
pub fn push(self, frame: OpFrame) -> Self {
self.try_push(frame).expect("script byte size exceeded")
}
pub fn try_push(mut self, frame: OpFrame) -> Option<Self> {
match frame {
OpFrame::False => self.insert_bytes(&[Operand::PushFalse.into()])?,
OpFrame::True => self.insert_bytes(&[Operand::PushTrue.into()])?,
OpFrame::PubKey(key) => {
self.insert_bytes(&[Operand::PushPubKey.into()])?;
self.insert_bytes(key.as_ref())?;
}
OpFrame::OpNot => self.insert_bytes(&[Operand::OpNot.into()])?,
OpFrame::OpIf => self.insert_bytes(&[Operand::OpIf.into()])?,
OpFrame::OpElse => self.insert_bytes(&[Operand::OpElse.into()])?,
OpFrame::OpEndIf => self.insert_bytes(&[Operand::OpEndIf.into()])?,
OpFrame::OpReturn => self.insert_bytes(&[Operand::OpReturn.into()])?,
OpFrame::OpCheckSig => self.insert_bytes(&[Operand::OpCheckSig.into()])?,
OpFrame::OpCheckSigFastFail => {
self.insert_bytes(&[Operand::OpCheckSigFastFail.into()])?
}
OpFrame::OpCheckMultiSig(threshold, key_count) => {
self.insert_bytes(&[Operand::OpCheckMultiSig.into(), threshold, key_count])?
}
OpFrame::OpCheckMultiSigFastFail(threshold, key_count) => self.insert_bytes(&[
Operand::OpCheckMultiSigFastFail.into(),
threshold,
key_count,
])?,
}
Some(self)
}
#[must_use]
fn insert_bytes(&mut self, bytes: &[u8]) -> Option<()> {
if self.byte_code.len() + bytes.len() <= MAX_SCRIPT_BYTE_SIZE {
self.byte_code.extend(bytes);
Some(())
} else {
None
}
}
}
impl AsRef<[u8]> for Builder {
fn as_ref(&self) -> &[u8] {
&self.byte_code
}
}