name: aiken-smart-contracts description: "Aiken workflows: validators, building, blueprints, .plutus generation. Safe guidance for smart contract development." allowed-tools: - Bash(aiken:) - Bash(cardano-cli:) - Read - Write context: - "!aiken --version 2>&1 | head -3" - "!aiken --help 2>&1 | head -20" metadata: {"openclaw":{"emoji":"\ud83e\uddf0","requires":{"anyBins":["cardano-cli","docker"]},"install":[{"id":"brew","kind":"brew","formula":"colima docker docker-compose curl","bins":["colima","docker","docker-compose","curl"],"label":"Install Docker runtime (Colima) + Docker CLI + Compose + curl (brew)","os":["darwin","linux"]}]}}
aiken-smart-contracts
When to use
- Writing or auditing Aiken validators
- Building and testing smart contracts
- Generating .plutus artifacts for CLI/MeshJS
Operating rules (must follow)
- Confirm Aiken version before generating code
- Verify script hashes after every rebuild
- Test on preprod/preview before mainnet
- Treat datum/redeemer schemas as versioned APIs
Workflow
1. Initialize project
aiken new my-project
cd my-project
2. Project structure
my-project/
├── aiken.toml # Project config
├── lib/ # Reusable modules
├── validators/ # Validator entry points
│ └── my_validator.ak
└── plutus.json # Generated blueprint
3. Write validator
// validators/my_validator.ak
use aiken/transaction.{ScriptContext}
validator {
fn spend(datum: Data, redeemer: Data, ctx: ScriptContext) -> Bool {
// Your validation logic
True
}
}
4. Build and test
# Build all validators
aiken build
# Run tests
aiken check
# Format code
aiken fmt
5. Generate artifacts
# Blueprint is auto-generated at plutus.json
# Extract .plutus for cardano-cli:
aiken blueprint convert > my_validator.plutus
# Get script hash
cardano-cli conway transaction policyid \
--script-file my_validator.plutus
6. Derive script address
cardano-cli conway address build \
--payment-script-file my_validator.plutus \
--testnet-magic 1 \
--out-file script.addr
Examples
Example: Simple spending validator
User request: "Create a validator that only allows spending by a specific pubkey"
Response:
// validators/pubkey_lock.ak
use aiken/hash.{Blake2b_224, Hash}
use aiken/transaction.{ScriptContext, Spend}
use aiken/transaction/credential.{VerificationKey}
type Datum {
owner: Hash<Blake2b_224, VerificationKey>
}
type Redeemer {
// Could be unit if no redeemer data needed
}
validator {
fn spend(datum: Datum, _redeemer: Redeemer, ctx: ScriptContext) -> Bool {
let ScriptContext { transaction, purpose } = ctx
expect Spend(_) = purpose
// Check if owner signed the transaction
list.has(transaction.extra_signatories, datum.owner)
}
}
# Build
aiken build
# Test
aiken check
# Generate .plutus
aiken blueprint convert > pubkey_lock.plutus
Example: Parameterized validator
User request: "Create a time-locked validator"
Response:
// validators/time_lock.ak
use aiken/interval.{Finite, Interval, IntervalBound}
use aiken/transaction.{ScriptContext, ValidityRange}
type Datum {
lock_until: Int // POSIX time in milliseconds
}
validator {
fn spend(datum: Datum, _redeemer: Data, ctx: ScriptContext) -> Bool {
let valid_range: ValidityRange = ctx.transaction.validity_range
// Check if current time is past lock_until
when valid_range.lower_bound.bound_type is {
Finite(tx_earliest_time) -> tx_earliest_time > datum.lock_until
_ -> False
}
}
}
V3 considerations (Conway)
- Single unified context argument
- Datum may be optional for some patterns
- Governance script purposes available
- Use
aiken build --plutus-version v3if targeting V3
Safety / key handling
- Datum/redeemer are on-chain visible—no secrets
- Version your datum schemas (breaking changes break funds)
- Verify script hash matches after any rebuild
- Always test with small amounts first
References
shared/PRINCIPLES.md- Aiken documentation
cardano-cli-plutus-scripts(for deployment)