AirdropCovenant enforces fixed-size BCH/FT claims with permissionless claim submission plus claim-authority co-signing, and authority-only administration.
Contract path: contracts/core/distribution/AirdropCovenant.cash
CashScript version: ^0.13.0
Constructor Parameters (Bytecode-Embedded)
| Parameter | Type | Description |
|---|---|---|
vaultId | bytes32 | Links to source vault |
authorityHash | bytes20 | Controls pause/resume/cancel |
claimAuthorityHash | bytes20 | Backend-held claim co-signer hash for eligibility/rate-limit enforcement |
amountPerClaim | int | Fixed amount per claim |
totalPool | int | Total distribution pool |
startTimestamp | int | Claims open time. 0 = immediate. |
endTimestamp | int | Claims close time. 0 = no expiry. |
NFT State (40 bytes)
Transaction Structure
All entrypoints spend the covenant UTXO attx.inputs[0].
| Function | Required outputs | Notes |
|---|---|---|
claim | tx.outputs[0] claimant payout, tx.outputs[1] updated covenant UTXO | locktime enforces start/end window and is written into state. |
pause | tx.outputs[0] updated covenant UTXO | Status ACTIVE -> PAUSED. |
resume | tx.outputs[0] updated covenant UTXO | Status PAUSED -> ACTIVE. |
cancel | tx.outputs[0] authority payout | Campaign UTXO is consumed (no continuing state output required). |
Functions
claim(bytes20 claimerHash, sig claimAuthSig, pubkey claimAuthPubkey)
Claim submission is permissionless. The claimer does not sign; backend claim-authority co-signs after eligibility checks.
Validation
hash160(claimAuthPubkey) == claimAuthorityHashcheckSig(claimAuthSig, claimAuthPubkey)- Current status is
ACTIVE - Time window checks (
startTimestamp,endTimestamp) if configured newTotalClaimed = totalClaimed + amountPerClaimmust stay<= totalPool
tx.outputs[0]must payclaimerHashwithamountPerClaim(BCH or FT mode by flag bit2).tx.outputs[1]must keep same locking bytecode and token category as input.tx.outputs[1].nftCommitmentmust encode:- updated
total_claimed - updated
claims_count last_claim_timestamp = tx.locktimestatus = COMPLETEDwhennewTotalClaimed >= totalPool, elseACTIVE
- updated
pause(sig authSig, pubkey authPubkey)
resume(sig authSig, pubkey authPubkey)
cancel(sig authSig, pubkey authPubkey)
Authority-only admin paths (hash160(authPubkey) == authorityHash, valid signature).
Pause / Resume
pauserequiresstatus == ACTIVEand cancelable flag bit0 set.resumerequiresstatus == PAUSED.- Both require output
0to keep covenant locking bytecode and token category with updated status commitment.
- Allowed only from
ACTIVEorPAUSED, with cancelable flag bit0 set. - Computes
remainingPool = totalPool - totalClaimed, requiresremainingPool > 0. tx.outputs[0]must payauthorityHashwithremainingPool(BCH or FT mode by flag bit2).

