| name | aiken-smart-contract |
| description | Write, test, and debug Aiken smart contracts for Cardano. Use when writing validators, minting policies, or any on-chain Plutus code. Triggers on: Aiken, validator, smart contract, Cardano on-chain, Plutus, minting policy, spend validator, datum, redeemer, plutus.json, blueprint. Covers language syntax, validator patterns, property-based testing, security best practices, stdlib usage, and off-chain MeshJS integration.
|
| user-invocable | true |
Aiken Smart Contract Development
You are an expert Aiken smart contract developer for Cardano. Aiken is a pure
functional language that compiles to UPLC (Untyped Plutus Lambda Calculus)
targeting Plutus V3.
Core Principles
- Validators are predicates โ they return Bool. True = authorize, False = reject.
- No side effects โ pure functional, no mutation, no loops (use recursion).
- Local reasoning only โ eUTxO model means each validator sees only its own context.
- Test everything โ Aiken's test runner uses the real CEK machine. Tests are production-accurate.
- Security first โ understand double satisfaction, datum hijacking, and other eUTxO-specific attacks.
Decision Tree
When asked to write a smart contract:
- Identify the validator purpose: spend, mint, withdraw, publish, vote, propose
- Design the datum and redeemer types before writing logic
- Write the validator using the correct handler signature
- Write tests immediately โ unit tests first, then property-based
- Review for security โ check the security patterns in security.md
- Build and verify โ
aiken build must succeed, aiken check must pass
- Write off-chain integration โ build transactions with MeshJS, test on preview testnet (see offchain.md)
When asked to audit or review a smart contract:
- Follow the auditing methodology in auditing.md
- Phase 1: Understand types, state model, actors, and trust boundaries
- Phase 2: Systematic vulnerability scan against all 11 security categories
- Phase 3: Parameterized validator analysis (if applicable)
- Phase 4: Multi-validator interaction review (if applicable)
- Phase 5: Test coverage assessment โ identify missing tests
- Report findings with severity, location, exploitation path, and fix
Handler Signatures (Aiken v1.1+)
// Spending validator โ most common
validator my_validator {
spend(
datum: Option<MyDatum>, // Always Option โ may be missing
redeemer: MyRedeemer,
output_reference: OutputReference,
transaction: Transaction,
) {
todo
}
}
// Minting policy
validator my_policy {
mint(
redeemer: MyRedeemer,
policy_id: PolicyId,
transaction: Transaction,
) {
todo
}
}
// Withdrawal validator
validator my_withdrawal {
withdraw(
redeemer: MyRedeemer,
credential: Credential,
transaction: Transaction,
) {
todo
}
}
// Certificate publishing
validator my_cert {
publish(
redeemer: MyRedeemer,
certificate: Certificate,
transaction: Transaction,
) {
todo
}
}
// Governance voting
validator my_vote {
vote(
redeemer: MyRedeemer,
voter: Voter,
transaction: Transaction,
) {
todo
}
}
// Governance proposal
validator my_proposal {
propose(
redeemer: MyRedeemer,
proposal_procedure: ProposalProcedure,
transaction: Transaction,
) {
todo
}
}
// Fallback for unhandled purposes
validator my_fallback {
else(script_context: ScriptContext) {
todo
}
}
Multi-Purpose Validators
A single validator can handle multiple purposes (same script hash):
validator token_lock {
mint(redeemer: MintAction, policy_id: PolicyId, tx: Transaction) {
// Minting logic
todo
}
spend(datum: Option<LockDatum>, redeemer: SpendAction, _oref: OutputReference, tx: Transaction) {
// Spending logic โ require token burn
todo
}
}
Parameterized Validators
Validators can take compile-time parameters:
validator my_validator(owner: VerificationKeyHash, deadline: POSIXTime) {
spend(_datum: Option<Data>, _redeemer: Data, _oref: OutputReference, tx: Transaction) {
let must_be_signed = list.has(tx.extra_signatories, owner)
let must_be_after_deadline =
interval.is_entirely_after(tx.validity_range, deadline)
must_be_signed && must_be_after_deadline
}
}
Parameters are applied when building the script address from the blueprint.
Key Language Idioms
// Pattern matching (exhaustive)
when redeemer is {
Lock -> handle_lock(datum, tx)
Unlock -> handle_unlock(datum, tx)
}
// expect โ unsafe downcast, fails if wrong
expect Some(datum) = datum_opt
expect InlineDatum(raw) = output.datum
expect typed_datum: MyDatum = raw
// Pipe operator โ chain operations
tx.outputs
|> list.filter(fn(o) { o.address == script_address })
|> list.any(fn(o) { check_output(o) })
// Trace for debugging (removed in production with --trace-level silent)
trace @"checking signature"
let signed = list.has(tx.extra_signatories, owner)
// ? operator โ postfix, traces expression name if False
list.has(tx.extra_signatories, owner)?
// Produces trace: "list.has(tx.extra_signatories, owner) ? False"
// NOTE: ? is postfix only (expr?), not infix (expr ? "msg")
Common Validation Patterns
// Check transaction signed by key
list.has(tx.extra_signatories, owner_pkh)
// Check time (must be after deadline)
interval.is_entirely_after(tx.validity_range, deadline)
// Check time (must be before deadline)
interval.is_entirely_before(tx.validity_range, deadline)
// Find own input
expect Some(own_input) = transaction.find_input(tx.inputs, oref)
// Find outputs to a script address
transaction.find_script_outputs(tx.outputs, script_hash)
// Check NFT exists in value
assets.quantity_of(value, policy_id, asset_name) == 1
// Merge values
assets.merge(value_a, value_b)
// Check lovelace amount
assets.lovelace_of(output.value) >= min_amount
Testing
Always write tests alongside validators. See testing.md for full details.
// Unit test
test must_be_signed() {
let tx = Transaction {
..transaction.placeholder,
extra_signatories: [mock_signer],
}
my_validator.spend(Some(datum), redeemer, mock_oref, tx)
}
// Expected failure
test must_fail_without_signature() fail {
my_validator.spend(Some(datum), redeemer, mock_oref, transaction.placeholder)
}
// Parameterized validator โ pass params first, then handler args
// validator gift_card(utxo_ref: OutputReference, token_name: ByteArray) { mint(...) }
// Call as: gift_card.mint(utxo_ref, token_name, redeemer, policy_id, tx)
// Property-based test
test prop_any_signer_works(signer via fuzz.bytearray_fixed(28)) {
let datum = MyDatum { owner: signer }
let tx = Transaction {
..transaction.placeholder,
extra_signatories: [signer],
}
my_validator.spend(Some(datum), Unlock, mock_oref, tx)
}
CLI Workflow
aiken new my-project
aiken build
aiken check
aiken check -m "test_name"
aiken fmt
aiken docs
aiken blueprint address
Reference Material
For detailed information, consult:
- Language reference โ types, syntax, modules, encoding
- Validator patterns โ common validator architectures
- Testing guide โ unit, property-based, scenario testing
- Security patterns โ eUTxO attack vectors and mitigations (11 categories)
- Auditing methodology โ structured audit process, severity classification, CIP-52 compliance
- Standard library โ key modules and functions
- Design patterns โ withdraw-zero trick, UTxO indexers, upgrade/migration, etc.
- Gotchas โ compiler pitfalls, type system surprises, testing patterns
- Off-chain integration โ MeshJS transaction building, datum encoding, integration testing
- CIP-113 Programmable Tokens โ multi-validator architecture, registry, transfer flows, E2E testing
Examples
Working examples with full test suites (all compiler-validated):
Phase 1 โ Core Patterns:
- Hello World โ simplest spend validator
- Vesting โ time-locked spending with dual authorization
- Gift Card โ mint+spend dual handler with one-shot NFT
Phase 2 โ Security & Design Patterns:
- Multi-Sig โ M-of-N threshold signatures
- State Machine โ continuing output pattern with state transitions
- NFT Vault โ datum hijacking prevention with NFT authentication
Phase 3 โ Advanced Optimization Patterns:
- Withdraw Zero โ batch validation via withdrawal delegation
- UTxO Indexer โ O(1) input-output linking with redeemer indices
- Tagged Output โ double satisfaction prevention with crypto hashing
- Validity Range โ interval normalisation for time-based validation
- TVMP โ transaction-level validation via minting policy receipt tokens
- Pool Restriction โ certificate-based delegation control with pool whitelist
- Oracle Feed โ reference input authentication with NFT verification
Phase 4 โ Governance:
Phase 5 โ DeFi & Inheritance:
- Escrow โ time-locked two-party exchange with refund/cancel
- Dead Man's Switch โ proof-of-life inheritance with periodic check-in
- Multi-Beneficiary โ percentage-based fund splitting for multiple heirs
Phase 6 โ Marketplace & DAO:
- Marketplace โ NFT listing/buying/cancelling with payment verification
- DAO Vote โ token-weighted governance voting with lock-until-deadline
Phase 7 โ Novel Patterns:
- Notary โ proof-of-existence document notarization (no Cardano equivalent exists)
Production References
Open-source Aiken contracts for studying production-scale implementations.
These go beyond teaching patterns into real-world architecture:
DEX Contracts (Audited, Production):
- Minswap DEX V2 โ Constant product AMM with batching architecture. Order validators, pool validators, batcher flow. Shows how withdraw-zero trick scales to production DEX throughput.
- Minswap Stableswap โ Stableswap curve implementation in Aiken. Advanced math with the
rational module.
- SundaeSwap V3 โ DEX rewritten from Plutus to Aiken. Uses withdraw-zero (
stake.ak) for order batching. Good example of validators/ and lib/ project structure at scale.
Lending & DeFi (Audited, Production):
NFT & Marketplace:
- Nebula (SpaceBudz) โ NFT marketplace contract with bid/offer UTxO model, chain indexer, event listener. Production Aiken.
DAO & Governance:
- Logical Mechanism โ "Distributed Representation" semi-liquid mint-lock-stake DAO. Also Assist library of specialized Aiken functions.
Reusable Libraries:
- Anastasia Labs Design Patterns โ Importable library (
aiken add anastasia-labs/aiken-design-patterns --version v1.1.0). Modules: merkelized validator, multi UTxO indexer, tx level minter, linked list (ordered/unordered), stake validator, parameter validation. Conway+ extensions planned.
- SundaeSwap aicone โ Reusable Aiken utility libraries.
SDK Integration:
- MeshJS Contracts โ Aiken contracts (escrow, marketplace, swap, vesting) with full TypeScript SDK integration. Shows the on-chain โ off-chain bridge.
Learning Resources:
- Awesome Aiken โ Curated list of Aiken libraries, dApps, tutorials.
- Aiken Official Docs โ Language fundamentals and common design patterns.
- Cardano CTF โ 25 challenges teaching real exploit patterns against Plutus/Aiken validators.