A collection of utility lock scripts and type scripts for the Nervos CKB blockchain. This project provides various proxy mechanisms, time-based locks, and other useful smart contract primitives.
This repository contains 8 different smart contracts designed to provide flexible locking mechanisms and utility functions for CKB applications:
- Lock Proxy Lock - Delegates unlocking authority to another lock script
- Input Type Proxy Lock - Unlocks when a specific type script appears in transaction inputs
- Output Type Proxy Lock - Unlocks when a specific type script appears in transaction outputs
- Single Use Lock - Can only be unlocked by consuming a specific outpoint
- Time Lock - Since-based lock (time/block/epoch) with additional lock script verification
- Type Burn Lock - Unlocks when a specific type script is burned (appears in inputs but not outputs)
- Easy to Discover Type - Reveals cell data through type script arguments
- Always Success - A simple script that always succeeds (for testing purposes)
- Rust toolchain with
riscv64imac-unknown-none-elf
target - Clang (for building)
- Make
- Clone the repository:
git clone https://github.com/ckb-ecofund/ckb-proxy-locks.git
cd ckb-proxy-locks
- Install the required Rust target:
make prepare
- Build all contracts:
make build
- Run tests:
make test
To build a specific contract:
make build CONTRACT=lock-proxy-lock
Purpose: Delegates unlocking authority to another lock script.
How it works:
- Takes a 32-byte lock script hash as argument
- Can be unlocked if any input cell uses the specified lock script
- Useful for creating hierarchical permission systems
Arguments:
args[0..32]
: Hash of the owner lock script
Use cases:
- Multi-signature wallets
- Delegated authority systems
- Hierarchical access control
Purpose: Unlocks when a specific type script appears in transaction inputs.
How it works:
- Takes a 32-byte type script hash as argument
- Can be unlocked if any input cell has the specified type script
- Enables type-script-based authorization
Arguments:
args[0..32]
: Hash of the required input type script
Use cases:
- Token-gated access
- NFT-based permissions
- Conditional unlocking based on asset ownership
Purpose: Unlocks when a specific type script appears in transaction outputs.
How it works:
- Takes a 32-byte type script hash as argument
- Can be unlocked if any output cell has the specified type script
- Useful for ensuring certain assets are created in the transaction
Arguments:
args[0..32]
: Hash of the required output type script
Use cases:
- Ensuring token minting
- Conditional payments
- Asset creation requirements
Purpose: Can only be unlocked by consuming a specific outpoint.
How it works:
- Takes an outpoint (36 bytes) as argument
- Can only be unlocked if the specified outpoint appears in transaction inputs
- Provides one-time unlock capability
Arguments:
args[0..36]
: The specific outpoint that must be consumed
Use cases:
- One-time payments
- Voucher systems
- Single-use authorizations
Purpose: Time-based lock with additional lock script verification.
How it works:
- Requires both time conditions and lock script presence
- Takes a lock script hash (32 bytes) and since value (8 bytes) as arguments
- Can only be unlocked after the specified since condition is met AND when the required lock script is present
- Uses CKB's
since
field mechanism for time/block-based constraints
Arguments:
args[0..32]
: Hash of the required lock scriptargs[32..40]
: Since value (8 bytes, little-endian) - can represent block number, epoch, or timestamp
Use cases:
- Vesting schedules
- Time-delayed payments
- Escrow with time conditions
Purpose: Unlocks when a specific type script is burned (destroyed).
How it works:
- Takes a 32-byte type script hash as argument
- Can be unlocked only when the specified type script appears in inputs but NOT in outputs
- Ensures the type script is consumed/burned in the transaction
Arguments:
args[0..32]
: Hash of the type script that must be burned
Use cases:
- Token burning mechanisms
- Proof of destruction
- Conditional unlocking based on asset burning
Purpose: A type script that reveals cell data through its arguments.
How it works:
- Takes a 32-byte data hash as argument
- Validates that all output cells with this type script have data matching the hash
- Makes cell data discoverable through the type script arguments
Arguments:
args[0..32]
: Hash of the expected cell data
Use cases:
- Data integrity verification
- Making cell data easily discoverable
- Content addressing
Purpose: A utility script that always succeeds.
How it works:
- Simply returns success (0) without any validation
- Used primarily for testing and development
Use cases:
- Testing and development
- Placeholder scripts
- Unconditional success scenarios
├── contracts/ # Individual contract implementations
│ ├── always-success/
│ ├── easy-to-discover-type/
│ ├── input-type-proxy-lock/
│ ├── lock-proxy-lock/
│ ├── output-type-proxy-lock/
│ ├── single-use-lock/
│ ├── time-lock/
│ └── type-burn-lock/
├── tests/ # Integration tests
├── build/ # Compiled binaries
├── scripts/ # Build scripts
└── deployment.toml # Deployment configuration
The project uses a workspace structure with individual Makefiles for each contract. The root Makefile coordinates building all contracts.
Build all contracts:
make build
Build in debug mode:
make build MODE=debug
Build specific contract:
make build CONTRACT=time-lock
Tests are located in the tests/
directory and use the ckb-testtool
framework.
Run all tests:
make test
Run tests with output:
make test CARGO_ARGS="-- --nocapture"
Check code:
make check
Run clippy:
make clippy
Format code:
make fmt
The project includes a deployment.toml
configuration file for deploying contracts to CKB networks. All contracts are configured with enable_type_id = false
for simpler deployment.
For reproducible builds, you can generate checksums:
make checksum
This creates a build/checksums-release.txt
file with SHA256 hashes of all built contracts.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass:
make test
- Submit a pull request
To generate a new contract from template:
make generate CRATE=my-new-contract
This will create a new contract in contracts/my-new-contract/
and update the workspace configuration.
This project is open source. Please check the individual contract files for specific license information.
This project was bootstrapped with ckb-script-templates.