|
1 | 1 | extern crate bimap; |
| 2 | +extern crate sha2; |
| 3 | +extern crate ripemd160; |
| 4 | +extern crate digest; |
2 | 5 |
|
3 | 6 | //use std::io; |
| 7 | +use std::mem; |
4 | 8 | use bimap::BiMap; |
| 9 | +use digest::Digest; |
| 10 | +use sha2::Sha256; |
| 11 | +use ripemd160::Ripemd160; |
5 | 12 |
|
6 | 13 | struct Compiler { |
7 | 14 | opcode_list: BiMap<&'static str, i32>, |
@@ -35,6 +42,7 @@ impl Compiler { |
35 | 42 | opcode_list.insert("OP_NOTIF", 0x64); |
36 | 43 | opcode_list.insert("OP_ELSE", 0x67); |
37 | 44 | opcode_list.insert("OP_ENDIF", 0x68); |
| 45 | + opcode_list.insert("OP_HASH160", 0xa9); |
38 | 46 |
|
39 | 47 | let mut opcode_alias_list: BiMap<&'static str, &'static str> = BiMap::new(); |
40 | 48 | opcode_alias_list.insert("OP_FALSE", "OP_0"); |
@@ -148,6 +156,7 @@ impl<'borrow_code_lifetime> VM<'borrow_code_lifetime> { |
148 | 156 | else if self.codes[self.pc] == compiler.compile_single("OP_IF") { self.op_if(); } |
149 | 157 | else if self.codes[self.pc] == compiler.compile_single("OP_ENDIF") { return 1; } |
150 | 158 | else if self.codes[self.pc] == compiler.compile_single("OP_ELSE") { return 1; } |
| 159 | + else if self.codes[self.pc] == compiler.compile_single("OP_HASH160") { self.op_hash160(); } |
151 | 160 | else { panic!("[VM] The opcode {:#x} is not implemented yet,", self.codes[self.pc]); } |
152 | 161 |
|
153 | 162 | return 0; |
@@ -211,6 +220,17 @@ impl<'borrow_code_lifetime> VM<'borrow_code_lifetime> { |
211 | 220 |
|
212 | 221 | //panic!("debug"); |
213 | 222 | } |
| 223 | + fn op_hash160(&mut self){ |
| 224 | + |
| 225 | + let value = self.stack.pop().unwrap(); |
| 226 | + |
| 227 | + let sha256hash = Sha256::digest(&value.to_be_bytes()); |
| 228 | + let ripemd160hash = Ripemd160::digest(sha256hash.as_slice()).as_ref(); |
| 229 | + |
| 230 | + let value = mem::transmute::<[u8; 12], i32>(ripemd160hash); |
| 231 | + |
| 232 | + self.stack.push(ripemd160hash.as_ref()); |
| 233 | + } |
214 | 234 | } |
215 | 235 |
|
216 | 236 | fn main() { |
|
0 commit comments