# 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="/pages/0UYb0mh54mqwYz8XblJv" %}
[Connect to Chiliz Chain](/develop/basics/connect-to-chiliz-chain.md)
{% 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="/pages/Af9548Yd4RQMNgtsUkq9" %}
[Obtain Free Testnet Tokens](/develop/basics/obtain-free-testnet-tokens.md)
{% endcontent-ref %}

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

{% content-ref url="/pages/cwZqLlr1ee8FwupJJUCc" %}
[Deploy with Remix](/develop/basics/deploy-a-smart-contract/deploy-with-remix.md)
{% 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.

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="/pages/DUqAvWtmu3FJYbH3fPN4" %}
[About Fan Tokens](/learn/about-fan-tokens.md)
{% 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.chiliz.com/develop/basics/write-a-smart-contract.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
