Skip to content
This repository was archived by the owner on Nov 17, 2025. It is now read-only.

Commit 2f7a083

Browse files
authored
Merge pull request #343 from ethereum/rust-types
rust: add type aliases for Address, Bytes32, Uint256
2 parents 2a5c280 + d83c193 commit 2f7a083

File tree

2 files changed

+94
-69
lines changed

2 files changed

+94
-69
lines changed

bindings/rust/evmc-vm/src/lib.rs

Lines changed: 57 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
//! This crate documents how to use certain data types.
1010
1111
mod container;
12+
mod types;
1213

1314
pub use container::EvmcContainer;
1415
pub use evmc_sys as ffi;
16+
pub use types::*;
1517

1618
pub trait EvmcVm {
1719
fn init() -> Self;
@@ -23,7 +25,7 @@ pub struct ExecutionResult {
2325
status_code: ffi::evmc_status_code,
2426
gas_left: i64,
2527
output: Option<Vec<u8>>,
26-
create_address: Option<ffi::evmc_address>,
28+
create_address: Option<Address>,
2729
}
2830

2931
/// EVMC execution message structure.
@@ -32,11 +34,11 @@ pub struct ExecutionMessage {
3234
flags: u32,
3335
depth: i32,
3436
gas: i64,
35-
destination: ffi::evmc_address,
36-
sender: ffi::evmc_address,
37+
destination: Address,
38+
sender: Address,
3739
input: Option<Vec<u8>>,
38-
value: ffi::evmc_uint256be,
39-
create2_salt: ffi::evmc_bytes32,
40+
value: Uint256,
41+
create2_salt: Bytes32,
4042
}
4143

4244
/// EVMC context structure. Exposes the EVMC host functions, message data, and transaction context
@@ -85,7 +87,7 @@ impl ExecutionResult {
8587
self.output.as_ref()
8688
}
8789

88-
pub fn get_create_address(&self) -> Option<&ffi::evmc_address> {
90+
pub fn get_create_address(&self) -> Option<&Address> {
8991
self.create_address.as_ref()
9092
}
9193
}
@@ -107,23 +109,23 @@ impl ExecutionMessage {
107109
self.gas
108110
}
109111

110-
pub fn destination(&self) -> &ffi::evmc_address {
112+
pub fn destination(&self) -> &Address {
111113
&self.destination
112114
}
113115

114-
pub fn sender(&self) -> &ffi::evmc_address {
116+
pub fn sender(&self) -> &Address {
115117
&self.sender
116118
}
117119

118120
pub fn input(&self) -> Option<&Vec<u8>> {
119121
self.input.as_ref()
120122
}
121123

122-
pub fn value(&self) -> &ffi::evmc_uint256be {
124+
pub fn value(&self) -> &Uint256 {
123125
&self.value
124126
}
125127

126-
pub fn create2_salt(&self) -> &ffi::evmc_bytes32 {
128+
pub fn create2_salt(&self) -> &Bytes32 {
127129
&self.create2_salt
128130
}
129131
}
@@ -150,89 +152,80 @@ impl<'a> ExecutionContext<'a> {
150152
&self.tx_context
151153
}
152154

153-
pub fn account_exists(&mut self, address: &ffi::evmc_address) -> bool {
155+
pub fn account_exists(&mut self, address: &Address) -> bool {
154156
unsafe {
155157
assert!((*self.context.host).account_exists.is_some());
156158
(*self.context.host).account_exists.unwrap()(
157159
self.context as *mut ffi::evmc_context,
158-
address as *const ffi::evmc_address,
160+
address as *const Address,
159161
)
160162
}
161163
}
162164

163-
pub fn get_storage(
164-
&mut self,
165-
address: &ffi::evmc_address,
166-
key: &ffi::evmc_bytes32,
167-
) -> ffi::evmc_bytes32 {
165+
pub fn get_storage(&mut self, address: &Address, key: &Bytes32) -> Bytes32 {
168166
unsafe {
169167
assert!((*self.context.host).get_storage.is_some());
170168
(*self.context.host).get_storage.unwrap()(
171169
self.context as *mut ffi::evmc_context,
172-
address as *const ffi::evmc_address,
173-
key as *const ffi::evmc_bytes32,
170+
address as *const Address,
171+
key as *const Bytes32,
174172
)
175173
}
176174
}
177175

178176
pub fn set_storage(
179177
&mut self,
180-
address: &ffi::evmc_address,
181-
key: &ffi::evmc_bytes32,
182-
value: &ffi::evmc_bytes32,
178+
address: &Address,
179+
key: &Bytes32,
180+
value: &Bytes32,
183181
) -> ffi::evmc_storage_status {
184182
unsafe {
185183
assert!((*self.context.host).set_storage.is_some());
186184
(*self.context.host).set_storage.unwrap()(
187185
self.context as *mut ffi::evmc_context,
188-
address as *const ffi::evmc_address,
189-
key as *const ffi::evmc_bytes32,
190-
value as *const ffi::evmc_bytes32,
186+
address as *const Address,
187+
key as *const Bytes32,
188+
value as *const Bytes32,
191189
)
192190
}
193191
}
194192

195-
pub fn get_balance(&mut self, address: &ffi::evmc_address) -> ffi::evmc_bytes32 {
193+
pub fn get_balance(&mut self, address: &Address) -> Uint256 {
196194
unsafe {
197195
assert!((*self.context.host).get_balance.is_some());
198196
(*self.context.host).get_balance.unwrap()(
199197
self.context as *mut ffi::evmc_context,
200-
address as *const ffi::evmc_address,
198+
address as *const Address,
201199
)
202200
}
203201
}
204202

205-
pub fn get_code_size(&mut self, address: &ffi::evmc_address) -> usize {
203+
pub fn get_code_size(&mut self, address: &Address) -> usize {
206204
unsafe {
207205
assert!((*self.context.host).get_code_size.is_some());
208206
(*self.context.host).get_code_size.unwrap()(
209207
self.context as *mut ffi::evmc_context,
210-
address as *const ffi::evmc_address,
208+
address as *const Address,
211209
)
212210
}
213211
}
214212

215-
pub fn get_code_hash(&mut self, address: &ffi::evmc_address) -> ffi::evmc_bytes32 {
213+
pub fn get_code_hash(&mut self, address: &Address) -> Bytes32 {
216214
unsafe {
217215
assert!((*self.context.host).get_code_size.is_some());
218216
(*self.context.host).get_code_hash.unwrap()(
219217
self.context as *mut ffi::evmc_context,
220-
address as *const ffi::evmc_address,
218+
address as *const Address,
221219
)
222220
}
223221
}
224222

225-
pub fn copy_code(
226-
&mut self,
227-
address: &ffi::evmc_address,
228-
code_offset: usize,
229-
buffer: &mut [u8],
230-
) -> usize {
223+
pub fn copy_code(&mut self, address: &Address, code_offset: usize, buffer: &mut [u8]) -> usize {
231224
unsafe {
232225
assert!((*self.context.host).copy_code.is_some());
233226
(*self.context.host).copy_code.unwrap()(
234227
self.context as *mut ffi::evmc_context,
235-
address as *const ffi::evmc_address,
228+
address as *const Address,
236229
code_offset,
237230
// FIXME: ensure that alignment of the array elements is OK
238231
buffer.as_mut_ptr(),
@@ -241,13 +234,13 @@ impl<'a> ExecutionContext<'a> {
241234
}
242235
}
243236

244-
pub fn selfdestruct(&mut self, address: &ffi::evmc_address, beneficiary: &ffi::evmc_address) {
237+
pub fn selfdestruct(&mut self, address: &Address, beneficiary: &Address) {
245238
unsafe {
246239
assert!((*self.context.host).selfdestruct.is_some());
247240
(*self.context.host).selfdestruct.unwrap()(
248241
self.context as *mut ffi::evmc_context,
249-
address as *const ffi::evmc_address,
250-
beneficiary as *const ffi::evmc_address,
242+
address as *const Address,
243+
beneficiary as *const Address,
251244
)
252245
}
253246
}
@@ -263,7 +256,7 @@ impl<'a> ExecutionContext<'a> {
263256
}
264257
}
265258

266-
pub fn get_block_hash(&mut self, num: i64) -> ffi::evmc_bytes32 {
259+
pub fn get_block_hash(&mut self, num: i64) -> Bytes32 {
267260
unsafe {
268261
assert!((*self.context.host).get_block_hash.is_some());
269262
(*self.context.host).get_block_hash.unwrap()(
@@ -273,17 +266,12 @@ impl<'a> ExecutionContext<'a> {
273266
}
274267
}
275268

276-
pub fn emit_log(
277-
&mut self,
278-
address: &ffi::evmc_address,
279-
data: &[u8],
280-
topics: &[ffi::evmc_bytes32],
281-
) {
269+
pub fn emit_log(&mut self, address: &Address, data: &[u8], topics: &[Bytes32]) {
282270
unsafe {
283271
assert!((*self.context.host).emit_log.is_some());
284272
(*self.context.host).emit_log.unwrap()(
285273
self.context as *mut ffi::evmc_context,
286-
address as *const ffi::evmc_address,
274+
address as *const Address,
287275
// FIXME: ensure that alignment of the array elements is OK
288276
data.as_ptr(),
289277
data.len(),
@@ -384,7 +372,7 @@ impl Into<ffi::evmc_result> for ExecutionResult {
384372
create_address: if self.create_address.is_some() {
385373
self.create_address.unwrap()
386374
} else {
387-
ffi::evmc_address { bytes: [0u8; 20] }
375+
Address { bytes: [0u8; 20] }
388376
},
389377
padding: [0u8; 4],
390378
}
@@ -468,7 +456,7 @@ mod tests {
468456
output_data: Box::into_raw(Box::new([0xde, 0xad, 0xbe, 0xef])) as *const u8,
469457
output_size: 4,
470458
release: Some(test_result_dispose),
471-
create_address: ffi::evmc_address { bytes: [0u8; 20] },
459+
create_address: Address { bytes: [0u8; 20] },
472460
padding: [0u8; 4],
473461
};
474462

@@ -569,10 +557,10 @@ mod tests {
569557

570558
#[test]
571559
fn message_from_ffi() {
572-
let destination = ffi::evmc_address { bytes: [32u8; 20] };
573-
let sender = ffi::evmc_address { bytes: [128u8; 20] };
574-
let value = ffi::evmc_uint256be { bytes: [0u8; 32] };
575-
let create2_salt = ffi::evmc_bytes32 { bytes: [255u8; 32] };
560+
let destination = Address { bytes: [32u8; 20] };
561+
let sender = Address { bytes: [128u8; 20] };
562+
let value = Uint256 { bytes: [0u8; 32] };
563+
let create2_salt = Bytes32 { bytes: [255u8; 32] };
576564

577565
let msg = ffi::evmc_message {
578566
kind: ffi::evmc_call_kind::EVMC_CALL,
@@ -603,10 +591,10 @@ mod tests {
603591
#[test]
604592
fn message_from_ffi_with_input() {
605593
let input = vec![0xc0, 0xff, 0xee];
606-
let destination = ffi::evmc_address { bytes: [32u8; 20] };
607-
let sender = ffi::evmc_address { bytes: [128u8; 20] };
608-
let value = ffi::evmc_uint256be { bytes: [0u8; 32] };
609-
let create2_salt = ffi::evmc_bytes32 { bytes: [255u8; 32] };
594+
let destination = Address { bytes: [32u8; 20] };
595+
let sender = Address { bytes: [128u8; 20] };
596+
let value = Uint256 { bytes: [0u8; 32] };
597+
let create2_salt = Bytes32 { bytes: [255u8; 32] };
610598

611599
let msg = ffi::evmc_message {
612600
kind: ffi::evmc_call_kind::EVMC_CALL,
@@ -639,19 +627,19 @@ mod tests {
639627
_context: *mut ffi::evmc_context,
640628
) -> ffi::evmc_tx_context {
641629
ffi::evmc_tx_context {
642-
tx_gas_price: ffi::evmc_uint256be { bytes: [0u8; 32] },
643-
tx_origin: ffi::evmc_address { bytes: [0u8; 20] },
644-
block_coinbase: ffi::evmc_address { bytes: [0u8; 20] },
630+
tx_gas_price: Uint256 { bytes: [0u8; 32] },
631+
tx_origin: Address { bytes: [0u8; 20] },
632+
block_coinbase: Address { bytes: [0u8; 20] },
645633
block_number: 42,
646634
block_timestamp: 235117,
647635
block_gas_limit: 105023,
648-
block_difficulty: ffi::evmc_uint256be { bytes: [0xaa; 32] },
636+
block_difficulty: Uint256 { bytes: [0xaa; 32] },
649637
}
650638
}
651639

652640
unsafe extern "C" fn get_dummy_code_size(
653641
_context: *mut ffi::evmc_context,
654-
_addr: *const ffi::evmc_address,
642+
_addr: *const Address,
655643
) -> usize {
656644
105023 as usize
657645
}
@@ -690,12 +678,12 @@ mod tests {
690678
flags: 0,
691679
depth: 123,
692680
gas: 105023,
693-
destination: ffi::evmc_address { bytes: [0u8; 20] },
694-
sender: ffi::evmc_address { bytes: [0u8; 20] },
681+
destination: Address { bytes: [0u8; 20] },
682+
sender: Address { bytes: [0u8; 20] },
695683
input_data: std::ptr::null() as *const u8,
696684
input_size: 0,
697-
value: ffi::evmc_uint256be { bytes: [0u8; 32] },
698-
create2_salt: ffi::evmc_uint256be { bytes: [0u8; 32] },
685+
value: Uint256 { bytes: [0u8; 32] },
686+
create2_salt: Uint256 { bytes: [0u8; 32] },
699687
}
700688
}
701689

@@ -738,7 +726,7 @@ mod tests {
738726
let msg = get_dummy_message();
739727

740728
// This address is useless. Just a dummy parameter for the interface function.
741-
let test_addr = ffi::evmc_address { bytes: [0u8; 20] };
729+
let test_addr = Address { bytes: [0u8; 20] };
742730
let mut context_raw = get_dummy_context();
743731
let mut exe_context = ExecutionContext::new(&msg, &mut context_raw);
744732

bindings/rust/evmc-vm/src/types.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use evmc_sys as ffi;
2+
3+
/// EVMC address
4+
pub type Address = ffi::evmc_address;
5+
6+
/// EVMC 32 bytes value (used for hashes)
7+
pub type Bytes32 = ffi::evmc_bytes32;
8+
9+
/// EVMC big-endian 256-bit integer
10+
pub type Uint256 = ffi::evmc_uint256be;
11+
12+
#[cfg(test)]
13+
mod tests {
14+
use super::*;
15+
16+
// These tests check for Default, PartialEq and Clone traits.
17+
#[test]
18+
fn address_smoke_test() {
19+
let a = ffi::evmc_address::default();
20+
let b = Address::default();
21+
assert_eq!(a.clone(), b.clone());
22+
}
23+
24+
#[test]
25+
fn bytes32_smoke_test() {
26+
let a = ffi::evmc_bytes32::default();
27+
let b = Bytes32::default();
28+
assert_eq!(a.clone(), b.clone());
29+
}
30+
31+
#[test]
32+
fn uint26be_smoke_test() {
33+
let a = ffi::evmc_uint256be::default();
34+
let b = Uint256::default();
35+
assert_eq!(a.clone(), b.clone());
36+
}
37+
}

0 commit comments

Comments
 (0)