# Write a Smart Contract

From the moment you decide to create a dApp on Chiliz Chain, you need to take the specifics of our blockchain into account.

While Chiliz Chain is EVM-compatible, treating it exactly like Ethereum can lead to usability issues, specifically regarding token decimals and gas mechanics.

Let's explore!

## Prerequisites

### Environment

Before you start writing your contract, make sure that your environment is ready.

First, you must have a wallet configured for Spicy Testnet (for development) or Chiliz Chain Mainnet (for production).

{% content-ref url="connect-to-chiliz-chain" %}
[connect-to-chiliz-chain](https://docs.chiliz.com/develop/basics/connect-to-chiliz-chain)
{% endcontent-ref %}

Second, you will need need $CHZ to pay for gas deployment on both Testnet and Mainnet. While you can buy Mainnet $CHZ on any crypto exchange, you can rely on faucets for Testnet tokens.

{% content-ref url="obtain-free-testnet-tokens" %}
[obtain-free-testnet-tokens](https://docs.chiliz.com/develop/basics/obtain-free-testnet-tokens)
{% endcontent-ref %}

In terms of tooling, you can rely on Hardhat or Remix. See for instance:

{% content-ref url="deploy-a-smart-contract/deploy-with-remix" %}
[deploy-with-remix](https://docs.chiliz.com/develop/basics/deploy-a-smart-contract/deploy-with-remix)
{% endcontent-ref %}

Finally, Chiliz Chain contracts are written in the Solidity language:

{% embed url="<https://www.soliditylang.org/>" %}

{% embed url="<https://solidity-by-example.org/>" %}

### Fan Tokens / CAP-20

The most specific aspect of Chiliz Chain is the CAP-20 standard, used for Fan Tokens.&#x20;

While technically identical to the ERC-20 standard code-wise, CAP-20 tokens have a specific configuration for decimals. In short: It uses 0 decimals, while regular ERC-20 token use 18 decimals.

{% content-ref url="../../learn/about-fan-tokens" %}
[about-fan-tokens](https://docs.chiliz.com/learn/about-fan-tokens)
{% endcontent-ref %}

Therefore, if you deploy a Fan Token with 18 decimals, it may not display correctly in ecosystem wallets or be compatible with future Socios.com integrations.

## Best practices in writing a smart contract

### Use Battle-Tested Libraries (OpenZeppelin)

Do not start from creating your contract from scratch.\
The single most effective security practice is to base your code on community-audited standards, to reduce the risk of vulnerabilities

For Chiliz Chain development, we strongly recommend using [OpenZeppelin Contracts](https://docs.openzeppelin.com/contracts). They provide secure and community-vetted implementations for tokens contracts.

By using standard contracts, your ensure that your tokens are compatible with known wallets (like MetaMask) and the Chiliz ecosystem (Socios.com).

### General EVM Best Practices

Regardless of the chain, these three patterns are non-negotiable for secure Solidity development.

#### The "Checks-Effects-Interactions" Pattern

This is your primary defense against [Reentrancy Attacks](https://solidity-by-example.org/hacks/re-entrancy/). Always structure your functions in this exact order:

1. Checks: Validate inputs and conditions (e.g., `require` statements).
2. Effects: Update the contract state (e.g., reduce balances).
3. Interactions: Interact with other contracts or send funds (e.g., `transfer`).

#### Robust Access Control

Never leave sensitive functions unprotected. If a function mints tokens, changes fees, or upgrades logic, it must be restricted.

* Simple: Use `Ownable` for single-admin contracts.
* Complex: Use `AccessControl` for contracts requiring multiple roles (e.g., `MINTER_ROLE`, `ADMIN_ROLE`).

#### Input Validation

Assume all input is malicious. Use `require()` statements at the very beginning of your functions to validate parameters.

For instance:

* Check for zero addresses (`address(0)`).
* Check for zero amounts when transferring.
* Verify array lengths match if passing multiple arrays.
* etc.

### Chiliz-Specific Implementation Details

While Chiliz Chain is EVM-compatible, certain "local rules" apply, specifically regarding token decimals and EVM versions.

#### CAP-20 Compliance (Fan Tokens)

If you are writing a contract that interacts with Fan Tokens (e.g., a Staking Pool for $PSG or $BAR), you must handle 0 decimals.

This means:

* Do not assume `1 Token = 10^18 units`. For Fan Tokens, `1 Token = 1 unit`.
* Avoid hardcoding `1e18` in your math if your contract is meant to be generic. Use the `token.decimals()` function dynamically.

#### EVM Version & Compiler

Chiliz Chain is compatible with the "Shanghai" EVM version.\
The recommended Solidity Version is `0.8.24`.

### Gas Optimization on Chiliz

Transactions on Chiliz Chain are significantly cheaper than Ethereum, but unoptimized code can still lead to congestion or failed transactions during high-traffic events (e.g., during a live match).

Here are three ways to save on gas:

* Use Custom Errors: Instead of long string messages in `require`, use `error` definitions to save gas.
* Order your state variables to fit into 32-byte slots. Put `uint128`, `address`, and `bool` next to each other where possible.
* Prefer `external` for functions that are never called internally by the contract itself.
