How to Create a Crowdsale (ICO) on Coinex Smart Chain Blockchain

Blockchain companies that are just starting out, more often do Initial Coin Offering (ICO) or Crowdsale to raise funds from the public. ICO/Crowdsale is the process of selling digital cryptocurrecy units or tokens to investors, with the aim of raising money, which later the money will be used to develop projects.

The ICO or Crowdsale system is actually very simple, namely the investor sends (example) ETH to the project address, and in return is the investor receives the tokens stored in the smart contract, the number of tokens received depends on the amount of ETH sent and the token price rate, ICO tokens are usually will be received automatically, after the investor successfully sends ETH.

ICO-Crowdsale usually runs on a blockchain that supports smart contract features, such as Ethereum, Coinex Smart Chain, Polygon. The process of selling ICO tokens is carried out automatically by smart contracts, the process of sending ICO tokens and native coins runs automatically too, this makes it very easy for project developers to raise funds.

In this article we will provide a tutorial on How to Create an ICO Crowdsale on the Coinex Smart Chain Blockchain. You can apply this method or use it when you want to raise funds. Making an ICO is very easy, it only takes a few steps, the ICO can be used immediately. Why should I choose Coinex Smart Chain? Because the CSC blockchain has high performance, transaction processing is very fast, EVM support and transaction fees are very cheap.

What You Need to Prepare to Make an ICO Crowdsale

1.  EVM Wallet

You can use the Metamask wallet to make a crowdsale, Metamask is available for Android and browser versions, I recommend using the browser version to make the process easier.

2.  Coin CET (Coin Native Coinex Smart Chain)

You need CET coins to pay for transactions on the Coinex Smart Chain blockchain-network, to get CET coins you can buy them on Coinex Exchange. If you have already purchased, send CET to your wallet

3. Token CRC20

Because we will raise funds by selling tokens, then you prepare a crc20 token which you will sell to investors. To create CRC20, you can use the Openzeplin smart contract.

4. Smart Contract Crowdsale

There are several types of ICO/Crowdsale smart contracts, in this article we will use the public crowdsale, without any other features.


How to Make a Crowdsale ICO on Coinex Smart Chain
1. Deploy Token CRC20 

Deploy the smart contract below using the remix ethereum IDE, please change the details of the name, supply and token symbol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";

contract CSCCryptoVIR1 is ERC20, ERC20Burnable {
constructor() ERC20("CSC CryptoVIR 1", "CSVR1") {
_mint(msg.sender, 1000000000 * 10 ** decimals());

Compile the smart contract, and deploy it using the “Injected Web3” Environment – After that, confirm it in your metamask wallet.


2. Deploy Smart Contract Crowdsale

This smart contract is a public smart crowdsale, so anyone can buy ico tokens, without a whitelist system. There are several things you need to set before deploying crodwsale,

  • Token Rate: this is the price for each token. The token sale will use native CET coins, for example if the rate is (1000 tokens for 1 CET) then when an investor sends 100 CET, he will receive 100,000 ico tokens.
  • Wallet Address: wallet address that will receive CET coins (the proceeds from the sale of ico tokens), all sales will go to the wallet.
  • Smart Contract Address token ICO: we need to enter the smart contract address of the token ico when we deploy the cmart contract crowdsale process

Smart Contract Crowdsale

// SPDX-License-Identifier: MIT
pragma solidity 0.5.17;

library Address {
function isContract(address account) internal view returns (bool) {
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
assembly { codehash := extcodehash(account) }
return (codehash != accountHash && codehash != 0x0);

contract Context {
constructor () internal { }
function _msgSender() internal view returns (address payable) {
return msg.sender;

contract ReentrancyGuard {
bool private _notEntered;
constructor () internal {
_notEntered = true;

modifier nonReentrant() {
require(_notEntered, "ReentrancyGuard: reentrant call");
_notEntered = false;


_notEntered = true;

library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");

return c;

function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");

function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;

return c;

function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;

uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");

return c;

interface ERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);

library SafeERC20 {
using SafeMath for uint256;
using Address for address;

function safeTransfer(ERC20 token, address to, uint256 value) internal {
callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));

function safeTransferFrom(ERC20 token, address from, address to, uint256 value) internal {
callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));

function callOptionalReturn(ERC20 token, bytes memory data) private {
require(address(token).isContract(), "SafeERC20: call to non-contract");

(bool success, bytes memory returndata) = address(token).call(data);
require(success, "SafeERC20: low-level call failed");

if (returndata.length > 0) { // Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");

contract ICO is Context, ReentrancyGuard {
using SafeMath for uint256;
using SafeERC20 for ERC20;
ERC20 private _mytoken;
address payable private _wallet;
uint256 private _ethRate;
uint256 private _mytokenDelivered;
event MyTokenPurchased(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
constructor (uint256 ethRate, address payable wallet, ERC20 mytoken) public {

require(ethRate > 0, "ICO: ethRate shouldn't be Zero");
require(wallet != address(0), "ICO: wallet is the Zero address");
require(address(mytoken) != address(0), "ICO: token is the Zero address");
_ethRate = ethRate;
_wallet = wallet;
_mytoken = mytoken;

function mytokenAddress() public view returns (ERC20) {
return _mytoken;

function teamWallet() public view returns (address payable) {
return _wallet;

function ethRate() public view returns (uint256) {
return _ethRate;

function mytokenDelivered() public view returns (uint256) {
return _mytokenDelivered;

function () external payable {

function buyMyTokenWithEther() public nonReentrant payable {
address beneficiary = _msgSender();
uint256 ethAmount = msg.value;
uint256 ContractBalance = _mytoken.balanceOf(address(this));
require(ethAmount > 0, "You need to sendo at least some Ether");
uint256 _mytokenAmount = _getEthRate(ethAmount);
_preValidatePurchase(beneficiary, _mytokenAmount);
require(_mytokenAmount <= ContractBalance, "Not enough MyToken in the reserve");
_mytokenDelivered = _mytokenDelivered.add(_mytokenAmount);
_processPurchase(beneficiary, _mytokenAmount);
emit MyTokenPurchased(_msgSender(), beneficiary, ethAmount, _mytokenAmount);
_updatePurchasingState(beneficiary, _mytokenAmount);
_postValidatePurchase(beneficiary, _mytokenAmount);

function _preValidatePurchase(address beneficiary, uint256 Amount) internal view {
require(beneficiary != address(0), "ICO: beneficiary is the zero address");
require(Amount != 0, "ICO: Amount is 0");
this; // silence state mutability warning without generating bytecode - see

function _postValidatePurchase(address beneficiary, uint256 Amount) internal view {

function _deliverMyToken(address beneficiary, uint256 mytokenAmount) internal {
_mytoken.safeTransfer(beneficiary, mytokenAmount);

function _processPurchase(address beneficiary, uint256 mytokenAmount) internal {
_deliverMyToken(beneficiary, mytokenAmount);

function _updatePurchasingState(address beneficiary, uint256 Amount) internal {

function _getEthRate(uint256 ethAmount) internal view returns (uint256) {
return ethAmount.mul(_ethRate);

function _forwardEtherFunds() internal {

contract LimitedUnitsIco is ICO {
using SafeMath for uint256;

uint256 private _maxMyTokenUnits;

constructor (uint256 maxMyTokenUnits) public {
require(maxMyTokenUnits > 0, "Max Capitalization shouldn't be Zero");
_maxMyTokenUnits = maxMyTokenUnits;

function maxMyTokenUnits() public view returns (uint256) {
return _maxMyTokenUnits;

function icoReached() public view returns (bool) {
return mytokenDelivered() >= _maxMyTokenUnits;

function _preValidatePurchase(address beneficiary, uint256 Amount) internal view {
super._preValidatePurchase(beneficiary, Amount);
require(mytokenDelivered().add(Amount) <= _maxMyTokenUnits, "Max MyToken Units exceeded");

Deploy using Remix-Ethereum-IDE, enter Rate details (token price per 1 CET), Wallet that will accommodate sales proceeds and Smart Contract CRC20


3. Send ICO Tokens to Smart Contract Address Crowdsale

After the smart contract creation is complete, you need to send crc20 ICO tokens to the crowdsale contract address, the number of tokens sent is in accordance with the initial sales allocation, the amount depends on your tokenomics project.


4. Test Crowdsale / Buying ICO Tokens

To buy ico tokens or participate in the crowdsale is very easy, you only need to send native CET coins to the crowdsale address (crowdsale smart contract address). After you send CET coin, you will receive ico tokens according to the token price rate, this process is automatic, you will receive tokens immediately without having to wait for unlock or vesting.

I tried to buy ico tokens by sending CET coins to the crowdsale address, within 7 seconds I immediately received the ico tokens, it’s fantastic, the coinex smart chain blockchain is really very fast, and the transaction fees are very cheap. With the crowdsale, you can easily raise project funds, without having to pay fees to other parties

Alif Fahmi

hi , I'm Alif, I'm a blockchain & cryptocurrency lover, I love writing & learning, my job is web developer & crypto trader