Advanced
How to create a smart contract on Bitcoin Cash
What is CashScript?
CashScript is a high-level programming language for smart contracts on Bitcoin Cash. It offers a strong abstraction layer over Bitcoin Cash’ native virtual machine, Bitcoin Script. Its syntax is based on Ethereum’s smart contract language Solidity, but its functionality is very different since smart contracts on Bitcoin Cash differ greatly from smart contracts on Ethereum. For a detailed comparison of them, refer to the blog post Smart Contracts on Ethereum, Bitcoin and Bitcoin Cash.
If you’re interested to see what kind of things can be built with CashScript, you can look at the Showcase or Examples. If you just want to dive into CashScript, refer to the Getting Started page and other pages in the documentation.
Getting Started
Installing the CashScript compiler
The command line CashScript compiler cashc
can be installed from NPM.
npm install -g cashc
Installing the JavaScript SDK
The JavaScript SDK can be installed into your project with NPM.
Copy
npm install cashscript
CAUTION
CashScript only offers a JavaScript SDK, but CashScript contracts can be integrated into other languages as well. Because there are no ready-to-use SDKs available for them, this is considered advanced usage, and it is recommended to use the JavaScript SDK.
Writing your first smart contract
There are some examples available on the Examples page, that can be used to take inspiration from. Further examples of the JavaScript integration can be found on GitHub. A simple example is included below.
pragma cashscript ^0.7.0; contract TransferWithTimeout(pubkey sender, pubkey recipient, int timeout) { // Allow the recipient to claim their received money function transfer(sig recipientSig) { require(checkSig(recipientSig, recipient)); } // Allow the sender to reclaim their sent money after the timeout is reached function timeout(sig senderSig) { require(checkSig(senderSig, sender)); require(tx.time >= timeout); } }
TIP
Read more about the CashScript language syntax in the Language Description.
Integrating into JavaScript
While more detailed examples are available on GitHub, we show an integration of the TransferWithTimeout
contract in a JavaScript project.
After compiling the contract file to an artifact JSON with cashc, it can be imported into the CashScript SDK.
Copy
cashc ./transfer_with_timeout.cash --output ./transfer_with_timeout.json
const { ElectrumNetworkProvider, Contract, SignatureTemplate } = require('cashscript'); const { alice, bob, alicePk, bobPk } = require('./keys'); async function run() { // Import the TransferWithTimeout JSON artifact const artifact = require('./transfer_with_timeout.json'); // Initialise a network provider for network operations const provider = new ElectrumNetworkProvider('mainnet'); // Instantiate a new TransferWithTimeout contract const contract = new Contract(artifact, [alicePk, bobPk, 600000], provider); // Call the transfer function with Bob's signature // i.e. Bob claims the money that Alice has sent him const transferDetails = await contract.functions .transfer(new SignatureTemplate(bob)) .to('bitcoincash:qrhea03074073ff3zv9whh0nggxc7k03ssh8jv9mkx', 10000) .send(); console.log(transferDetails); // Call the timeout function with Alice's signature // i.e. Alice recovers the money that Bob has not claimed const timeoutDetails = await contract.functions .timeout(new SignatureTemplate(alice)) .to('bitcoincash:qqeht8vnwag20yv8dvtcrd4ujx09fwxwsqqqw93w88', 10000) .send(); console.log(timeoutDetails); }
Command Line Interface
The cashc
command line interface is used to compile CashScript .cash
files into .json
artifact files. These artifacts can be imported and used by the JavaScript SDK or other libraries / applications that use CashScript. For more information on this artifact format refer to Artifacts.
Installation
You can use npm
to install the cashc
command line tool globally.
npm install -g cashc
Usage
The cashc
CLI tool can be used to compile .cash
files to JSON artifact files.
Usage: cashc [options] [source_file] Options: -V, --version Output the version number. -o, --output <path> Specify a file to output the generated artifact. -h, --hex Compile the contract to hex format rather than a full artifact. -A, --asm Compile the contract to ASM format rather than a full artifact. -c, --opcount Display the number of opcodes in the compiled bytecode. -s, --size Display the size in bytes of the compiled bytecode. -?, --help Display help