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-elftarget - 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 testTo build a specific contract:
make build CONTRACT=lock-proxy-lockPurpose: 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
sincefield 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 buildBuild in debug mode:
make build MODE=debugBuild specific contract:
make build CONTRACT=time-lockTests are located in the tests/ directory and use the ckb-testtool framework.
Run all tests:
make testRun tests with output:
make test CARGO_ARGS="-- --nocapture"Check code:
make checkRun clippy:
make clippyFormat code:
make fmtThe 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 checksumThis 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-contractThis 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.