arnaucube
arnaucube/evm-rsPublic Self-hosted repository
Add calldata_load opcode impl
arnaucube root@arnaucube.com
Sat, 11 Sep 2021 23:12:52 +0200
commit

f3d9333f9cd7d38a06ca5f2ebfd18b65349a3164

parent

e4a3b10f48f102bf5c1e71c65e08c139e50c76ea

1 files changed, 51 insertions(+), 1 deletions(-)

jump to
M src/lib.rs → src/lib.rs

@@ -56,6 +56,11 @@ };

s.opcodes = new_opcodes(); s } + fn print_stack(&self) { + for i in (0..self.stack.len()).rev() { + println!("{:x?}", &self.stack[i][28..]); + } + } fn push(&mut self, b: [u8; 32]) { self.stack.push(b); }

@@ -67,6 +72,14 @@ let mut d: [u8; 32] = [0; 32];

d[32 - b.len()..].copy_from_slice(&b[..]); self.stack.push(d); } + // put_arbitrary puts in the last element of the stack the value + fn put_arbitrary(&mut self, b: &[u8]) { + // TODO if b.len()>32 return error + let mut d: [u8; 32] = [0; 32]; + d[32 - b.len()..].copy_from_slice(&b[..]); + let l = self.stack.len(); + self.stack[l - 1] = d; + } fn pop(&mut self) -> [u8; 32] { match self.stack.pop() { Some(x) => return x,

@@ -84,6 +97,17 @@ if !self.opcodes.contains_key(&opcode) {

panic!("invalid opcode {:x}", opcode); } + if debug { + println!( + "{:?} (0x{:x}): pc={:?} gas={:?}\nstack:", + self.opcodes.get(&opcode).unwrap().name, + opcode, + self.pc, + self.gas, + ); + self.print_stack(); + println!(""); + } match opcode & 0xf0 { 0x00 => { // arithmetic

@@ -102,6 +126,15 @@ 0x08 => self.add_mod(),

0x09 => self.mul_mod(), 0x0a => self.exp(), // 0x0b => self.sign_extend(), + _ => panic!("unimplemented {:x}", opcode), + } + self.pc += 1; + } + 0x30 => { + match opcode { + 0x35 => { + self.calldata_load(&calldata); + } _ => panic!("unimplemented {:x}", opcode), } self.pc += 1;

@@ -201,7 +234,10 @@ // boolean

// crypto // contract context - fn calldata_load(&mut self, calldata: &[u8]) {} + fn calldata_load(&mut self, calldata: &[u8]) { + self.put_arbitrary(&calldata[self.calldata_i..self.calldata_i + 32]); + self.calldata_i += 32; + } // blockchain context

@@ -414,5 +450,19 @@ // assert_eq!(out[0], 0x09);

assert_eq!(s.gas, 9999999991); assert_eq!(s.pc, 7); assert_eq!(s.pop(), str_to_u256("515")); + } + + #[test] + fn execute_opcodes_3() { + // contains calldata + let code = hex::decode("60003560203501").unwrap(); + let calldata = hex::decode("00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000004").unwrap(); + + let mut s = Stack::new(); + s.execute(&code, &calldata, false); + + assert_eq!(s.gas, 9999999985); + assert_eq!(s.pc, 7); + assert_eq!(s.pop(), str_to_u256("9")); } }