1use hex;
20use script::op_codes::*;
21use std::fmt;
22use util::Result;
23
24mod checker;
25mod interpreter;
26#[allow(dead_code)]
27pub mod op_codes;
28mod stack;
29
30pub use self::checker::{Checker, TransactionChecker, TransactionlessChecker};
31pub(crate) use self::interpreter::next_op;
32
33pub const MAX_SCRIPT_ELEMENT_SIZE: usize = 520;
35
36pub const MAX_PUBKEYS_PER_MULTISIG: usize = 20;
38
39pub const MAX_OPS_PER_SCRIPT: usize = 500;
41
42pub const MAX_SCRIPT_SIZE: usize = 10000;
44
45#[derive(Default, Clone, PartialEq, Eq, Hash)]
47pub struct Script(pub Vec<u8>);
48
49impl Script {
50 pub fn new() -> Script {
52 Script(vec![])
53 }
54
55 pub fn append(&mut self, byte: u8) {
57 self.0.push(byte);
58 }
59
60 pub fn append_slice(&mut self, slice: &[u8]) {
62 self.0.extend_from_slice(slice);
63 }
64
65 pub fn append_data(&mut self, data: &[u8]) {
67 let len = data.len();
68 match len {
69 0 => self.0.push(op_codes::OP_0),
70 1..=75 => {
71 self.0.push(op_codes::OP_PUSH + len as u8);
72 self.0.extend_from_slice(data);
73 }
74 76..=255 => {
75 self.0.push(op_codes::OP_PUSHDATA1);
76 self.0.push(len as u8);
77 self.0.extend_from_slice(data);
78 }
79 256..=65535 => {
80 self.0.push(op_codes::OP_PUSHDATA2);
81 self.0.push((len >> 0) as u8);
82 self.0.push((len >> 8) as u8);
83 self.0.extend_from_slice(data);
84 }
85 _ => {
86 self.0.push(op_codes::OP_PUSHDATA4);
87 self.0.push((len >> 0) as u8);
88 self.0.push((len >> 8) as u8);
89 self.0.push((len >> 16) as u8);
90 self.0.push((len >> 24) as u8);
91 self.0.extend_from_slice(data);
92 }
93 }
94 }
95
96 pub fn append_num(&mut self, n: i32) -> Result<()> {
100 self.append_data(&stack::encode_num(n as i64)?);
101 Ok(())
102 }
103
104 pub fn eval<T: Checker>(&self, checker: &mut T) -> Result<()> {
106 self::interpreter::eval(&self.0, checker)
107 }
108}
109
110impl fmt::Debug for Script {
111 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
112 let script = &self.0;
113 let mut ret = String::new();
114 let mut i = 0;
115 ret.push_str("[");
116 while i < script.len() {
117 if i != 0 {
118 ret.push_str(" ")
119 }
120 match script[i] {
121 OP_0 => ret.push_str("OP_0"),
122 OP_1NEGATE => ret.push_str("OP_1NEGATE"),
123 OP_1 => ret.push_str("OP_1"),
124 OP_2 => ret.push_str("OP_2"),
125 OP_3 => ret.push_str("OP_3"),
126 OP_4 => ret.push_str("OP_4"),
127 OP_5 => ret.push_str("OP_5"),
128 OP_6 => ret.push_str("OP_6"),
129 OP_7 => ret.push_str("OP_7"),
130 OP_8 => ret.push_str("OP_8"),
131 OP_9 => ret.push_str("OP_9"),
132 OP_10 => ret.push_str("OP_10"),
133 OP_11 => ret.push_str("OP_11"),
134 OP_12 => ret.push_str("OP_12"),
135 OP_13 => ret.push_str("OP_13"),
136 OP_14 => ret.push_str("OP_14"),
137 OP_15 => ret.push_str("OP_15"),
138 OP_16 => ret.push_str("OP_16"),
139 len @ 1..=75 => {
140 ret.push_str(&format!("OP_PUSH+{} ", len));
141 if i + 1 + len as usize <= script.len() {
142 ret.push_str(&hex::encode(&script[i + 1..i + 1 + len as usize]));
143 } else {
144 break;
145 }
146 }
147 OP_PUSHDATA1 => {
148 ret.push_str("OP_PUSHDATA1 ");
149 if i + 2 <= script.len() {
150 let len = script[i + 1] as usize;
151 ret.push_str(&format!("{} ", len));
152 if i + 2 + len <= script.len() {
153 ret.push_str(&hex::encode(&script[i + 2..i + 2 + len]));
154 } else {
155 break;
156 }
157 } else {
158 break;
159 }
160 }
161 OP_PUSHDATA2 => {
162 ret.push_str("OP_PUSHDATA2 ");
163 if i + 3 <= script.len() {
164 let len = ((script[i + 1] as usize) << 0) + ((script[i + 2] as usize) << 8);
165 ret.push_str(&format!("{} ", len));
166 if i + 3 + len <= script.len() {
167 ret.push_str(&hex::encode(&script[i + 3..i + 3 + len]));
168 } else {
169 break;
170 }
171 } else {
172 break;
173 }
174 }
175 OP_PUSHDATA4 => {
176 ret.push_str("OP_PUSHDATA4 ");
177 if i + 5 <= script.len() {
178 let len = ((script[i + 1] as usize) << 0)
179 + ((script[i + 2] as usize) << 8)
180 + ((script[i + 3] as usize) << 16)
181 + ((script[i + 4] as usize) << 24);
182 ret.push_str(&format!("{} ", len));
183 if i + 5 + len <= script.len() {
184 ret.push_str(&hex::encode(&script[i..i + len]));
185 } else {
186 break;
187 }
188 } else {
189 break;
190 }
191 }
192 OP_NOP => ret.push_str("OP_NOP"),
193 OP_IF => ret.push_str("OP_IF"),
194 OP_NOTIF => ret.push_str("OP_NOTIF"),
195 OP_ELSE => ret.push_str("OP_ELSE"),
196 OP_ENDIF => ret.push_str("OP_ENDIF"),
197 OP_VERIFY => ret.push_str("OP_VERIFY"),
198 OP_RETURN => ret.push_str("OP_RETURN"),
199 OP_TOALTSTACK => ret.push_str("OP_TOALTSTACK"),
200 OP_FROMALTSTACK => ret.push_str("OP_FROMALTSTACK"),
201 OP_IFDUP => ret.push_str("OP_IFDUP"),
202 OP_DEPTH => ret.push_str("OP_DEPTH"),
203 OP_DROP => ret.push_str("OP_DROP"),
204 OP_DUP => ret.push_str("OP_DUP"),
205 OP_NIP => ret.push_str("OP_NIP"),
206 OP_OVER => ret.push_str("OP_OVER"),
207 OP_PICK => ret.push_str("OP_PICK"),
208 OP_ROLL => ret.push_str("OP_ROLL"),
209 OP_ROT => ret.push_str("OP_ROT"),
210 OP_SWAP => ret.push_str("OP_SWAP"),
211 OP_TUCK => ret.push_str("OP_TUCK"),
212 OP_2DROP => ret.push_str("OP_2DROP"),
213 OP_2DUP => ret.push_str("OP_2DUP"),
214 OP_3DUP => ret.push_str("OP_3DUP"),
215 OP_2OVER => ret.push_str("OP_2OVER"),
216 OP_2ROT => ret.push_str("OP_2ROT"),
217 OP_2SWAP => ret.push_str("OP_2SWAP"),
218 OP_CAT => ret.push_str("OP_CAT"),
219 OP_SPLIT => ret.push_str("OP_SPLIT"),
220 OP_SIZE => ret.push_str("OP_SIZE"),
221 OP_AND => ret.push_str("OP_AND"),
222 OP_OR => ret.push_str("OP_OR"),
223 OP_XOR => ret.push_str("OP_XOR"),
224 OP_EQUAL => ret.push_str("OP_EQUAL"),
225 OP_EQUALVERIFY => ret.push_str("OP_EQUALVERIFY"),
226 OP_1ADD => ret.push_str("OP_1ADD"),
227 OP_1SUB => ret.push_str("OP_1SUB"),
228 OP_NEGATE => ret.push_str("OP_NEGATE"),
229 OP_ABS => ret.push_str("OP_ABS"),
230 OP_NOT => ret.push_str("OP_NOT"),
231 OP_0NOTEQUAL => ret.push_str("OP_0NOTEQUAL"),
232 OP_ADD => ret.push_str("OP_ADD"),
233 OP_SUB => ret.push_str("OP_SUB"),
234 OP_DIV => ret.push_str("OP_DIV"),
235 OP_MOD => ret.push_str("OP_MOD"),
236 OP_BOOLAND => ret.push_str("OP_BOOLAND"),
237 OP_BOOLOR => ret.push_str("OP_BOOLOR"),
238 OP_NUMEQUAL => ret.push_str("OP_NUMEQUAL"),
239 OP_NUMEQUALVERIFY => ret.push_str("OP_NUMEQUALVERIFY"),
240 OP_NUMNOTEQUAL => ret.push_str("OP_NUMNOTEQUAL"),
241 OP_LESSTHAN => ret.push_str("OP_LESSTHAN"),
242 OP_GREATERTHAN => ret.push_str("OP_GREATERTHAN"),
243 OP_LESSTHANOREQUAL => ret.push_str("OP_LESSTHANOREQUAL"),
244 OP_GREATERTHANOREQUAL => ret.push_str("OP_GREATERTHANOREQUAL"),
245 OP_MIN => ret.push_str("OP_MIN"),
246 OP_MAX => ret.push_str("OP_MAX"),
247 OP_WITHIN => ret.push_str("OP_WITHIN"),
248 OP_NUM2BIN => ret.push_str("OP_NUM2BIN"),
249 OP_BIN2NUM => ret.push_str("OP_BIN2NUM"),
250 OP_RIPEMD160 => ret.push_str("OP_RIPEMD160"),
251 OP_SHA1 => ret.push_str("OP_SHA1"),
252 OP_SHA256 => ret.push_str("OP_SHA256"),
253 OP_HASH160 => ret.push_str("OP_HASH160"),
254 OP_HASH256 => ret.push_str("OP_HASH256"),
255 OP_CODESEPARATOR => ret.push_str("OP_CODESEPARATOR"),
256 OP_CHECKSIG => ret.push_str("OP_CHECKSIG"),
257 OP_CHECKSIGVERIFY => ret.push_str("OP_CHECKSIGVERIFY"),
258 OP_CHECKMULTISIG => ret.push_str("OP_CHECKMULTISIG"),
259 OP_CHECKMULTISIGVERIFY => ret.push_str("OP_CHECKMULTISIGVERIFY"),
260 OP_CHECKLOCKTIMEVERIFY => ret.push_str("OP_CHECKLOCKTIMEVERIFY"),
261 OP_CHECKSEQUENCEVERIFY => ret.push_str("OP_CHECKSEQUENCEVERIFY"),
262 _ => ret.push_str(&format!("{}", script[i])),
263 }
264 i = next_op(i, script);
265 }
266
267 if i < script.len() {
269 for j in i..script.len() {
270 ret.push_str(&format!(" {}", script[j]));
271 }
272 }
273 ret.push_str("]");
274 f.write_str(&ret)
275 }
276}
277
278#[cfg(test)]
279mod tests {
280 use super::op_codes::*;
281 use super::*;
282
283 #[test]
284 fn append_data() {
285 let mut s = Script::new();
286 s.append_data(&vec![]);
287 assert!(s.0.len() == 1);
288
289 let mut s = Script::new();
290 s.append_data(&vec![0; 1]);
291 assert!(s.0[0] == OP_PUSH + 1 && s.0.len() == 2);
292
293 let mut s = Script::new();
294 s.append_data(&vec![0; 75]);
295 assert!(s.0[0] == OP_PUSH + 75 && s.0.len() == 76);
296
297 let mut s = Script::new();
298 s.append_data(&vec![0; 76]);
299 assert!(s.0[0] == OP_PUSHDATA1 && s.0[1] == 76 && s.0.len() == 78);
300
301 let mut s = Script::new();
302 s.append_data(&vec![0; 255]);
303 assert!(s.0[0] == OP_PUSHDATA1 && s.0[1] == 255 && s.0.len() == 257);
304
305 let mut s = Script::new();
306 s.append_data(&vec![0; 256]);
307 assert!(s.0[0] == OP_PUSHDATA2 && s.0[1] == 0 && s.0[2] == 1 && s.0.len() == 259);
308
309 let mut s = Script::new();
310 s.append_data(&vec![0; 65535]);
311 assert!(s.0[0] == OP_PUSHDATA2 && s.0[1] == 255 && s.0[2] == 255 && s.0.len() == 65538);
312
313 let mut s = Script::new();
314 s.append_data(&vec![0; 65536]);
315 assert!(s.0[0] == OP_PUSHDATA4 && s.0[1] == 0 && s.0[2] == 0 && s.0[3] == 1);
316 assert!(s.0.len() == 65541);
317 }
318}