Near protocol sharding separates transaction inclusion from cross-shard completion
Near protocol sharding divides state and processing among parallel shards, while receipts carry authorized work to each receiver account. To assess cross-shard execution, follow the transaction into every non-refund receipt, inspect each terminal status, and confirm the intended return value or state change. Block inclusion confirms that the transaction reached a block, not completion of the full receipt chain.
An application therefore needs two views: the execution graph and the resulting state or return value. The graph exposes routing, failures, callbacks, and refunds. The result check establishes whether the requested operation produced the condition that the user or contract expected.
Receipt Routing Across Shards
A submitted transaction first produces an execution outcome that identifies an action receipt. The receiver account determines where that receipt must execute. Its destination chunk processes the actions, and contract code may create further receipts. This chain, rather than the signed envelope alone, holds the work that can cross shard boundaries.
When a transaction affects an account on another shard, the runtime routes its receipt to the shard containing that receiver account.
An action receipt requests work such as a transfer or function call. A data receipt carries a completed promise result to an action receipt that is waiting for it. Either type can connect one execution step to another, while every executed receipt records its own outcome, executor, resource use, logs, and any newly created receipt identifiers.
Account state remains colocated within one shard, so execution goes to the state rather than copying that state between shards.
The branching structure matters most when a contract calls other contracts. One successful branch does not establish that a sibling branch succeeded. A branch ends when its final non-refund receipt reaches a terminal outcome without creating another non-refund receipt. The transaction remains incomplete until every relevant branch reaches that point.
Chunks Keep Parallel Work Under One Chain
Chunks let NEAR process shard state in parallel without presenting each shard as a separate blockchain. A block coordinates the chunks associated with the network state, while each chunk carries work and commitments for its shard. Validators can verify the relevant transitions through chunk data and state roots. This structure preserves one chain-level history, yet an application must still distinguish transaction inclusion from the later execution of receipts in destination chunks.
Same-Shard and Cross-Shard Execution Boundaries
Application behavior should follow receipt semantics rather than assume that current account placement creates synchronous execution. Cross-contract calls use asynchronous promises, even when two accounts happen to occupy the same shard. This rule prevents application correctness from depending on a shard layout that can change through protocol upgrades or resharding.
Calls aimed at one contract may place several actions in one receipt. Those batched actions execute as a unit, and a failure reverts that receipt’s actions. Calls to separate contracts create independent work with separate outcomes. Their state changes do not form one automatic rollback boundary, so a later failure cannot erase an earlier successful receipt on another execution path.
Independent Calls and Partial Effects
Asynchronous execution creates a period in which the initiating contract has finished, but a remote call or callback remains pending. Other transactions can interact with the contract during that interval. Contract logic must protect any temporary state and define what should happen when the remote operation returns success, failure, or an unexpected value.
A cross-contract call and its callback execute independently, so failure in the called contract does not automatically reverse earlier state changes. A callback can inspect the promise result and apply a compensating update when the application requires one.
Gas also belongs to individual execution steps. The remote function and its callback each need enough prepaid gas for their own receipt. A callback failure can leave the earlier call completed without its intended follow-up. Refund receipts return unused amounts through the receipt system, but they do not repair application state or replace explicit failure handling.
What Proves That Cross-Shard Execution Finished?
Executed non-refund receipt outcomes and the intended return value or state change establish completion; the required finality milestone depends on the decision. An INCLUDED response establishes block inclusion but says nothing about downstream completion. EXECUTED_OPTIMISTIC waits for non-refund receipts to execute without requiring their blocks to be final. INCLUDED_FINAL confirms that the transaction’s block is final but does not wait for receipt execution. EXECUTED waits for the transaction’s block to be final and for all non-refund receipts to finish, while FINAL also waits until every receipt execution, including refunds, is final. Accounting processes may therefore require a stricter milestone than an interface that only needs a readable result.
A wait milestone still needs interpretation. Inspect the transaction outcome and every relevant receipt outcome for failures, then read the destination account or contract state. Runtime success means that execution completed without a protocol-level failure; it does not prove that an application-specific return value, balance change, or stored record matches the intended operation.
A Cross-Shard Completion Checklist
Start with either a status interface that exposes receipt outcomes or a direct transaction-status query. Both options must establish the same boundary: every relevant non-refund branch has stopped producing pending work, and the requested return value or state change is observable. If the first tool shows only inclusion, use an endpoint that supports an executed wait level and receipt details.
- Retain the transaction hash and signer account ID used by the status query.
- Select the weakest wait milestone that still satisfies the application’s finality requirement.
- Follow child receipt identifiers until each relevant branch has a terminal outcome.
- Record failures, executors, and logs without treating logs alone as completion evidence.
- Decode the relevant return value, or query the affected account or contract state, and compare the result with the requested operation.
Mark the operation complete only when the terminal outcomes and observed result match the requested operation. If receipt detail is unavailable, keep the original hash and retry the status lookup through a compatible endpoint. Do not create a replacement transaction merely because one interface lacks enough evidence.
Congestion, Delay, and Incomplete Evidence
Receipt execution can take longer when a destination chunk cannot process its entire incoming queue. The producer can place remaining receipts in a delayed queue for later chunks. Cross-shard work is therefore not guaranteed to finish in the next block.
An RPC timeout has a similarly narrow meaning: the requested wait milestone was not reached before that endpoint’s deadline. Poll the same transaction hash before considering a new submission. An UNKNOWN_TRANSACTION response can reflect an incorrect transaction hash or sender account ID, or a provider that no longer retains the record. None of those responses, by itself, proves execution failure.
Resharding and Durable Integration Choices
Resharding changes the shard layout and may move an account’s state assignment at an epoch boundary. Application code remains durable when it addresses accounts, creates promises, and evaluates receipt outcomes without hard-coding shard numbers. Indexers and diagnostic tools that need physical placement must resolve it against the relevant block or epoch. The decision changes only when a task depends on low-level shard location rather than the account-level execution result.
FAQ
Does a Successful top-level Status Cover Every Downstream Contract Call?
Not necessarily. Returning a promise delegates the transaction’s reported return value and status to that promise; returning a value or nothing does not. Independently created calls can therefore have separate receipt outcomes even when the initiating receipt succeeded. Inspect the receipt tree when the application depends on every downstream branch.
Can Independent Receipts From One Transaction Finish in a Different Order?
Yes. Independent receipts can enter different shard queues and complete in separate chunks, so their order should not be inferred from the order in which calls were created. A callback with declared promise dependencies waits for the required results. Unrelated branches may progress independently and should be reconciled by their receipt identifiers and terminal outcomes.
Is a Returned False Value the Same as a Failed Receipt?
No. A function can execute successfully and return a value that decodes to false, an empty value, or another application-defined result. That receipt still has a successful runtime outcome. A failed receipt instead reports an execution failure. Status handling must decode the return value and apply the contract’s own success condition.
Why Might an Attached Deposit Return to a Contract Instead of the Original Signer?
A calling contract supplies an attached deposit from its own account when it creates the remote function-call receipt. If that remote call fails, the deposit returns to the calling contract. It does not automatically travel onward to the user who initiated the original transaction. The callback must issue any user refund required by the application’s rules.