EVM Compatibility in nigo-protocol: Reusing Existing Contracts and Development Tools
Choosing a new ledger also means considering the code and tools you will use on it. If you already have contracts written in Solidity and an app that reads balances and signs transactions with familiar libraries, being able to keep using that work is a substantial benefit.
nigo-protocol provides this connection through an EVM execution path within its own ledger architecture. In SDK sample verification, the same Token bytecode and ABI were used with ethers, viem, and Web3j for deployment, queries, signed transaction submission, and result checks. The necessary changes were handled through SDK settings and transaction options without rewriting the business rules.
EVM function calls and state changes explained how contract execution is reflected in the ledger. This article examines what that structure offers developers. Let us follow a token transfer app to see what it means to keep using existing code and tools.
Keep the development model when the ledger changes
EVM is a virtual machine that executes contract code. Compiling Solidity produces the bytecode that EVM executes. An app encodes function arguments and interprets return values according to an interface called the ABI. For a dApp—an app that uses contracts—the bytecode and ABI connect business rules with the way the app calls them.
nigo-protocol's EVM path supports this development model. A contract expresses its business logic through functions and storage, and the app calls those functions through the ABI. The ledger's execution layer reflects the results in StateCell, nigo-protocol's common state format. When calling an EVM contract, developers do not have to construct proposals for cell input and output changes themselves.
Client tools are part of this connection too. An SDK is a library that helps with function calls and transaction construction and signing. RPC is the request interface through which an SDK queries a node or submits a transaction. The versions used in verification were ethers 6.17.0, viem 2.55.19, and Web3j 4.10.0. All three SDKs used the same Token ABI and bytecode and constructed transactions through their standard signing paths.
The benefit to developers is concrete. In the verified flow, the contract's token transfer rules stayed the same, while familiar libraries continued to handle function calls, signing, and result queries. The EVM compatibility layer connects the ledger's internal state representation with the interfaces used by the app.
Complete a transfer with the same token code
Consider a token contract T that stores balances by address.
Deploy the same code afresh on nigo-protocol and prepare a state where A holds 100 tokens and B holds 0.
When A signs a call to transfer(B, 20), the result is A=80 and B=20.
These amounts are an illustrative example, not the transfer amounts used in the actual verification.
Assume there is no separate token transfer fee, minting, or burning, and no other transaction changes these balances before or after the transfer. The amount of the base coin attached to the call and the protocol fee are both zero, while execution limits still apply. Because this starts with a new deployment, migrating existing balances and history from another chain is a separate task.
The app follows the familiar sequence of calls, signing, and queries:
Deploy the same T code
on the new ledger
↓
Read balances: A=100, B=0
↓
A signs and submits
transfer(B, 20)
↓
Check the finalized result
and transfer event
↓
Read balances: A=80, B=20
First, the app calls T's balanceOf(A) through the ABI and reads a token balance of 100.
This query is sent as an eth_call request, which executes the function without changing state.
The app then uses the same ABI to construct the arguments for transfer(B, 20)
and submits a transaction signed with A's key to the node.
Once the transaction is finalized, the app checks its receipt, the execution result record,
for success and T's Transfer(A, B, 20) event.
Calling balanceOf again returns A=80 and B=20. The token total also remains unchanged: 100 + 0 = 80 + 20.
Both the code preparing the request to sign and the code reading its result use the same contract interface.
The actual SDK samples also verified deployment, contract queries, signed submission, and receipt and event checks as one complete flow. Beyond establishing that the contract executes, they verified the connection through which existing SDKs construct requests and interpret results. That provides evidence for reusing the code and tools needed to build a token transfer screen.
Account delegation and standard cryptographic operations are supported too
EVM apps do more than read and write token storage. They may also extend account behavior or verify signatures and proofs. nigo-protocol supports execution features needed to build these contracts as well.
Attach executable code to an account with set_code
set_code is the Type-4 transaction defined by EIP-7702.
A regular account controlled by a signing key can use a signed authorization to designate the address of code to execute.
The designated code then executes using that account's address and storage.
This extends an account's behavior through code while preserving its address, and the delegation persists across subsequent transactions.
A new valid authorization can change or clear the delegation.
nigo-protocol supports receiving Type-4 transactions, validating authorizations, setting delegations, and executing delegated code. Verification records also cover official execution tests applied through the actual transaction processing path, comparing state changes, gas, and execution results. Developers can build on this delegation mechanism to design features such as account logic that groups multiple token transfers. The specific wallet behavior is implemented in the delegated code and the client.
Keep using standard cryptographic calls through precompiles
A precompile is a built-in EVM execution facility called at a predefined address for operations such as signature recovery, hashing, and elliptic-curve arithmetic. Contracts pass data in the prescribed input format and receive the result.
nigo-protocol implements the complete standard precompile set for Osaka, a version of Ethereum's execution rules.
Along with ecrecover for signature recovery and hash operations such as SHA-256,
it provides MODEXP and BN254 operations, KZG point evaluation,
BLS12-381 operations,
and P-256 signature verification.
Contracts using these facilities can keep their code that calls cryptographic operations
through the existing standard addresses and input formats.
Verification checks gas calculation and handling of invalid inputs as well as operation results. Alongside execution-layer verification using official test data, it checks precompile behavior through internal contract calls, top-level transactions, and RPC queries. Beyond SDK verification of the token sample, this provides an execution foundation for apps that use signatures and cryptographic proofs.
Preserve business rules and adjust integration settings
Moving to a different ledger means configuring the RPC endpoint, chain ID, signer, and deployment address for the destination. The ledger's policies also need to be reflected in how the SDK sets fees or queries results again. In the verified samples, these adjustments allowed the same contract's business rules to remain intact.
This level of change is classified as LOW_CHANGE: the contract and business logic are preserved, while integration details such as SDK initialization and transaction options are adjusted. It is distinguished from Config-only, which changes only connection information and deployment settings, to make the actual scope of modifications visible. The verified outcome is a reduced need to reimplement business behavior, with the necessary adjustments concentrated in integration settings.
Fee configuration is one example. Gas measures the resources used during execution. nigo-protocol's ZERO policy sets the fee amount to zero, while its FIXED policy sets a fixed price per unit of gas. Both policies enforce execution limits.
The Type-2 transactions used in verification explicitly specified the maximum fee per gas and maximum priority fee per gas. Under ZERO, both values were set to 0. Under FIXED with a price of P per gas, they were set to P and 0, respectively. These are transaction options supplied to the SDK to match nigo-protocol's fee policy.
The example's transfer(B, 20) call and T's code that updates balances remain unchanged.
The destination ledger's fee policy is reflected in transaction construction,
while the business rule that transfers 20 tokens is reused.
Being able to distinguish the code to retain from the settings to adjust makes a migration plan concrete.
The connection was verified through queries after restart
An app should still be able to read transaction history and balances when a user returns after checking a transfer result. SDK verification included queries after a node restart.
Separate ZERO and FIXED runs each used a new file-backed database to process the sample transactions. The node was then stopped and restarted with the same database. After restart, no new transactions were submitted; existing transactions, receipts, blocks, logs, and contract state were queried again. The preserved results were compared to check that they matched before and after restart.
This is evidence that the results of requests originating in an SDK are stored and remain queryable when the same database is reopened. The verified scope is querying results preserved by the same node version. Converting an older version's database to a new format requires separate verification.
When code reuse, standard signing and requests, and queries of stored results form a complete flow, app developers can show users transfer results without accessing the ledger's internal storage format directly.
Match the query scope your app needs
The token transfer example uses current balances and finalized transaction results.
Currently, nigo-protocol's eth_call reads state finalized by consensus.
Specifying latest, safe, or finalized, or omitting the tag, selects the same current finalized state.
Receipts and event logs are also provided from finalized transaction results.
Adding a “balance at the end of last month” screen changes the query requirements.
The current RPC can query historical finalized blocks and event logs,
but it does not support running eth_call against the state at an arbitrary historical block number.
Such a screen requires considering both the supported scope of historical state queries
and how the app's historical data will be organized.
For an actual migration, list the functions, transaction formats, and query points in time that the app uses,
then verify those flows with the intended SDK version.
The token samples verified with the three SDKs provide a starting point.
Features in other contracts and browser-wallet connection and approval screens
require additional verification against the app's needs.
Construction and signing of the Type-4 transactions needed for set_code were verified with the tested ethers and viem versions.
Web3j 4.10.0 does not provide this construction and signing capability,
so the SDK should be chosen to match the transaction formats the app will use.
Use a new ledger with existing development work
nigo-protocol's EVM compatibility provides a connection through which an existing development model can continue. The verified token flow used the same bytecode and ABI and familiar SDK signing and query capabilities. Necessary changes were handled in integration settings and transaction options while preserving the business logic.
For developers who have built up contracts and calling code, this is a foundation for reusing that work. The ledger's internal StateCell design can coexist with the experience of building apps using Solidity and EVM tools. Account delegation and standard precompile support extend the development patterns that can be reused beyond simple token transfers. The value of this compatibility is building apps with the same code and tools, then adjusting the necessary integration settings to connect them to a new ledger.
After exploring Direct Cell, Native Program, and EVM, a natural next question is how they can work together within a single business process. When different execution models connect through the same assets and workflows, the value of sharing one ledger becomes more concrete. What path does an EVM contract take to interact with Native assets, and how are each domain's permissions and validation rules enforced? An upcoming post will examine this connection and how related changes are rolled back together when execution fails.