1 /* EVMC: Ethereum Client-VM Connector API. 2 * Copyright 2019 The EVMC Authors. 3 * Licensed under the Apache License, Version 2.0. 4 */ 5 6 use evmc_declare::evmc_declare_vm; 7 use evmc_vm::*; 8 9 #[evmc_declare_vm("ExampleRustVM", "evm, precompiles", "6.3.0-dev")] 10 pub struct ExampleRustVM; 11 12 impl EvmcVm for ExampleRustVM { init() -> Self13 fn init() -> Self { 14 ExampleRustVM {} 15 } 16 execute<'a>( &self, _revision: Revision, _code: &'a [u8], message: &'a ExecutionMessage, _context: Option<&'a mut ExecutionContext<'a>>, ) -> ExecutionResult17 fn execute<'a>( 18 &self, 19 _revision: Revision, 20 _code: &'a [u8], 21 message: &'a ExecutionMessage, 22 _context: Option<&'a mut ExecutionContext<'a>>, 23 ) -> ExecutionResult { 24 if _context.is_none() { 25 return ExecutionResult::failure(); 26 } 27 let _context = _context.unwrap(); 28 29 if message.kind() != MessageKind::EVMC_CALL { 30 return ExecutionResult::failure(); 31 } 32 33 if _code.len() == 0 { 34 return ExecutionResult::failure(); 35 } 36 37 let tx_context = _context.get_tx_context().clone(); 38 39 let save_return_block_number: Vec<u8> = vec![ 40 0x43, 0x60, 0x00, 0x55, 0x43, 0x60, 0x00, 0x52, 0x59, 0x60, 0x00, 0xf3, 41 ]; 42 43 if save_return_block_number != _code { 44 return ExecutionResult::failure(); 45 } 46 47 assert!(tx_context.block_number <= 255); 48 let block_number = tx_context.block_number as u8; 49 50 let storage_key = Bytes32::default(); 51 let mut storage_value = Bytes32::default(); 52 storage_value.bytes[31] = block_number; 53 _context.set_storage(&message.destination(), &storage_key, &storage_value); 54 55 let ret = format!("{}", block_number).into_bytes(); 56 ExecutionResult::success(message.gas() / 2, Some(&ret)) 57 } 58 } 59