Skip to main content

Getting Started

Try CashScript Online

To get started with writing CashScript smart contracts quickly, it is recommended to try out the CashScript Playground, a web application which lets you easily write and create contracts!

Here you will learn what a CashScript contract looks like through the TransferWithTimeout example contract. Then you can compile the contract and provide the contract arguments to create a smart contract address. To actually create the smart contract itself, you fund the address so that it has a UTXO on the contract address. After setting up the smart contract, you can try spending from the smart contract by invoking a contract function!

tip

The CashScript Playground is a great way to get started without doing any JavaScript coding to set up wallets, fetch balances and invoke contract functions. This way you can focus on learning one thing at a time!

Creating a CashScript Smart Contract

With the CashScript playground there's a nice integrated editor to get started, as well as an integrated compiler to change your CashScript contract into a Contract Artifact behind the scenes. Now, to get started we will have to set up a CashScript editor — outside of the Playground — and learn how to work with the cashc compiler to create CashScript contract artifacts.

Prerequisites

To write CashScript smart contracts locally you use a code editor. For the best developer experience, we recommend to use VS Code with the CashScript extension. This way it will automatically recognize .cash files and offer highlighting and autocompletion.

prerequisties
  • Basic familiarity with the command line
  • Node.js installed
  • A code editor (VS Code recommended)
tip

To set up your CashScript developer environment, see the Syntax Highlighting guide.

Installing the CashScript compiler

The command line CashScript compiler cashc can be installed from NPM.

npm install -g cashc

Writing your first smart contract

Open your code editor to start writing your first CashScript smart contract. We can start from a basic TransferWithTimeout smart contract. Create a new file TransferWithTimeout.cash.

The TransferWithTimeout contract takes in 3 contract arguments and has 2 contract functions: transfer and timeout.

pragma cashscript ^0.10.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

There are some other examples available on the Examples page that can be used to take inspiration from. Further examples of the TypeScript and JavaScript integration can be found on GitHub.

Compiling your smart contract

The next step after writing your smart contract is using the command line compiler to create a contract artifact, so that it can be imported into the CashScript SDK.

cashc ./TransferWithTimeout.cash --output ./TransferWithTimeout.json

This will create an artifact file TransferWithTimeout.json from your CashScript file. If you look at the bytecode property on the artifact you will see the raw BCH script generated by the cashc compiler:

OP_3 OP_PICK OP_0 OP_NUMEQUAL OP_IF OP_4 OP_ROLL OP_ROT OP_CHECKSIG OP_NIP OP_NIP OP_NIP OP_ELSE OP_3 OP_ROLL OP_1 OP_NUMEQUALVERIFY OP_3 OP_ROLL OP_SWAP OP_CHECKSIGVERIFY OP_SWAP OP_CHECKLOCKTIMEVERIFY OP_2DROP OP_1 OP_ENDIF

Creating a CashScript Transaction

After creating a contract artifact, we can now use the TypeScript SDK to initialise the smart contract and to invoke spending functions on the smart contract UTXOs. We'll continue with the TransferWithTimeout artifact generated in the previous steps.

info

The CashScript SDK is written in TypeScript meaning that you can either use TypeScript or vanilla JavaScript to use the SDK. It's recommended to use TypeScript for full type-safety of all you contract logic.

Installing the TypeScript SDK

The TypeScript SDK can be installed into your project with NPM. Note that CashScript is a pure ESM package.

npm install cashscript

Initialising a Contract

Now to initialise a contract we will import the ElectrumNetworkProvider and Contract classes from the CashScript SDK. We also need to import the contract artifact. Lastly, we need public keys from a generated key-pair to use as arguments for contract initialisation.

import { ElectrumNetworkProvider, Contract } from 'cashscript';
import artifact from './TransferWithTimeout.json';
import { alicePub, bobPub } from './keys.js';

// Initialise a network provider for network operations
const provider = new ElectrumNetworkProvider('chipnet');

// Instantiate a new TransferWithTimeout contract
const contractArguments = [alicePub, bobPub, 100000n];
const options = { provider };
const contract = new Contract(artifact, contractArguments, options);

// Get the contract address and info about its balance
console.log("Contract address: " + contract.address);
console.log("Contract balance: " + await contract.getBalance());
console.log("Contract UTXOs: " + await contract.getUtxos());
tip

For a code example of how to generate key-pairs with Libauth, see the CashScript Examples' common.ts file where Alice and Bob's key-pairs are created.

Creating a Transaction

Lastly, to spend from the smart contract we've initialised, you need to make sure there is an actual contract balance on the smart contract address. In other words, we need to make sure there's at least one UTXO with the smart contract locking bytecode, so that we can spend from it!

import { ElectrumNetworkProvider, Contract, SignatureTemplate } from 'cashscript';
import { alicePub, bobPriv, bobPub } from './keys.js';
import artifact from './TransferWithTimeout.json';

// Initialise a network provider for network operations
const provider = new ElectrumNetworkProvider('chipnet');

// Instantiate a new TransferWithTimeout contract
const contractArguments = [alicePub, bobPub, 100000n];
const options = { provider };
const contract = new Contract(artifact, contractArguments, options);

// 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(bobPriv))
.to('bitcoincash:qrhea03074073ff3zv9whh0nggxc7k03ssh8jv9mkx', 10000n)
.send();

console.log(transferDetails);

Congrats 🎉! You've successfully created a transaction spending from a Bitcoin Cash smart contract!