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!

The Playground supports 'Mocknet', allowing you to create virtual UTXOs for development without having to get Testnet coins and set up a Testnet wallet.

tip

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

Here are the 5 simple steps for creating your first smart contract transaction with the Playground:

  1. Compile a contract, for example the default TransferWithTimeout contract.
  2. Create a new contract in the 'New Contract' tab by providing the contract arguments.
  3. Add UTXOs to the smart contract address and the wallets used for testing.
  4. Next, go to the TransactionBuilder select the contract and the function to invoke
  5. Finally, specify the in- and outputs for the transaction and click 'Send'!

Creating a CashScript Contract

To get started coding locally we will use a code editor 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.

prerequisites
  • 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 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 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 earlier.

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!