Skip to content

How to Spend an Expired Ergo Box#

Spending an expired Ergo box involves satisfying specific conditions that differ from spending a regular box. The following criteria must be met:

Conditions for Spending an Expired Box#

  1. Storage Fee Duration: The box must have been retained for at least the designated storage fee period. This is validated by calculating the difference between the height of the upcoming block, as indicated in the preheader, and the creation height of the box. This difference should be greater than or equal to the storage fee period.
  2. Spending Proof: For an expired box, the spending proof must be left empty, eliminating the need for cryptographic authorization for the box's spending.
  3. Storage Rent Awareness: If the expired box is affected by storage rent, it must be processed through the appropriate storage rent mechanism. The node validates the rent conditions; an external storage-rent endpoint is not a consensus requirement.

Code Snippet for Verifying Storage Fee Duration#

The following line of code checks whether the box has been stored for the required minimum duration, comparing the height of the upcoming block (context.preHeader.height) with the box's creation height (context.self.creationHeight):

context.preHeader.height - context.self.creationHeight >= Constants.StoragePeriod

Reference: ErgoInterpreter.scala, line 73

Spending Proof for Expired Boxes#

The term "spending proof" typically refers to a cryptographic authorization required for spending a box. However, in the context of an expired box, this requirement is waived. The spending proof for the expired box must be empty, meaning that no cryptographic validation is needed to authorize its spending. This allows any participant to spend the expired box without needing to prove ownership, as long as the storage fee duration condition is fulfilled.

Additional Details for Spending an Expired Box#

If both the above conditions are met, the expired box can be spent by anyone. To do so, one needs to provide an index of a newly recreated box (or an index of any box, if the expired box lacks sufficient funds for the storage fee) in the context extension variable #127, which will be stored as part of the input.

Storage Rent-Specific Handling#

  1. Custom Block Candidate Endpoint

    • Miningcore introduces support for querying custom block candidates that include expired boxes.
    • This is done via a configurable SrUrl, which must point to an external service exposing a /blocks/query endpoint.
    • This service is not part of the official Ergo node and must be implemented separately.
  2. Integration with Mining Pools

    • Mining pools using this fork of Miningcore can use MiningRequestSRBlockCandidateAsync() to fetch candidate blocks that account for expired boxes.
    • This enables pools to mine transactions that reclaim storage rent from old, unspent boxes.
  3. Implementation in ErgoClient

    • The ErgoClient class was updated to accept a separate SrUrl base address, which it uses only when calling MiningRequestSRBlockCandidateAsync().
    • This method builds a request to GET {SrUrl}/blocks/query, expecting a response in the same format as a regular Ergo mining candidate.
    • The actual service must be custom-built to return valid WorkMessage objects with expired box logic included.
  4. Spending an Expired Box Affected by Storage Rent

    • If an expired box cannot cover its calculated rent, the native validation path can consume it fully while naming an existing output index.
    • Additional inputs may be needed for the rest of the transaction, but are not a blanket rent top-up requirement.
    • This mechanism ensures that outdated UTXOs do not remain in the state indefinitely and that rent is either paid or reclaimed.

Summary#

With these changes, expired Ergo boxes can be properly mined and spent under storage rent conditions. While the Ergo node enforces storage rent rules during validation, v6.0.8 provides native mining-time collection, while external custom-candidate services remain an alternative integration.

Native Node Collection and Validation#

Reference-client v6.0.8 provides a native collection path: enable ergo.node.mining, ergo.node.extraIndex, and ergo.node.storageRentCollection, then wait for the index to catch up. An external custom-candidate service is an optional integration path rather than a requirement for native collection. Mainnet normally filters empty-proof rent claims from the mempool, so native claims go directly into candidate blocks.

From height 1,885,000, transaction validation requires distinct values for context-extension variable 127 across inputs that carry it. Separate expired boxes must not share one recreation output index. The rent interpreter also checks the recreation's creation height against the spending height; preserving the old creation height is not enough.

If a box cannot cover its calculated rent, the native rent path can consume it fully while naming an existing output index. There is no general requirement to add another input solely to top up that box's rent. Ordinary transaction conservation, output, and mining-policy rules still apply.

Proposed Rent Rule Changes#

EIP-53 proposes a grace period for underfunded token/register boxes. EIP-51 proposes rent-paying refresh within that window, while EIP-52 includes miner-attested claims. These remain proposals, including open reference implementations; they do not establish an activated grace period or attestation rule. The shipped mempool policy and native collection settings above are separate from those proposed consensus changes.