Sigil is a next-generation WebAssembly-based framework for writing, deploying, and executing smart contracts on Bitcoin through the Kontor metaprotocol. It is designed to make contract development feel like writing normal software rather than learning a specialized domain-specific language. Developers who know Rust can write Sigil contracts with minimal additional concepts, using familiar tools like cargo and the Rust analyzer. Contracts compile to WebAssembly bytecode, which is then published to Bitcoin in a Kontor transaction and executed by indexers when called.
WebAssembly is a natural choice for blockchain smart contracts because it offers deterministic execution, efficient bytecode, and broad language support. However, most WASM-based blockchain platforms treat contracts as isolated modules with custom ABIs for host interaction—requiring developers to manually serialize data, manage dependencies, and coordinate interfaces through ad-hoc conventions. Sigil takes a different approach by adopting the WebAssembly Component Model, a standardized system for composing WASM modules with typed interfaces. This means contracts can call each other with full type safety, interfaces are specified in a language-agnostic IDL (WIT), and integration errors are caught at compile time rather than discovered when transactions fail on-chain.
In Sigil, contracts export functions with explicit signatures defined in WIT. If Contract A calls Contract B, Sigil generates a typed stub for B’s interface that A imports at compile time. If B’s interface changes—say, adding a field to a struct or modifying a function parameter—A will fail to compile until the change is addressed. This eliminates an entire class of bugs common in other smart contract systems, where interface mismatches cause runtime failures after deployment. The same type checking applies to storage: Sigil’s storage system uses a path-based hierarchy with Rust traits that ensure you can’t accidentally store the wrong type at a given path or retrieve a value with an incorrect type annotation.
A Sigil contract defines an init function (called once when the contract is deployed), procedural functions that can read and write state, and view functions that are read-only. Functions receive a context object that provides access to the transaction signer, enables cross-contract calls, and exposes storage operations. Storage is lazy-loaded—reading a value queries the database only for that specific path rather than deserializing an entire contract state object. This makes gas costs predictable and proportional to actual usage. Cross-contract calls are synchronous and type-checked; the callee executes immediately within the caller’s transaction, and re-entrancy is prohibited to prevent common exploit patterns.
Sigil provides simple macros that generate the necessary boilerplate, allowing developers to focus on application logic rather than framework integration. The contract! macro sets up the module structure and WIT bindings. The #[derive(Storage)] macro generates typed accessors for contract state. Cross-contract calls use the import! macro to pull in another contract’s interface and generate a local stub. The result is code that looks like ordinary Rust: strongly typed, well-integrated with language tooling, and testable using standard Rust test frameworks. Because the runtime primitives are abstracted behind traits, the same contract code runs in unit tests (with an in-memory backend) and on-chain (with the indexer’s SQLite backend) without modification.