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