@@ -9,65 +9,116 @@ pub struct CallInputs {
9
9
/// The call data of the call.
10
10
pub input : Bytes ,
11
11
/// The return memory offset where the output of the call is written.
12
- /// For EOF this range is invalid as EOF does write output to memory.
12
+ ///
13
+ /// In EOF, this range is invalid as EOF calls do not write output to memory.
13
14
pub return_memory_offset : Range < usize > ,
14
15
/// The gas limit of the call.
15
16
pub gas_limit : u64 ,
16
- /// The account address of bytecode that is going to be executed.
17
+ /// The account address of bytecode that is going to be executed.
18
+ ///
19
+ /// Previously `context.code_address`.
17
20
pub bytecode_address : Address ,
18
21
/// Target address, this account storage is going to be modified.
22
+ ///
23
+ /// Previously `context.address`.
19
24
pub target_address : Address ,
20
25
/// This caller is invoking the call.
26
+ ///
27
+ /// Previously `context.caller`.
21
28
pub caller : Address ,
22
- /// Value that is transferred in Ether.
29
+ /// Call value.
30
+ ///
31
+ /// NOTE: This value may not necessarily be transferred from caller to callee, see [`CallValue`].
23
32
///
24
- /// If enum is [`TransferValue::Value`] balance is transferer from `caller` to the `target_address`.
33
+ /// Previously `transfer.value` or `context.apparent_value`.
34
+ pub value : CallValue ,
35
+ /// The call scheme.
25
36
///
26
- /// If enum is [`TransferValue::ApparentValue`] balance transfer is **not**
27
- /// done and apparent value is used by CALLVALUE opcode. Used by delegate call.
28
- pub value : TransferValue ,
29
- /// The scheme used for the call. Call, callcode, delegatecall or staticcall.
37
+ /// Previously `context.scheme`.
30
38
pub scheme : CallScheme ,
31
- /// Whether this is a static call.
39
+ /// Whether the call is initiated inside a static call.
32
40
pub is_static : bool ,
33
- /// Call is initiated from EOF bytecode.
41
+ /// Whether the call is initiated from EOF bytecode.
34
42
pub is_eof : bool ,
35
43
}
36
44
37
45
impl CallInputs {
38
46
/// Creates new call inputs.
47
+ ///
48
+ /// Returns `None` if the transaction is not a call.
39
49
pub fn new ( tx_env : & TxEnv , gas_limit : u64 ) -> Option < Self > {
40
50
let TransactTo :: Call ( target_address) = tx_env. transact_to else {
41
51
return None ;
42
52
} ;
43
-
44
53
Some ( CallInputs {
45
54
input : tx_env. data . clone ( ) ,
46
55
gas_limit,
47
56
target_address,
48
57
bytecode_address : target_address,
49
58
caller : tx_env. caller ,
50
- value : TransferValue :: Value ( tx_env. value ) ,
59
+ value : CallValue :: Transfer ( tx_env. value ) ,
51
60
scheme : CallScheme :: Call ,
52
61
is_static : false ,
53
62
is_eof : false ,
54
63
return_memory_offset : 0 ..0 ,
55
64
} )
56
65
}
57
66
58
- /// Returns boxed call inputs.
67
+ /// Creates new boxed call inputs.
68
+ ///
69
+ /// Returns `None` if the transaction is not a call.
59
70
pub fn new_boxed ( tx_env : & TxEnv , gas_limit : u64 ) -> Option < Box < Self > > {
60
71
Self :: new ( tx_env, gas_limit) . map ( Box :: new)
61
72
}
62
73
63
- /// Return call value
64
- pub fn call_value ( & self ) -> U256 {
65
- let ( TransferValue :: Value ( value) | TransferValue :: ApparentValue ( value) ) = self . value ;
66
- value
74
+ /// Returns `true` if the call will transfer a non-zero value.
75
+ #[ inline]
76
+ pub fn transfers_value ( & self ) -> bool {
77
+ self . value . transfer ( ) . is_some_and ( |x| x > U256 :: ZERO )
78
+ }
79
+
80
+ /// Returns the transfer value.
81
+ ///
82
+ /// This is the value that is transferred from caller to callee, see [`CallValue`].
83
+ #[ inline]
84
+ pub const fn transfer_value ( & self ) -> Option < U256 > {
85
+ self . value . transfer ( )
86
+ }
87
+
88
+ /// Returns the **apparent** call value.
89
+ ///
90
+ /// This value is not actually transferred, see [`CallValue`].
91
+ #[ inline]
92
+ pub const fn apparent_value ( & self ) -> Option < U256 > {
93
+ self . value . apparent ( )
94
+ }
95
+
96
+ /// Returns the address of the transfer source account.
97
+ ///
98
+ /// This is only meaningful if `transfers_value` is `true`.
99
+ #[ inline]
100
+ pub const fn transfer_from ( & self ) -> Address {
101
+ self . caller
102
+ }
103
+
104
+ /// Returns the address of the transfer target account.
105
+ ///
106
+ /// This is only meaningful if `transfers_value` is `true`.
107
+ #[ inline]
108
+ pub const fn transfer_to ( & self ) -> Address {
109
+ self . target_address
110
+ }
111
+
112
+ /// Returns the call value, regardless of the transfer value type.
113
+ ///
114
+ /// NOTE: this value may not necessarily be transferred from caller to callee, see [`CallValue`].
115
+ #[ inline]
116
+ pub const fn call_value ( & self ) -> U256 {
117
+ self . value . get ( )
67
118
}
68
119
}
69
120
70
- /// Call schemes .
121
+ /// Call scheme .
71
122
#[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
72
123
#[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
73
124
pub enum CallScheme {
@@ -81,19 +132,61 @@ pub enum CallScheme {
81
132
StaticCall ,
82
133
}
83
134
84
- /// Transfered value from caller to callee .
135
+ /// Call value.
85
136
#[ derive( Clone , Debug , PartialEq , Eq , Hash ) ]
86
137
#[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
87
- pub enum TransferValue {
88
- /// Transfer value from caller to callee.
89
- Value ( U256 ) ,
90
- /// For delegate call, the value is not transferred but
91
- /// apparent value is used for CALLVALUE opcode
92
- ApparentValue ( U256 ) ,
138
+ pub enum CallValue {
139
+ /// Concrete value, transferred from caller to callee at the end of the transaction.
140
+ Transfer ( U256 ) ,
141
+ /// Apparent value, that is **not** actually transferred.
142
+ ///
143
+ /// Set when in a `DELEGATECALL` call type, and used by the `CALLVALUE` opcode.
144
+ Apparent ( U256 ) ,
93
145
}
94
146
95
- impl Default for TransferValue {
147
+ impl Default for CallValue {
148
+ #[ inline]
96
149
fn default ( ) -> Self {
97
- TransferValue :: Value ( U256 :: ZERO )
150
+ CallValue :: Transfer ( U256 :: ZERO )
151
+ }
152
+ }
153
+
154
+ impl CallValue {
155
+ /// Returns the call value, regardless of the type.
156
+ #[ inline]
157
+ pub const fn get ( & self ) -> U256 {
158
+ match * self {
159
+ Self :: Transfer ( value) | Self :: Apparent ( value) => value,
160
+ }
161
+ }
162
+
163
+ /// Returns the transferred value, if any.
164
+ #[ inline]
165
+ pub const fn transfer ( & self ) -> Option < U256 > {
166
+ match * self {
167
+ Self :: Transfer ( transfer) => Some ( transfer) ,
168
+ Self :: Apparent ( _) => None ,
169
+ }
170
+ }
171
+
172
+ /// Returns whether the call value will be transferred.
173
+ #[ inline]
174
+ pub const fn is_transfer ( & self ) -> bool {
175
+ matches ! ( self , Self :: Transfer ( _) )
176
+ }
177
+
178
+ /// Returns the apparent value, if any.
179
+ #[ inline]
180
+ pub const fn apparent ( & self ) -> Option < U256 > {
181
+ match * self {
182
+ Self :: Transfer ( _) => None ,
183
+ Self :: Apparent ( apparent) => Some ( apparent) ,
184
+ }
185
+ }
186
+
187
+ /// Returns whether the call value is apparent, and not actually transferred.
188
+ #[ inline]
189
+ pub const fn is_apparent ( & self ) -> bool {
190
+ matches ! ( self , Self :: Apparent ( _) )
98
191
}
99
192
}
0 commit comments