Browse Source

Add calldata_load opcode impl

master
arnaucube 3 years ago
parent
commit
f3d9333f9c
1 changed files with 51 additions and 1 deletions
  1. +51
    -1
      src/lib.rs

+ 51
- 1
src/lib.rs

@ -56,6 +56,11 @@ impl Stack {
s.opcodes = new_opcodes(); s.opcodes = new_opcodes();
s 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]) { fn push(&mut self, b: [u8; 32]) {
self.stack.push(b); self.stack.push(b);
} }
@ -67,6 +72,14 @@ impl Stack {
d[32 - b.len()..].copy_from_slice(&b[..]); d[32 - b.len()..].copy_from_slice(&b[..]);
self.stack.push(d); 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] { fn pop(&mut self) -> [u8; 32] {
match self.stack.pop() { match self.stack.pop() {
Some(x) => return x, Some(x) => return x,
@ -84,6 +97,17 @@ impl Stack {
panic!("invalid opcode {:x}", 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 { match opcode & 0xf0 {
0x00 => { 0x00 => {
// arithmetic // arithmetic
@ -106,6 +130,15 @@ impl Stack {
} }
self.pc += 1; self.pc += 1;
} }
0x30 => {
match opcode {
0x35 => {
self.calldata_load(&calldata);
}
_ => panic!("unimplemented {:x}", opcode),
}
self.pc += 1;
}
0x50 => { 0x50 => {
self.pc += 1; self.pc += 1;
match opcode { match opcode {
@ -201,7 +234,10 @@ impl Stack {
// crypto // crypto
// contract context // 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 // blockchain context
@ -415,4 +451,18 @@ mod tests {
assert_eq!(s.pc, 7); assert_eq!(s.pc, 7);
assert_eq!(s.pop(), str_to_u256("515")); 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"));
}
} }

Loading…
Cancel
Save