Building DApps on Zilliqa with Scilla Smart Contracts

Zilliqa uses sharding to achieve high throughput. If you need a blockchain that handles thousands of transactions per second, it is worth checking out. The platform uses Scilla for smart contracts. Scilla is designed to prevent common vulnerabilities like reentrancy attacks.

What is Scilla?

Scilla stands for Smart Contract Intermediate-Level Language. It is a functional language with formal verification in mind. The syntax looks different from Solidity. You will see explicit state management and separation between computation and communication.

Setting Up Your Environment

Install the Zilliqa JavaScript library:

npm install @zilliqa-js/zilliqa

You will also need:

  • A Zilliqa wallet (ZilPay works well)
  • Access to Zilliqa testnet or mainnet
  • The Scilla IDE for contract development

Writing a Basic Smart Contract

Here is a simple counter contract in Scilla:

scilla_version 0

library SimpleCounterLib

let one = Uint32 1

contract SimpleCounter

field count : Uint32 = Uint32 0

procedure IncreaseCount()
  c <- count;
  count := c + one
end

transition Increase()
  IncreaseCount();
  event Increased(count)
end

Breaking this down:

  • scilla_version 0 declares the Scilla version
  • library defines reusable values
  • field declares contract state
  • procedure is internal logic (not callable externally)
  • transition is the public interface

The arrow operator (<-) reads from state. The assignment operator (:=) writes to state. Events emit logs for frontend listeners.

Testing Your Contract

Use the Scilla IDE at ide.zilliqa.com. Paste your contract and run the checker. It catches type errors and potential issues before deployment.

You can also use the Scilla interpreter locally:

scilla-checker -libdir stdlib -gaslimit 10000 contract.scilla

Deploying to Testnet

Use Zilliqa-JS to deploy:

const { Zilliqa } = require('@zilliqa-js/zilliqa');
const { BN, units } = require('@zilliqa-js/util');

const zilliqa = new Zilliqa('https://dev-api.zilliqa.com');

// Add your private key
zilliqa.wallet.addByPrivateKey(privateKey);

const code = `your scilla code here`;
const init = [];

const contract = zilliqa.contracts.new(code, init);

const [deployTx, deployedContract] = await contract.deploy({
  gasPrice: units.toQa('2000', units.Units.Li),
  gasLimit: Long.fromNumber(10000)
});

console.log('Contract address:', deployedContract.address);

Calling Contract Transitions

After deployment, call transitions like this:

const callTx = await deployedContract.call(
  'Increase',
  [],
  {
    gasPrice: units.toQa('2000', units.Units.Li),
    gasLimit: Long.fromNumber(10000)
  }
);

console.log('Transaction ID:', callTx.id);

Building the Frontend

Connect your frontend using Zilliqa-JS or ZilPay. ZilPay injects a wallet provider similar to MetaMask.

if (window.zilPay) {
  const zilPay = window.zilPay;
  await zilPay.wallet.connect();

  const contract = zilPay.contracts.at(contractAddress);
  const tx = await contract.call('Increase', []);
}

Key Differences from Ethereum

  • Scilla separates pure computation from blockchain state
  • No reentrancy possible by design
  • Gas model differs from EVM
  • Addresses use bech32 format (zil1...)

Next Steps

Start with the testnet. Get test ZIL from the faucet. Deploy simple contracts first. Read the Scilla documentation for advanced patterns like ADTs and message passing between contracts.

The Zilliqa developer portal has more examples and tutorials. Join the Discord for community support.