Cara Membuat Staking Token CRC20 Coinex Smart Chain – Part 1


Staking pada cryptocurrency adalah mempertaruhkan sejumlah coin atau token kedalam sebuah pool atau smart contract, dengan imbalan reward atau mendapat ticket whitelist untuk IDO. Staking saat ini sudah sangat familier, biasanya digunakan untuk project defi untuk meberikan imbalan kepada komunitas, atau digunakan untuk mendapatkan ticket whitelist atau token lainya seperti NFT (Non Fungiable Token)

Staking Token berjalan di blockchain sepenuhnya, contoh jika anda staking token crc20, maka anda berintraksi langsung dengan smart contract staking di blockchain coinex, tanpa ada campur tangan pihak lain. Pada umumnya, informasi & fitur staking bisa dilihat di blockchain secara langsung, contoh

  • Apakah token akan di lock atau tidak ?
  • Apakah ada fee transaksi atau tidak ?
  • Apakah ada reward berupa token / ticket IDO / NFT ?
  • Atau beberapa fitur lain

Hal di atas bisa anda lihat langsung di smart contract staking, anda bisa melihat dan menelusuri langsung di explorer coinex smart chain. Setiap smart contract staking mempunyai fitur yang berbeda-beda, semua tergantung dari pembuat smart contract atau developer. Bagi para pengguna crypto – defi, staking adalah peluang untuk menghasilkan keuntungan secara pasif, tanpa melakukan perdagangan coin atau token. Staking hanya bisa di jalankan di blockchain yang penggunakan protocol Proof of Stake, contoh Coinex Smart Chain, di blockchain tersebut anda bisa staking coin native coinex (CET) atau staking token crc20/crc721

Untuk membuat Dapps staking anda perlu membuat smart contract, anda bisa menggunakan smart contract open source dari openzepplin. Di Artikel ini kami akan memberikan tutorial cara membuat staking token crc20 di blockchain coinex smart chain. Staking yang kita buat nanti tidak memiliki fitur reward , smart contract staking hanya mempunyai fitur stake, unstake, dan beberapa fitur lainya, smart contract staking ini biasanya digunakan untuk Whitelist IDO.

Contoh penggunaan : ketika ada suatu project (A) ingin melakukan IDO, dan mereka bekerjasama dengan project B, maka siapa saja yang ingin membeli token IDO project A, harus staking token B terlebih dahulu dengan jumlah dan waktu tertentu. Orang lain menyebut ini “Staking untuk Whitelist IDO” atau Staking untuk mendapatkan ticket membeli Token IDO

 

Apa Saja Yang Dibutuhkan ?

1# Wallet EVM (Metamask)

Saya anjurkan anda menggunakan metamask browser, karena lebih mudah digunakan untuk trading atau untuk interact contract dengan blockchain coinex smart chain. Jangan lupa untuk seting RPC blockchain coinx smart chain, seperti di bawah ini

RPC URL : https://rpc.coinex.net
Network Name : Coinex Smart Chain
ChainID : 52
Symbol : CET
Block Explorer : https://www.coinex.net

 

2# Coin CET (Coine Native Blockchain Coinex Smart Chain)

CET merupakan coin native dari blockchain coinex smart chain, anda bisa membeli coin tersebut di Coinex Exchange. Coine CET digunakan untuk membayar semua transaksi di blockchain coinex, seperti deploy, transfer, transfer crc20 dan interact contract seperti staking, unstaking, dll . Setelah anda membeli coin CET, kirim coin tersebut ke wallet EVM anda

 

3# Smart Contract CRC20

Ini adalah smart contract untuk membuat token crc20 coinex smart chain, saya menggunakan code opensource dari openzepplin.anda bisa menggunakan dari source lain, atau merubah / modifikasi sesuai keinginan.

// 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 TokenStake1 is ERC20, ERC20Burnable {
constructor() ERC20("Token Stake 1", "TS1") {
_mint(msg.sender, 1000000 * 10 ** decimals());
}
}

 

4# Smart Contract Staking

Ini adalah smart contract staking, menggunakan code dari openzepplin open sorce, anda bisa custom smart contract tersebut jika menginginkan perubahan pada smart contract, anda bisa menggunakan smart contract tersebut secara gratis, membagikan ke orang lain dan bebas untuk merubah sesuai keinginan.

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/interfaces/IERC20.sol";

contract StakeMyToken is ReentrancyGuard, Ownable {
address public TOKEN;
uint256 public UNSTAKEABLE_FEE = 9200; // How much can they Unstake? 92% AKA 8% Staking FEE
uint256 public MINIMUM_CONTRIBUTION_AMOUNT = 1 ether; // Minimum Token Amount to Stake
bool public CONTRACT_RENOUNCED = false; // for ownerOnly Functions

string private constant NEVER_CONTRIBUTED_ERROR = "This address has never contributed Tokens to the protocol";
string private constant NO_ETH_CONTRIBUTIONS_ERROR = "No Token Contributions";
string private constant MINIMUM_CONTRIBUTION_ERROR = "Contributions must be over the minimum contribution amount";

struct Staker {
address addr; // The Address of the Staker
uint256 lifetime_contribution; // The Total Lifetime Contribution of the Staker
uint256 contribution; // The Current Contribution of the Staker
uint256 yield; // The Current Yield / Reward amount of the Staker
uint256 last_yield_time; // The previous yield claim time.
uint256 unstakeable; // How much can the staker withdraw.
uint256 joined; // When did the Staker start staking
bool exists;
}

mapping(address => Staker) public stakers;
address[] public stakerList;
constructor() ReentrancyGuard() {

}

receive() external payable {}
fallback() external payable {}

function SweepToken() external onlyOwner {
uint256 a = IERC20(TOKEN).balanceOf(address(this));
// Do whatever with tokens sent to the contract (used to send initial bnb to get farms/yields going)
}

function UpdateToken(address _token) external onlyOwner {
TOKEN = _token;
}

function AddStakerYield(address addr, uint256 a) private {
stakers[addr].yield = stakers[addr].yield + a;
}

function RemoveStakerYield(address addr, uint256 a) private {
stakers[addr].yield = stakers[addr].yield - a;
}

function RenounceContract() external onlyOwner {
CONTRACT_RENOUNCED = true;
}

function ChangeMinimumStakingAmount(uint256 a) external onlyOwner {
MINIMUM_CONTRIBUTION_AMOUNT = a;
}

function ChangeUnstakeableFee(uint256 a) external onlyOwner {
UNSTAKEABLE_FEE = a;
}

function UnstakeAll() external onlyOwner {
if(CONTRACT_RENOUNCED == true){revert("Unable to perform this action");}
for (uint i = 0; i < stakerList.length; i++) {
address user = stakerList[i];
ForceRemoveStake(user);
}
}

function Stake(uint256 amount) external {
// Users must approve this contract to spend their tokens first.
require(amount >= MINIMUM_CONTRIBUTION_AMOUNT, MINIMUM_CONTRIBUTION_ERROR);
require(IERC20(TOKEN).transferFrom(msg.sender, address(this), amount), "Unable to transfer your tokens to this contract");
uint256 unstakeable = (amount * UNSTAKEABLE_FEE) / 10000;

if(StakerExists(msg.sender)){
stakers[msg.sender].lifetime_contribution = stakers[msg.sender].lifetime_contribution + amount;
stakers[msg.sender].contribution = stakers[msg.sender].contribution + unstakeable;
stakers[msg.sender].unstakeable = stakers[msg.sender].unstakeable + unstakeable;
}else{
// Create new user
Staker memory user;
user.addr = msg.sender;
user.contribution = unstakeable;
user.lifetime_contribution = amount;
user.yield = 0;
user.exists = true;
user.unstakeable = unstakeable;
user.joined = block.timestamp;
// Add user to Stakers
stakers[msg.sender] = user;
stakerList.push(msg.sender);
}

// Staking has completed (or failed and won't reach this point)
uint256 c = (10000 - UNSTAKEABLE_FEE);
uint256 fee = (amount * c) / 10000;
// Staking fee is stored as fee, use as you wish
}

function RemoveStake() external {
address user = msg.sender;
if(!StakerExists(user)){ revert(NEVER_CONTRIBUTED_ERROR); }
uint256 uns = stakers[user].unstakeable;
if(uns == 0){ revert("This user has nothing to withdraw from the protocol"); }
// Proceed to Unstake user funds from 3rd Party Yielding Farms etc

// Remove Stake
stakers[user].unstakeable = 0;
stakers[user].contribution = 0;
IERC20(TOKEN).transfer(user, uns);
}

function ForceRemoveStake(address user) private {
// withdraw avAVAX for WAVAX and Unwrap WAVAX for AVAX
if(!StakerExists(user)){ revert(NEVER_CONTRIBUTED_ERROR); }
uint256 uns = stakers[user].unstakeable;
if(uns == 0){ revert("This user has nothing to withdraw from the protocol"); }
// Proceed to Unstake user funds from 3rd Party Yielding Farms etc

// Remove Stake
stakers[user].unstakeable = 0;
stakers[user].contribution = 0;
IERC20(TOKEN).transfer(user, uns);
}
/*

CONTRIBUTER GETTERS

*/
function StakerExists(address a) public view returns(bool){
return stakers[a].exists;
}

function StakerCount() public view returns(uint256){
return stakerList.length;
}

function GetStakeJoinDate(address a) public view returns(uint256){
if(!StakerExists(a)){revert(NEVER_CONTRIBUTED_ERROR);}
return stakers[a].joined;
}

function GetStakerYield(address a) public view returns(uint256){
if(!StakerExists(a)){revert(NEVER_CONTRIBUTED_ERROR);}
return stakers[a].yield;
}

function GetStakingAmount(address a) public view returns (uint256){
if(!StakerExists(a)){revert(NEVER_CONTRIBUTED_ERROR);}
return stakers[a].contribution;
}

function GetStakerPercentageByAddress(address a) public view returns(uint256){
if(!StakerExists(a)){revert(NEVER_CONTRIBUTED_ERROR);}
uint256 c_total = 0;
for (uint i = 0; i < stakerList.length; i++) {
c_total = c_total + stakers[stakerList[i]].contribution;
}
if(c_total == 0){revert(NO_ETH_CONTRIBUTIONS_ERROR);}
return (stakers[a].contribution * 10000) / c_total;
}

function GetStakerUnstakeableAmount(address addr) public view returns(uint256) {
if(StakerExists(addr)){ return stakers[addr].unstakeable; }else{ return 0; }
}

function GetLifetimeContributionAmount(address a) public view returns (uint256){
if(!StakerExists(a)){revert("This address has never contributed DAI to the protocol");}
return stakers[a].lifetime_contribution;
}

function CheckContractRenounced() external view returns(bool){
return CONTRACT_RENOUNCED;
}

}

 

Cara Membuat Staking Token CRC20 Coinex Smart Chain

1# Deploy Token CRC20

Untuk step awal, anda harus deploy token crc20 menggunakan smart contract yang kami sediakan di atas, Buka Remix IDE Coinex https://ide.coinex.net/

  • Buat file baru, contoh token.sol dan masukan smart contract
  • Compile smart contract tersebut
  • Deploy smart contract & tunggu sampai transaksi terkonfirmasi sepenuhnya di blockchain (3-5 detik selesai)

 

2# Deploy Staking Smart Contract

Step sama seperti di atas, gunakan remix ide coinex untuk deploy smart contract staking.

  • Buat file baru, contoh stakingtoken.sol dan masukan smart contract staking
  • Compile smart contract tersebut, jika ada warning skip saja
  • Deploy smart contract staking & tunggu sampai transaksi terkonfirmasi sepenuhnya di blockchain (3-5 detik selesai)

 

3# Verifikasi Smart Contract CRC20 & Staking

Setelah proses pembuatan token crc20 selesai dan pembuatan smart contract staking selesai, tahap selanjutnya adalah verifikasi smart contract tersebut ke explorer coinex smart chain,, verifikasi ini sangat diperlukan untuk transparansi smart contract dan memudahkan user untuk interact dengan smart contract tersebut, karena ketika smart contract terverifikasi, semua informasi yang ada di smart contract tersebut tercantum di halaman explorer coinex smart chain, user bisa menilai apakah ada kesalahan code atau kecurangan di smart contract tersebut.

  • Install plugin flattener di Remix IDE coinex, aktifkan
  • Flat 2 file smart contract tersebut (token crc20 dan staking)
  • Simpan 2 file baru (hasil dari flattener tersebut)
  • Buka smart contract  token crc20 dan staking di explorer, lakukan verifikasi dengan cara klik menu “contract info” klik “verify & publish”
  • Masukan semua informasi yang dibutuhkan sepert nama contract, jenis compiler, versi compiler, jenis file , dll
  • Jika sudah terisi dengan benar dan lengkap, klik verifikasi / publish

 

Lanjut ke Part 2


Alif Fahmi

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