Skip to main content
All articles

Approving an Asset in Native and Using It in EVM

· 8 min read
Bankware Global Engineering

An asset that you can send directly from a wallet should also be usable in a business contract. The contract handles a payment within the amount you authorize, and if the business operation fails, the asset transfer is canceled with it. If each execution path requires separate balances or approval records, much of the benefit of using one ledger disappears.

nigo-protocol allows the same Native Asset to be transferred directly by its owner or used through Native programs and EVM contracts. The unified asset design establishes a common model; connections between execution domains make that model useful in actual workflows. One path checks authority granted through another, and their combined success or failure is reflected in the same state.

The article on EVM compatibility explored the benefits of retaining existing contract code and development tools. Here, we will follow an EVM business contract as it uses a Native asset on the ledger.

Comparing two ways to use the same starting balance​

A holds 100 units of asset X, and B holds none. P is an EVM contract that handles payments, and A has not yet authorized P to spend X. This article starts independently from that state; it does not carry forward a transfer from another article.

Assume X is an active standard asset that permits direct transfers by its owner. The required policy and EVM adapter contract are already in place, and we will not mint, burn, or change the policy. The amounts 100, 20, and 30 are illustrative. We assume a zero fee, sufficient execution budget, and valid signatures and inputs. The NIGO needed for the transaction is provided separately from the business asset X.

The first option is for A to send 20 units of X directly to B. In a Direct Cell transaction, A specifies the cells to consume and the cells to create. The ledger checks ownership, the signature, the asset's current direct-transfer conditions, and conservation of quantity. On success, A holds 80 and B holds 20. P's allowance remains zero.

This does not invoke the asset policy's virtual machine. Direct is an execution path that verifies the owner's transfer authority under common rules; it is not a fallback for a failed policy execution.

The second option is to grant P limited spending authority and let it perform the business operation. We now start again from A=100, B=0, and allowance=0. This is not a transaction following the direct transfer above.

Approving in Native and spending through an EVM contract​

A uses a separate Native transaction to authorize P to spend 30 units of X. Once that transaction is finalized, A still holds 100 and B still holds zero. An approval does not transfer X to P in advance. It records an allowance: the amount of A's asset that P may spend.

An EVM transaction then calls P's business function. P checks that the requester and payment recipient meet its business conditions, then requests transferFrom(A, B, 20) from X's adapter, the contract connecting EVM calls to the Native asset. The adapter is bound to X and forwards the request to X's currently bound Native policy.

The policy checks A's allowance of 30 for P. If the requested amount of 20 is within that limit and the required inputs and asset rules are satisfied, it applies the balance transfer and allowance reduction together. The result is A=80, B=20, and a remaining allowance of 10. The total quantity of X remains 100.

Native transaction: A approves 30 for P → finalized
Balances A=100, B=0 / allowance=30
↓
EVM transaction: P asks X's adapter to transfer 20
↓
X's Native policy validates → changes applied to the shared ledger
Balances A=80, B=20 / allowance=10

The approval created through Native and the allowance read through EVM are the same record. If A subsequently uses another Native transaction to set the remaining allowance to zero, the balances stay at 80/20, and P's next delegated spending request is rejected. EVM does not retain a separate copy of the old allowance of 10 that it can continue to spend.

A wallet can manage permissions through Native requests while a developer composes the business workflow in an EVM contract. Both use the same asset and approval state.

Shared state still requires checking whose authority is being used​

The adapter forwards requests; calling its address does not itself grant permission to spend an asset. In this example, the spender the policy checks is P, the contract that actually called the adapter. It does not substitute the address that originally signed the EVM transaction for P.

Without this distinction, merely calling a contract could let that contract exercise A's direct ownership rights. nigo-protocol checks the actual call relationship and adapter code, then permits only the effects that the current policy authorizes for that caller.

P must also validate the external requester and recipient according to its business rules. P's allowance must not become a way for anyone to direct payments to an arbitrary address.

The adapter also does not automatically turn an arbitrary ERC-20 contract into a Native Asset. X in this article is a Native Asset from the outset; P is a business contract that uses X. The asset state lives in a different place from the model described in the article on EVM calls and state changes, where token balances are held in an EVM contract's own storage.

What if the business operation fails after the transfer?​

Suppose P transfers 20 units of X to B, then cancels the entire call because a later business condition is not met. EVM's REVERT rolls back the changes made by that call. If the Native asset transfer survived, the business operation would have failed while the payment still went through.

To prevent this, Native changes made through the adapter are included in the EVM call's rollback scope. They are first applied to tentative state and are committed only if the enclosing call also succeeds. If the enclosing call reverts, the transfer, the allowance reduction, and the resulting events are all discarded together.

The two outcomes below are alternatives branching from the same state, in which the Native approval of 30 has already been finalized.

EVM business outcomeA's XB's XP's remaining allowance
Before the call100030
Transfer and enclosing operation both succeed802010
Enclosing operation reverts after the transfer100030

The allowance remains 30 in the failed branch because that approval was finalized in an earlier, separate transaction. Canceling this call does not cancel the earlier approval transaction. Conversely, if the successful 80/20/10 state had already been finalized and a new transaction failed, its rollback point would also be 80/20/10.

Rolling back business changes does not erase the entire transaction-processing history. The outer EVM transaction's nonce, fee settlement, and failure outcome are handled according to the transaction rules. For a Type-4 transaction that designates an account's execution code, valid authorization changes can also survive a business-operation failure. The adapter does not create a separate signed Native transaction or charge a separate Native fee internally. Its execution cost is included in the outer EVM transaction's execution budget. What remains after a transaction fails examines this boundary in more detail by comparing pre-execution rejection, child-call failure, and a full revert.

Putting the common model to use​

Standard-asset regression tests checked allowance use across Native and EVM, the authority of the actual calling contract, and the rollback of balances, allowances, and events when an enclosing call fails. Execution tests for composed policies also exercised Native changes within signed Type-2 and Type-4 transactions, distinguishing an enclosing call's failure from the outer transaction's fee and nonce handling.

Functional acceptance checks using public RPC endpoints, the actual SDK, and a fixed build included approving through Native and spending through ethers, as well as consuming an SDK-created approval in a Native transaction. This evidence establishes the connection for the asset configurations and call paths that were tested. It does not establish every possible contract combination or production performance.

NIGO belongs to the same asset model, but its roles and entry points remain distinct. It has a reserved asset identifier and serves the fee and EVM value roles. Currently, NIGO allowance approval and spending are supported through the Native path. The EVM adapter example for X therefore should not be read as applying unchanged to NIGO allowances.

So far, we have assumed that valid inputs can be prepared. But what if the balance is sufficient and approval is in place, yet a transfer is blocked because the asset is spread across many small cells? Making an asset spendable requires more than knowing the total balance: the system must also find inputs that a single transaction can consume. The next article examines a case where that distinction blocked even a small transfer.