1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
pub struct Uint128 {
pub bytes: [u8; 16],
}
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
pub struct Uint256 {
pub bytes: [u8; 32],
}
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
pub struct Bytes20 {
pub bytes: [u8; 20],
}
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
pub struct Bytes32 {
pub bytes: [u8; 32],
}
pub type EtherValue = Uint128;
pub type Address = Bytes20;
pub type StorageKey = Bytes32;
pub type StorageValue = Bytes32;
pub type LogTopic = Bytes32;
pub type Hash = Bytes32;
pub type Difficulty = Uint256;
macro_rules! from_primitive_impl {
($f:ident, $size:expr, $to:ident) => {
impl From<[$f; $size]> for $to {
fn from(a: [$f; $size]) -> Self {
$to { bytes: a }
}
}
};
}
macro_rules! from_primitive_ref_impl {
($f:ident, $size:expr, $to:ident) => {
impl From<&[$f; $size]> for $to {
fn from(a: &[$f; $size]) -> Self {
$to { bytes: a.clone() }
}
}
};
}
macro_rules! from_type_for_primitive_impl {
($f:ident, $size:expr, $to:ident) => {
impl From<$f> for [$to; $size] {
fn from(a: $f) -> Self {
a.bytes
}
}
};
}
from_primitive_impl!(u8, 16, Uint128);
from_primitive_impl!(u8, 32, Uint256);
from_primitive_impl!(u8, 20, Bytes20);
from_primitive_impl!(u8, 32, Bytes32);
from_primitive_ref_impl!(u8, 16, Uint128);
from_primitive_ref_impl!(u8, 32, Uint256);
from_primitive_ref_impl!(u8, 20, Bytes20);
from_primitive_ref_impl!(u8, 32, Bytes32);
from_type_for_primitive_impl!(Uint128, 16, u8);
from_type_for_primitive_impl!(Uint256, 32, u8);
from_type_for_primitive_impl!(Bytes20, 20, u8);
from_type_for_primitive_impl!(Bytes32, 32, u8);
#[cfg(test)]
mod tests {
use super::{Bytes20, Bytes32, Uint128, Uint256};
macro_rules! test_conversions {
($type: ident, $size: expr, $test_name: ident) => {
#[test]
fn $test_name() {
let raw = [1; $size];
let uint = $type::from(raw);
assert_eq!(uint.bytes[$size - 1], 1);
let uint = $type::from(&raw);
assert_eq!(uint.bytes[$size - 1], 1);
let uint: $type = raw.into();
assert_eq!(uint.bytes[$size - 1], 1);
let uint: $type = (&raw).into();
assert_eq!(uint.bytes[$size - 1], 1);
let r: [u8; $size] = uint.into();
assert_eq!(r[$size - 1], 1);
}
};
}
test_conversions!(Uint128, 16, test_uint128);
test_conversions!(Uint256, 32, test_uint256);
test_conversions!(Bytes20, 20, test_bytes20);
test_conversions!(Bytes32, 32, test_bytes32);
}