NOTE: this is used for both internal and external calls. External calls are triggered from ExecutionFramework and contain only EVMC_CREATE or EVMC_CALL.
| 257 | // NOTE: this is used for both internal and external calls. |
| 258 | // External calls are triggered from ExecutionFramework and contain only EVMC_CREATE or EVMC_CALL. |
| 259 | evmc::Result EVMHost::call(evmc_message const& _message) noexcept |
| 260 | { |
| 261 | recordCalls(_message); |
| 262 | if (_message.recipient == 0x0000000000000000000000000000000000000001_address) |
| 263 | return precompileECRecover(_message); |
| 264 | else if (_message.recipient == 0x0000000000000000000000000000000000000002_address) |
| 265 | return precompileSha256(_message); |
| 266 | else if (_message.recipient == 0x0000000000000000000000000000000000000003_address) |
| 267 | return precompileRipeMD160(_message); |
| 268 | else if (_message.recipient == 0x0000000000000000000000000000000000000004_address) |
| 269 | return precompileIdentity(_message); |
| 270 | else if (_message.recipient == 0x0000000000000000000000000000000000000005_address && m_evmVersion >= langutil::EVMVersion::byzantium()) |
| 271 | return precompileModExp(_message); |
| 272 | else if (_message.recipient == 0x0000000000000000000000000000000000000006_address && m_evmVersion >= langutil::EVMVersion::byzantium()) |
| 273 | { |
| 274 | if (m_evmVersion <= langutil::EVMVersion::istanbul()) |
| 275 | return precompileALTBN128G1Add<EVMC_ISTANBUL>(_message); |
| 276 | else |
| 277 | return precompileALTBN128G1Add<EVMC_LONDON>(_message); |
| 278 | } |
| 279 | else if (_message.recipient == 0x0000000000000000000000000000000000000007_address && m_evmVersion >= langutil::EVMVersion::byzantium()) |
| 280 | { |
| 281 | if (m_evmVersion <= langutil::EVMVersion::istanbul()) |
| 282 | return precompileALTBN128G1Mul<EVMC_ISTANBUL>(_message); |
| 283 | else |
| 284 | return precompileALTBN128G1Mul<EVMC_LONDON>(_message); |
| 285 | } |
| 286 | else if (_message.recipient == 0x0000000000000000000000000000000000000008_address && m_evmVersion >= langutil::EVMVersion::byzantium()) |
| 287 | { |
| 288 | if (m_evmVersion <= langutil::EVMVersion::istanbul()) |
| 289 | return precompileALTBN128PairingProduct<EVMC_ISTANBUL>(_message); |
| 290 | else |
| 291 | return precompileALTBN128PairingProduct<EVMC_LONDON>(_message); |
| 292 | } |
| 293 | else if (_message.recipient == 0x0000000000000000000000000000000000000009_address && m_evmVersion >= langutil::EVMVersion::istanbul()) |
| 294 | return precompileBlake2f(_message); |
| 295 | |
| 296 | auto const stateBackup = accounts; |
| 297 | |
| 298 | u256 value{convertFromEVMC(_message.value)}; |
| 299 | auto& sender = accounts[_message.sender]; |
| 300 | |
| 301 | evmc::bytes code; |
| 302 | |
| 303 | evmc_message message = _message; |
| 304 | if (message.depth == 0) |
| 305 | { |
| 306 | message.gas -= message.kind == EVMC_CREATE ? evmasm::GasCosts::txCreateGas : evmasm::GasCosts::txGas; |
| 307 | for (size_t i = 0; i < message.input_size; ++i) |
| 308 | message.gas -= message.input_data[i] == 0 ? evmasm::GasCosts::txDataZeroGas : evmasm::GasCosts::txDataNonZeroGas(m_evmVersion); |
| 309 | if (message.gas < 0) |
| 310 | { |
| 311 | evmc::Result result; |
| 312 | result.status_code = EVMC_OUT_OF_GAS; |
| 313 | accounts = stateBackup; |
| 314 | return result; |
| 315 | } |
| 316 | } |
no test coverage detected