Adding some more methods
This commit is contained in:
		
							parent
							
								
									0733214059
								
							
						
					
					
						commit
						5c79b1b84b
					
				| @ -99,75 +99,136 @@ pub const	GAS: Instruction =  0x5a; //< get the amount of available gas | ||||
| pub const	JUMPDEST: Instruction =  0x5b; //< set a potential jump destination
 | ||||
| 
 | ||||
| pub const	PUSH1: Instruction =  0x60;		//< place 1 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH2: Instruction =  0x61; //< place 2 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH3: Instruction =  0x62; //< place 3 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH4: Instruction =  0x63; //< place 4 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH5: Instruction =  0x64; //< place 5 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH6: Instruction =  0x65; //< place 6 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH7: Instruction =  0x66; //< place 7 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH8: Instruction =  0x67; //< place 8 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH9: Instruction =  0x68; //< place 9 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH10: Instruction =  0x69; //< place 10 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH11: Instruction =  0x6a; //< place 11 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH12: Instruction =  0x6b; //< place 12 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH13: Instruction =  0x6c; //< place 13 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH14: Instruction =  0x6d; //< place 14 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH15: Instruction =  0x6e; //< place 15 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH16: Instruction =  0x6f; //< place 16 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH17: Instruction =  0x70; //< place 17 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH18: Instruction =  0x71; //< place 18 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH19: Instruction =  0x72; //< place 19 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH20: Instruction =  0x73; //< place 20 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH21: Instruction =  0x74; //< place 21 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH22: Instruction =  0x75; //< place 22 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH23: Instruction =  0x76; //< place 23 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH24: Instruction =  0x77; //< place 24 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH25: Instruction =  0x78; //< place 25 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH26: Instruction =  0x79; //< place 26 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH27: Instruction =  0x7a; //< place 27 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH28: Instruction =  0x7b; //< place 28 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH29: Instruction =  0x7c; //< place 29 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH30: Instruction =  0x7d; //< place 30 byte item on stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	PUSH31: Instruction =  0x7e; //< place 31 byte item on stack
 | ||||
| pub const	PUSH32: Instruction =  0x7f; //< place 32 byte item on stack
 | ||||
| 
 | ||||
| pub const	DUP1: Instruction =  0x80;		//< copies the highest item in the stack to the top of the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	DUP2: Instruction =  0x81; //< copies the second highest item in the stack to the top of the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	DUP3: Instruction =  0x82; //< copies the third highest item in the stack to the top of the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	DUP4: Instruction =  0x83; //< copies the 4th highest item in the stack to the top of the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	DUP5: Instruction =  0x84; //< copies the 5th highest item in the stack to the top of the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	DUP6: Instruction =  0x85; //< copies the 6th highest item in the stack to the top of the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	DUP7: Instruction =  0x86; //< copies the 7th highest item in the stack to the top of the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	DUP8: Instruction =  0x87; //< copies the 8th highest item in the stack to the top of the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	DUP9: Instruction =  0x88; //< copies the 9th highest item in the stack to the top of the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	DUP10: Instruction =  0x89; //< copies the 10th highest item in the stack to the top of the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	DUP11: Instruction =  0x8a; //< copies the 11th highest item in the stack to the top of the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	DUP12: Instruction =  0x8b; //< copies the 12th highest item in the stack to the top of the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	DUP13: Instruction =  0x8c; //< copies the 13th highest item in the stack to the top of the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	DUP14: Instruction =  0x8d; //< copies the 14th highest item in the stack to the top of the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	DUP15: Instruction =  0x8e; //< copies the 15th highest item in the stack to the top of the stack
 | ||||
| pub const	DUP16: Instruction =  0x8f; //< copies the 16th highest item in the stack to the top of the stack
 | ||||
| 
 | ||||
| pub const	SWAP1: Instruction =  0x90;		//< swaps the highest and second highest value on the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	SWAP2: Instruction =  0x91; //< swaps the highest and third highest value on the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	SWAP3: Instruction =  0x92; //< swaps the highest and 4th highest value on the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	SWAP4: Instruction =  0x93; //< swaps the highest and 5th highest value on the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	SWAP5: Instruction =  0x94; //< swaps the highest and 6th highest value on the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	SWAP6: Instruction =  0x95; //< swaps the highest and 7th highest value on the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	SWAP7: Instruction =  0x96; //< swaps the highest and 8th highest value on the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	SWAP8: Instruction =  0x97; //< swaps the highest and 9th highest value on the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	SWAP9: Instruction =  0x98; //< swaps the highest and 10th highest value on the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	SWAP10: Instruction =  0x99; //< swaps the highest and 11th highest value on the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	SWAP11: Instruction =  0x9a; //< swaps the highest and 12th highest value on the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	SWAP12: Instruction =  0x9b; //< swaps the highest and 13th highest value on the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	SWAP13: Instruction =  0x9c; //< swaps the highest and 14th highest value on the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	SWAP14: Instruction =  0x9d; //< swaps the highest and 15th highest value on the stack
 | ||||
| #[allow(dead_code)] | ||||
| pub const	SWAP15: Instruction =  0x9e; //< swaps the highest and 16th highest value on the stack
 | ||||
| pub const	SWAP16: Instruction =  0x9f; //< swaps the highest and 17th highest value on the stack
 | ||||
| 
 | ||||
| pub const	LOG0: Instruction =  0xa0;		//< Makes a log entry; no topics.
 | ||||
| #[allow(dead_code)] | ||||
| pub const	LOG1: Instruction =  0xa1; //< Makes a log entry; 1 topic.
 | ||||
| #[allow(dead_code)] | ||||
| pub const	LOG2: Instruction =  0xa2; //< Makes a log entry; 2 topics.
 | ||||
| #[allow(dead_code)] | ||||
| pub const	LOG3: Instruction =  0xa3; //< Makes a log entry; 3 topics.
 | ||||
| pub const	LOG4: Instruction =  0xa4; //< Makes a log entry; 4 topics.
 | ||||
| 
 | ||||
|  | ||||
| @ -73,6 +73,11 @@ impl<'a> CodeReader<'a> { | ||||
| 		U256::zero() | ||||
| 	} | ||||
| 
 | ||||
| 	fn len (&self) -> usize { | ||||
| 		self.code.len() | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO [todr] All get_slice should operate on memory not code!!!
 | ||||
| 	/// Retrieve part of the code described by offset and size
 | ||||
| 	fn get_slice(&self, init_off_u: U256, init_size_u: U256) -> &[u8] { | ||||
| 		let init_off = init_off_u.low_u64() as usize; | ||||
| @ -161,7 +166,7 @@ impl Interpreter { | ||||
| 				// TODO [todr] Fix u64 for gasLeft
 | ||||
| 				let (gas_left, maybe_address) = try!(ext.create(gas.low_u64(), &endowment, &contract_code)); | ||||
| 				match maybe_address { | ||||
| 					Some(address) => stack.push(U256::from(address)), | ||||
| 					Some(address) => stack.push(address_to_u256(address)), | ||||
| 					None => stack.push(U256::zero()) | ||||
| 				} | ||||
| 				Ok(U256::from(gas_left)) | ||||
| @ -206,6 +211,7 @@ impl Interpreter { | ||||
| 			instructions::PUSH1...instructions::PUSH32 => { | ||||
| 				// Load to stack
 | ||||
| 				let bytes = instructions::get_push_bytes(instruction); | ||||
| 				// TODO [todr] move positions management outside of CodeReader
 | ||||
| 				let val = code.read(bytes); | ||||
| 				stack.push(val); | ||||
| 				Ok(gas) | ||||
| @ -226,6 +232,13 @@ impl Interpreter { | ||||
| 				// Size of memry to stack
 | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			instructions::SHA3 => { | ||||
| 				let offset = stack.pop_back(); | ||||
| 				let size = stack.pop_back(); | ||||
| 				let sha3 = code.get_slice(offset, size).sha3(); | ||||
| 				stack.push(U256::from(sha3.as_slice())); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			instructions::SLOAD => { | ||||
| 				let key = H256::from(&stack.pop_back()); | ||||
| 				let word = U256::from(ext.sload(&key).as_slice()); | ||||
| @ -246,6 +259,79 @@ impl Interpreter { | ||||
| 				stack.push(U256::from(gas)); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			instructions::ADDRESS => { | ||||
| 				stack.push(address_to_u256(params.address.clone())); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			instructions::ORIGIN => { | ||||
| 				stack.push(address_to_u256(params.origin.clone())); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			instructions::BALANCE => { | ||||
| 				let address = u256_to_address(&stack.pop_back()); | ||||
| 				let balance = ext.balance(&address); | ||||
| 				stack.push(balance); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			instructions::CALLER => { | ||||
| 				stack.push(address_to_u256(params.sender.clone())); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			instructions::CALLVALUE => { | ||||
| 				stack.push(params.value.clone()); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			// instructions::CALLDATALOAD
 | ||||
| 			instructions::CALLDATASIZE => { | ||||
| 				stack.push(U256::from(params.data.len())); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			instructions::CODESIZE => { | ||||
| 				stack.push(U256::from(code.len())); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			instructions::EXTCODESIZE => { | ||||
| 				let address = u256_to_address(&stack.pop_back()); | ||||
| 				let len = ext.extcode(&address).len(); | ||||
| 				stack.push(U256::from(len)); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			// instructions::CALLDATACOPY => {},
 | ||||
| 			// instructions::CODECOPY => {},
 | ||||
| 			// instructions::EXTCODECOPY => {
 | ||||
| 			// 	let address = u256_to_addres(&stack.pop_back());
 | ||||
| 			// 	let code = ext.extcode(address);
 | ||||
| 			// },
 | ||||
| 			instructions::GASPRICE => { | ||||
| 				stack.push(params.gas_price.clone()); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			instructions::BLOCKHASH => { | ||||
| 				let block_number = stack.pop_back(); | ||||
| 				let block_hash = ext.blockhash(&block_number); | ||||
| 				stack.push(U256::from(block_hash.as_slice())); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			instructions::COINBASE => { | ||||
| 				stack.push(address_to_u256(ext.env_info().author.clone())); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			instructions::TIMESTAMP => { | ||||
| 				stack.push(U256::from(ext.env_info().timestamp)); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			instructions::NUMBER => { | ||||
| 				stack.push(U256::from(ext.env_info().number)); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			instructions::DIFFICULTY => { | ||||
| 				stack.push(ext.env_info().difficulty.clone()); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			instructions::GASLIMIT => { | ||||
| 				stack.push(ext.env_info().gas_limit.clone()); | ||||
| 				Ok(gas) | ||||
| 			}, | ||||
| 			_ => { | ||||
| 				self.exec_stack_instruction(instruction, stack); | ||||
| 				Ok(gas) | ||||
| @ -267,6 +353,14 @@ impl Interpreter { | ||||
| 		U256::zero() == val | ||||
| 	} | ||||
| 
 | ||||
| 	fn bool_to_u256(&self, val: bool) -> U256 { | ||||
| 		if val { | ||||
| 			U256::one() | ||||
| 		} else { | ||||
| 			U256::zero() | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fn exec_stack_instruction(&self, instruction: Instruction, stack : &mut Stack<U256>) { | ||||
| 		match instruction { | ||||
| 			instructions::DUP1...instructions::DUP16 => { | ||||
| @ -278,11 +372,89 @@ impl Interpreter { | ||||
| 				let position = instructions::get_swap_position(instruction); | ||||
| 				stack.swap_with_top(position) | ||||
| 			}, | ||||
| 			instructions::POP => { | ||||
| 				stack.pop_back(); | ||||
| 			}, | ||||
| 			instructions::ADD => { | ||||
| 				let a = stack.pop_back(); | ||||
| 				let b = stack.pop_back(); | ||||
| 				stack.push(a + b); | ||||
| 			}, | ||||
| 			instructions::MUL => { | ||||
| 				let a = stack.pop_back(); | ||||
| 				let b = stack.pop_back(); | ||||
| 				stack.push(a * b); | ||||
| 			}, | ||||
| 			instructions::SUB => { | ||||
| 				let a = stack.pop_back(); | ||||
| 				let b = stack.pop_back(); | ||||
| 				stack.push(a - b); | ||||
| 			}, | ||||
| 			instructions::DIV => { | ||||
| 				let a = stack.pop_back(); | ||||
| 				let b = stack.pop_back(); | ||||
| 				stack.push(if self.is_zero(b) { | ||||
| 					a / b 
 | ||||
| 				} else { | ||||
| 					U256::zero() | ||||
| 				}); | ||||
| 			}, | ||||
| 			instructions::MOD => { | ||||
| 				let a = stack.pop_back(); | ||||
| 				let b = stack.pop_back(); | ||||
| 				stack.push(if self.is_zero(b) { | ||||
| 					a % b 
 | ||||
| 				} else { | ||||
| 					U256::zero() | ||||
| 				}); | ||||
| 			}, | ||||
| 			// instructions::SDIV => {},
 | ||||
| 			// instructions::SMOD => {},
 | ||||
| 			// instructions::EXP => {},
 | ||||
| 			instructions::NOT => { | ||||
| 				let a = stack.pop_back(); | ||||
| 				stack.push(!a); | ||||
| 			}, | ||||
| 			instructions::LT => { | ||||
| 				let a = stack.pop_back(); | ||||
| 				let b = stack.pop_back(); | ||||
| 				stack.push(self.bool_to_u256(a < b)); | ||||
| 			}, | ||||
| 			// instructions::SLT => {},
 | ||||
| 			instructions::GT => { | ||||
| 				let a = stack.pop_back(); | ||||
| 				let b = stack.pop_back(); | ||||
| 				stack.push(self.bool_to_u256(a > b)); | ||||
| 			}, | ||||
| 			// instructions::SGT => {},
 | ||||
| 			instructions::EQ => { | ||||
| 				let a = stack.pop_back(); | ||||
| 				let b = stack.pop_back(); | ||||
| 				stack.push(self.bool_to_u256(a == b)); | ||||
| 			}, | ||||
| 			instructions::ISZERO => { | ||||
| 				let a = stack.pop_back(); | ||||
| 				stack.push(self.bool_to_u256(self.is_zero(a))); | ||||
| 			}, | ||||
| 			instructions::AND => { | ||||
| 				let a = stack.pop_back(); | ||||
| 				let b = stack.pop_back(); | ||||
| 				stack.push(a & b); | ||||
| 			}, | ||||
| 			instructions::OR => { | ||||
| 				let a = stack.pop_back(); | ||||
| 				let b = stack.pop_back(); | ||||
| 				stack.push(a | b); | ||||
| 			}, | ||||
| 			instructions::XOR => { | ||||
| 				let a = stack.pop_back(); | ||||
| 				let b = stack.pop_back(); | ||||
| 				stack.push(a ^ b); | ||||
| 			}, | ||||
| 			// instructions::BYTE => {},
 | ||||
| 			// instructions::ADDMOD => {},
 | ||||
| 			// instructions::MULMOD => {},
 | ||||
| 			// instructions::SIGNEXTEND => {},
 | ||||
| 			_ => panic!(format!("Unknown stack instruction: {:x}", instruction)) | ||||
| 		} | ||||
|   } | ||||
| @ -304,6 +476,15 @@ impl Interpreter { | ||||
| 
 | ||||
|     return jump_dests; | ||||
|   } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| fn u256_to_address(value: &U256) -> Address { | ||||
| 	Address::from(H256::from(value)) | ||||
| } | ||||
| 
 | ||||
| fn address_to_u256(value: Address) -> U256 { | ||||
| 	U256::from(H256::from(value).as_slice()) | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user