I’m exploring what Bitcoin Cash contract development in a Haskell DSL could look like and this is the, work in progress, result. Although this is op-code level script programming, Haskell’s abstraction mechanisms, strong typing, property based testing, and tooling such as the Language Server Protocol, makes it into a beast of its own. The project also provides a VM supporting the BCH 2025 features, which can be used to test arbitrary BCH bytecode. This is alpha software.
albaDsl
AlbaDsl is a shallowly embedded Domain Specific Language (DSL) for programming Bitcoin Cash Script (2025) in Haskell. It uses Haskell’s type system to statically enforce the type of the input and output stacks of a given program. Stack items can be assigned names for easier reference. Haskell functions can be used as a form of statically typed parameterized macros. Collections of such macros can be grouped into libraries and complex contracts can be built from them. Standard Haskell tooling such as syntax highlighting, code formatting, and Language Server Protocol (LSP) can be used. When using the Haskell Language Server, it gives immediate feedback about type errors such as mismatched stack element types.
Bitcoin Cash contracts written in albaDsl can be assembled into transactions and serialized into byte strings for publishing to the network using, for example, Bitcoin Cash Node.
albaVm
AlbaVm is a Bitcoin Cash virtual machine written in Haskell. It supports the BCH 2025 instruction set (including tokens, BigInts, and VM limits). It passes the Libauth 2025 standard and non-standard “success vectors”, and part of the non-standard and invalid “failure vectors” (correct failure reasons yet to be verified). AlbaVm can be used to evaluate arbitrary BCH byte code, and specifically albaDsl programs during development and testing.
Combining albaDsl & albaVm to verify contracts
Given an albaDsl program ‘p’, the albaDsl compiler ‘compile’ and the albaVm evaluator ‘eval’, it is possible to combine them into a function ‘g = eval (compile p)’. This function can be used to calculate the result of applying ‘p’ to arbitrary input stacks. Thus it can be used to write unit tests for the program. Such tests can make use of automatic property based testing via Haskell’s QuickCheck. Possibly, the LiquidHaskell program verifier can also be used for verification.
The example contracts in this repository (transferWithTimeout and lastWill) illustrate how contracts can be built and tested.