GitHub Logo HIP-1217: Contracts/Calls API Changes

Author Keith Kowal
Working Group Steven Sheeny
Requested By Keith Kowal<@reccetech>, Steven Sheeny<@steven-sheehy>
Discussions-To https://github.com/hiero-ledger/hiero-improvement-proposals/pull/1217
Status Last Call
Review period ends Mon, 07 Jul 2025 07:00:00 +0000
Type Informational
Created 2025-06-14
Updated 2025-06-23

Abstract

The /api/v1/contracts/call endpoint has been updated to support a modularized execution flow. This new implementation replaces the current monolithic version, and integrates directly with the consensus node via the hedera-app library. This change delivers a more accurate execution behavior aligned with Hiero Consensus Nodes, enabling broader operation support. However, this improvement does also introduce changes which may break some applications as detailed in this HIP.

Motivation

The current monolithic EVM implementation at times diverged from consensus node behavior, and had inconsistencies in address resolution, payer balance validation, and error handling. To provide a reliable, consensus-aligned developer experience, a modularized EVM execution flow was introduced. The purpose of this HIP is to notify the community of changes introduced by the updated code so they can take action to update their applications accordingly. This document only details the changes in behavior up to this point in time. In the future, new validations, error codes, system contracts, and changes in gas calculation may change inside consensus nodes. Due to the shared EVM execution logic between consensus nodes and mirror nodes, mirror nodes will directly reflect these changes once it upgrades its hedera-app library version. These future changes will be communicated by other HIPs specifically dealing with this new functionality.

Rationale

By modularizing the EVM flow and tightly coupling it to hedera-app, Hedera ensures consistent behavior between simulated calls against the mirror node and actual contract execution against the consensus node. This EVM modularization brings three core benefits:

  1. More accurate gas pricing estimates
  2. Behaviour consistent with latest changes in Hedera Consensus Nodes including support for newer system contracts
  3. Simplified debugging through improved error codes

User stories

User Personas:

Developer: Builds applications and tools
Indexer: Indexes activity and state of Hedera Smart Contracts
Exchange Operator: Operates exchange for users
Wallet Operator: Operates user wallet services and infrastructure

User Stories

As a Developer I want to understand the state of my smart contract running on Hiero public networks
As a Indexer I want to understand and record the activity and state of key smart contracts on Hedera
As an Exchange Operator: I want to understand the state of assets under control by my users
As a Wallet Operator: I want to understand and present smart contract assets under control of users in their wallet

Specification

Changes to the /api/v1/contracts/call endpoint might have the following potential impacts for developer applications:

1. Address Resolution Behavior

Impact: Contract calls that previously succeeded may now fail with CONTRACT_REVERT_EXECUTED or other execution-related errors when addresses are provided in the long-zero format and the referenced account has a public key derived alias.

Reason for change: The modularized flow introduces stricter address resolution logic that prioritizes EVM aliases over long-zero format addresses when the target account has an alias. This change aligns with consensus node behavior and ensures consistent and accurate address resolution.

Resolution: When passing account or contract addresses in any part of the request payload—such as calldata, constructor arguments, or encoded function parameters—clients must use the public key derived EVM alias format (e.g., 0xc5b7…) rather than the long-zero format (e.g., 0x0000000000000000000000000000000000abc123) if the account has the former.

2. Payer Balance Validation

Impact: Contract calls that previously succeeded under the monolithic flow may now fail in the modularized flow with INSUFFICIENT_PAYER_BALANCE if the payer account does not have sufficient funds, even when the call is a simulation (e.g., using eth_call).

Reason for change: The modularized execution flow enforces a stricter validation of the payer’s balance before executing contract calls. This change aligns with consensus node behavior, ensuring that contract calls fail early if the payer cannot cover the required cost.

Details: In the monolithic flow, balance checks were more lenient or deferred, allowing some calls to succeed even when the payer lacked sufficient balance. Under the modularized flow, the same calls now fail immediately if the balance check fails, resulting in INSUFFICIENT_PAYER_BALANCE being returned.

Resolution: Ensure that payer accounts have sufficient balances to cover contract call costs. Update client-side logic and test cases to account for stricter balance validation in the modularized flow.

3. Invalid Input Handling

Impact: Error responses may differ from the previous monolithic flow when handling malformed or invalid inputs. Reason for change: The modularized execution flow introduces more granular validation and status reporting aligned with consensus node behavior.

Details: Some statuses like CONTRACT_REVERT_EXECUTED, INSUFFICIENT_GAS, and INVALID_SOLIDITY_ADDRESS are common to both flows. However, the modularized flow introduces more specific statuses such as INVALID_ALIAS_KEY, INVALID_CONTRACT_ID, and MAX_CHILD_RECORDS_EXCEEDED, providing clearer failure reasons. One example is when sending a non-zero value to the exchange rate precompile:

  • Modularized: fails with INVALID_CONTRACT_ID
  • Monolithic: fails with CONTRACT_REVERT_EXECUTED

Resolution: Update client-side logic to handle a wider range of status codes and to expect HTTP 400 responses with more descriptive error messages. Ensure precompile calls like the exchange rate query are made with no value, or expect INVALID_CONTRACT_ID under modularized behavior.

4. Gas Estimation

Impact: Gas estimation may now return slightly different results due to improved modeling especially for contract deploy.

Reason for change: Estimation logic has been updated to better reflect actual execution cost as in consensus node.

Resolution: When comparing to old estimates, expect minor differences except for contract deployment.

5. Default KYC Status

Impact: The result of getDefaultKycStatus may differ between the monolithic and modularized flows, potentially affecting token-related contract interactions.

Reason for change: The modularized flow retrieves KYC status directly from the consensus node’s state via hedera-app, whereas the monolithic flow used separate internal logic.

Details: In some cases, tokens that returned a default false KYC status in the monolithic flow may now return true (or vice versa) based on the actual token configuration in state. Resolution: Review any tests or client logic that depend on the default KYC status returned by contract calls and adjust expectations to reflect the consensus-backed behavior in the modularized flow.

6. Return Values vs Exceptions

Impact: In some scenarios, contract calls that previously returned a default value (e.g., 0x) may now result in an error, or conversely, calls that previously threw an error may now return a benign fallback value (e.g., false or 0x), depending on the modularized flow’s interpretation of the state.

Reason for change: The modularized flow improves internal consistency with the consensus node by aligning behavior with smart contract execution semantics, particularly for missing or uninitialized state entries. Rather than throwing exceptions for all unexpected conditions, modularized flow may return fallback values when appropriate. Examples:

  1. eth_call with a sender address that does not exist:
    • Monolithic: Returns 0x
    • Modularized: Throws a PAYER_ACCOUNT_NOT_FOUND error
  2. Precompiled HTS contract call (e.g., isToken) on a token that has not yet been persisted:
    • Monolithic: reverts the call with CONTRACT_REVERT_EXECUTED
    • Modularized: returns false or an empty result

Resolution: Update error handling logic to support both patterns. When using eth_call, handle both exception-based and value-based responses, depending on the context and behavior in the modularized flow.

7. Calls to Nonexistent Contracts

Impact: Calling a contract that does not exist may return a different status in the modularized flow compared to the monolithic implementation.

Reason for change: The modularized flow validates contract existence directly against the consensus node state and returns INVALID_CONTRACT_ID, while the monolithic flow previously would have returned INVALID_TRANSACTION in this scenario.

Details: Client applications relying on a specific error code for missing contracts may behave differently depending on the flow used.

Resolution: Update any error handling logic or tests expecting INVALID_TRANSACTION to also handle INVALID_CONTRACT_ID when running against the modularized flow.

8. Redirect Call Errors

Impact: Contract calls that redirect and fail due to invalid input may produce different error statuses between the monolithic and modularized flows.

Reason for change: The modularized flow execution logic results in standard EVM reverts (e.g., CONTRACT_REVERT_EXECUTED) instead mono errors result in INVALID_TOKEN_ID.

Details: Affected functions include:

  • decimalsRedirect
  • ownerOfRedirect
  • tokenURIRedirect

In these and similar cases:

  • Monolithic: Returned specific status codes such as INVALID_TOKEN_ID
  • Modularized: Failing redirects result in CONTRACT_REVERT_EXECUTED

Resolution: Update tests and error handling logic to account for CONTRACT_REVERT_EXECUTED and INVALID_TOKEN_ID

Backwards Compatibility

These changes are not backwards compatible. Applications relying on the current behavior must be updated to avoid failed executions, incorrect error handling, or unexpected state evaluations. Test Cases

  • Address alias resolution fails with long-zero format when alias exists.
  • Simulation fails with insufficient payer balance.
  • Exchange rate precompile with non-zero value fails with INVALID_CONTRACT_ID.
  • eth_call on nonexistent address throws PAYER_ACCOUNT_NOT_FOUND.
  • Calling non-existing contract fails with INVALID_CONTRACT_ID

Security Implications

The stricter validation and improved modeling reduce risk of unintended contract success/failure. The new codebase also supports additional checks that ensure code will detect any bugs in a fail-fast way.

Reference Implementation

Modularized code currently running on Hedera testnet and previewnet

Rejected Ideas

Open Issues

References

Copyright/license

This document is licensed under the Apache License, Version 2.0 — see LICENSE or https://www.apache.org/licenses/LICENSE-2.0.

Citation

Please cite this document as: