In the name of Allah, the Most Gracious, the Most Merciful.
Ini adalah catatan ketiga belajar blockchain.
touch test/Token.js
const { ethers } = require("hardhat");
const { expect } = require("chai");
describe("Token", () => {
it("has a name", async() => {
// fetch token from blockchain
const Token = await ethers.getContractFactory("Token")
let token = await Token.deploy()
// read token name
const name = await token.name()
// check token name is correct
expect(name).to.equal("Dallan")
})
})
Kode di atas adalah contoh dari sebuah test unit yang ditulis menggunakan tools seperti Hardhat dan Chai. Test unit ini digunakan untuk menguji smart contract yang disebut "Token". Pada kode ini, terdapat satu "describe" block yang diberi label "Token" dan satu "it" block didalamnya. "Describe" block digunakan untuk memberikan deskripsi umum dari apa yang diuji dalam test unit tersebut, sedangkan "it" block digunakan untuk memberikan deskripsi spesifik dari pengujian yang dilakukan.
Pengujian yang dilakukan dalam "it" block tersebut adalah untuk memastikan bahwa smart contract Token memiliki nama yang sesuai. Pertama, kode menggunakan objek ethers untuk mengambil factory contract dari smart contract "Token" yang didefinisikan di dalam kode. Kemudian smart contract tersebut di-deploy ke jaringan dan digunakan untuk memanggil fungsi name() yang diharapkan akan me-return nama dari smart contract tersebut. Kemudian, kode menggunakan fungsi expect dari library chai untuk membandingkan nama dari smart contract tersebut dengan nilai yang diharapkan ("Dallan").
Jika nama dari smart contract tersebut sesuai dengan yang diharapkan, maka tes ini akan berhasil dan tidak menghasilkan error. Namun, jika nama yang diterima tidak sesuai dengan yang diharapkan, maka tes ini akan gagal dan akan menghasilkan error yang akan ditampilkan pada output.
npx hardhat test


Lanjut mengkoding Token.sol untuk memenuhi standar erc-20 pada dokumentasi ini
string public symbol = "DLN";
update test/Token.js
it("has correct symbol", async() => {
// fetch token from blockchain
const Token = await ethers.getContractFactory("Token")
let token = await Token.deploy()
// read token symbol
const symbol = await token.symbol()
// check token symbol is correct
expect(symbol).to.equal("DLN")
})
lakukan pengujian kembali

supaya kode di bawah tidak ditulis berulang kali, gunakan fungsi beforeEach
// fetch token from blockchain
const Token = await ethers.getContractFactory("Token")
let token = await Token.deploy()
hasilnya seperti ini:
const { ethers } = require("hardhat");
const { expect } = require("chai");
describe("Token", () => {
let token
beforeEach(async() => {
// fetch token from blockchain
const Token = await ethers.getContractFactory("Token")
token = await Token.deploy()
})
it("has a name", async() => {
// read token name
const name = await token.name()
// check token name is correct
expect(name).to.equal("Dallan")
})
it("has correct symbol", async() => {
// read token symbol
const symbol = await token.symbol()
// check token symbol is correct
expect(symbol).to.equal("DLN")
})
})
Ini adalah kode JavaScript yang digunakan untuk melakukan pengujian pada smart contract yang disebut "Token" menggunakan tool bernama Hardhat dan library Chai.
Pada baris pertama, kode ini mengimport objek "ethers" dari paket "hardhat" dan objek "expect" dari paket "chai". Objek "ethers" digunakan untuk bekerja dengan smart contract pada blockchain, sementara objek "expect" digunakan untuk menuliskan asumsi yang harus dipenuhi oleh smart contract yang diuji.
Setelah itu, ada sebuah fungsi "describe" dengan parameter "Token", yang digunakan untuk menjelaskan apa yang diuji dalam pengujian ini.
Didalam fungsi tersebut, ada sebuah variable token yang akan diisi dari hasil deploy dari contract factory "Token" pada fungsi beforeEach() yang dijalankan sebelum setiap pengujian.
Lalu ada dua fungsi "it" dengan parameter yang berbeda, yang digunakan untuk menjelaskan apa yang diuji dalam setiap pengujian. Pada fungsi pertama, kode akan mengecek apakah nama dari token sesuai dengan yang diharapkan dengan mengeksekusi perintah .name() pada token dan mengecek apakah hasilnya sama dengan string "Dallan" menggunakan perintah expect(). Pada fungsi kedua, kode akan mengecek apakah simbol dari token sesuai dengan yang diharapkan dengan mengeksekusi perintah .symbol() pada token dan mengecek apakah hasilnya sama dengan string "DLN" menggunakan perintah expect().
Supaya kodingannya lebih bersih nan rapih, pindahhkan nilai variabel name dan symbol ke parameter fungsi expect menggantikan parameter name dan symbol sebelumnya alih-alih dijadikan nilai variabel, sehingga hasilnya jadi seperti ini:
const { ethers } = require("hardhat");
const { expect } = require("chai");
describe("Token", () => {
let token
beforeEach(async() => {
// fetch token from blockchain
const Token = await ethers.getContractFactory("Token")
token = await Token.deploy()
})
it("has a name", async() => {
// check token name is correct
expect(await token.name()).to.equal("Dallan")
})
it("has correct symbol", async() => {
// check token symbol is correct
expect(await token.symbol()).to.equal("DLN")
})
})
Ini adalah sebuah skrip testing untuk sebuah kontrak smart contract yang bernama "Token" menggunakan library "hardhat" dan "chai" di JavaScript. Skrip ini mengecek nama dan simbol dari token yang di-deploy di blockchain.
Secara umum, skrip ini melakukan hal-hal berikut:
Memuat library "hardhat" dan "chai" yang digunakan untuk mengeksekusi skrip ini.Mendefinisikan sebuah blok "describe" yang berisi dua blok "it" yang menjelaskan dua fungsi yang akan diuji.Blok "beforeEach" dijalankan sebelum setiap fungsi "it", digunakan untuk meng-instantiate kontrak smart contract baru dari "Token" dari blockchainFungsi "it" pertama mengecek nama dari token yang di-deploy dengan mengeksekusi fungsi "name()" dari kontrak dan mengecek apakah sesuai dengan string "Dallan" menggunakan "expect" dari chai.Fungsi "it" kedua mengecek simbol dari token yang di-deploy dengan mengeksekusi fungsi "symbol()" dari kontrak dan mengecek apakah sesuai dengan string "DLN" menggunakan "expect" dari chai.
Lanjut mengkoding Token.sol tambahkan variabel decimals dengan nilai 18, variabel ini bertipe uint256 di mana maksudnya adalah uint (angka non negatif, dan 256 pada jumlah bits. Nilai 18 adalah standar erc-20 di mana ada 18 angka di belakang koma.
uint256 public decimals = 18;
Update Token.js
it("has correct decimals", async() => {
// check token symbol is correct
expect(await token.decimals()).to.equal("18")
})
lakukan testing contract

lanjut mengkoding Token.sol. Kali ini mendeklarasikan variabel totalSuply menggunakan satuan wei, jadi rumusnya total suplai x 10^18
uint256 public totalSuply = 1000000 * (10 ** decimals); // total suply diubah ke satuan wei
lalu update kembali Token.js
it("has correct total suply", async() => {
// check token total suply is correct
const value = ethers.utils.parseUnits("1000000", "ether")
expect(await token.totalSuply()).to.equal(value)
})
ethers.utils.parseUnits("1000000", "ether") adalah fungsi dari library Ethers.js yang digunakan untuk mengubah input angka dari satuan wei (yang merupakan satuan dasar dalam Ethereum) ke satuan yang lebih besar, seperti ether.
Fungsi ini menerima dua argumen:
Input angka yang akan dikonversi, dalam contoh ini adalah "1000000"Satuan tujuan yang ingin digunakan, dalam contoh ini adalah "ether"
Jadi, hasil dari ethers.utils.parseUnits("1000000", "ether") adalah sebuah bilangan yang menunjukkan bahwa 1000000 wei setara dengan 1 ether.
Informasi tambahan, 1 Ether setara dengan 10^18 wei, jadi dari kode diatas, 1000000 wei setara dengan 1 Ether Jadi angka 1000000 adalah total suply token.
Jangan lupa testing kembali

supaya dinamis dalam menentukan total supply, bisa menggunakan cara ini:
buat fungsi tokens yang punya parameter n diluar describe.
const { ethers } = require("hardhat");
const { expect } = require("chai");
const tokens = (n) => {
return ethers.utils.parseUnits(n.toString(), "ether")
}
describe("Token", () => {
let token
beforeEach(async() => {
// fetch token from blockchain
const Token = await ethers.getContractFactory("Token")
token = await Token.deploy()
})
it("has a name", async() => {
// check token name is correct
expect(await token.name()).to.equal("Dallan")
})
it("has correct symbol", async() => {
// check token symbol is correct
expect(await token.symbol()).to.equal("DLN")
})
it("has correct decimals", async() => {
// check token decimals is correct
expect(await token.decimals()).to.equal("18")
})
it("has correct total suply", async() => {
// check token total suply is correct
const value = tokens("1000000")
expect(await token.totalSuply()).to.equal(value)
})
})
Kode di atas ditulis dalam bahasa JavaScript dan menggunakan framework Mocha untuk menguji smart contract yang disebut "Token."
Baris pertama dan kedua mengimpor modul 'ethers' dan 'chai' yang akan digunakan untuk berinteraksi dengan smart contract dan melakukan asumsi, masing-masing.Fungsi 'tokens' mengambil sebuah angka sebagai input dan mengembalikan angka tersebut dalam wei, unit terkecil dari ether.Fungsi 'describe' dari Mocha yang digunakan untuk menjelaskan suite dari tesFungsi 'beforeEach' dari Mocha, yang akan dijalankan sebelum setiap tes 'it'Dalam fungsi 'beforeEach', sebuah instance baru dari smart contract di-deploy ke blockchain menggunakan modul 'ethers'.Fungsi 'it' adalah tes Mocha, setiap satu melakukan asumsi terhadap instance smart contract untuk memastikan properti-properti kontrak ditetapkan dengan benar.Dalam tes pertama, kode akan memeriksa apakah fungsi "name" dari kontrak mengembalikan "Dallan"Dalam tes kedua, kode akan memeriksa apakah fungsi "symbol" dari kontrak mengembalikan "DLN"Dalam tes ketiga, kode akan memeriksa apakah fungsi "decimals" dari kontrak mengembalikan "18"Dalam tes keempat, kode akan memeriksa apakah fungsi "totalSupply" dari kontrak mengembalikan jumlah ether yang benar dengan menggunakan fungsi 'tokens()' untuk mengonversi ether menjadi wei sebelum memeriksa nilai total supply Tolong diperhatikan bahwa kode ini menggunakan lingkungan hardhat, dan mungkin tidak berjalan di EVM lainnya.
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;
import "hardhat/console.sol";
contract Token {
// deklarasikan variabel
string public name;
string public symbol;
// decimals
uint256 public decimals = 18;
// total suply
uint256 public totalSupply;
constructor(string memory _name, string memory _symbol, uint256 _totalSupply) {
name = _name;
symbol = _symbol;
totalSupply = _totalSupply * (10 ** decimals);
}
}
Ini adalah kode Solidity yang menunjukkan implementasi dasar dari sebuah kontrak smart contract bernama "Token". Kontrak ini digunakan untuk menyimpan informasi tentang sebuah token, seperti nama, simbol, jumlah desimal, dan jumlah total yang beredar.
Kontrak ini mendeklarasikan beberapa variabel publik yaitu "name", "symbol", "decimals", dan "totalSupply" yang digunakan untuk menyimpan informasi tentang token tersebut. Variabel "name" dan "symbol" disimpan sebagai string, "decimals" sebagai uint256 (unsigned integer dengan ukuran 256 bit) dan "totalSupply" juga dalam uint256.
Kontrak ini juga memiliki sebuah constructor, yaitu sebuah fungsi yang dijalankan saat kontrak di-deploy ke blockchain. Constructor ini menerima tiga argumen: _name, _symbol, dan _totalSupply. Argumen ini digunakan untuk mengatur nilai variabel publik "name", "symbol", dan "totalSupply" saat kontrak di-deploy.
Kontrak juga menentukan jumlah total supply sesuai dengan jumlah desimal, totalSupply = _totalSupply * (10 ** decimals)
Kontrak ini tidak memiliki fungsi apapun selain constructor, sehingga tidak bisa digunakan untuk mengirim atau mentransfer token, atau mengubah informasi token setelah kontrak di-deploy.
const { ethers } = require("hardhat");
const { expect } = require("chai");
const tokens = (n) => {
return ethers.utils.parseUnits(n.toString(), "ether")
}
describe("Token", () => {
let token
beforeEach(async() => {
// fetch token from blockchain
const Token = await ethers.getContractFactory("Token")
token = await Token.deploy("Dallan", "DLN", "1000000")
})
describe("Deployment", () => {
const name = "Dallan"
const symbol = "DLN"
const decimals = "18"
const totalSupply = tokens("1000000")
it("has a name", async() => {
// check token name is correct
expect(await token.name()).to.equal(name)
})
it("has correct symbol", async() => {
// check token symbol is correct
expect(await token.symbol()).to.equal(symbol)
})
it("has correct decimals", async() => {
// check token decimals is correct
expect(await token.decimals()).to.equal(decimals)
})
it("has correct total supply", async() => {
// check token total suply is correct
expect(await token.totalSupply()).to.equal(totalSupply)
})
})
})
Di dalam blok kode yang diberi label "describe('Token')", di mana di dalamnya terdapat beberapa unit test yang diberi label "describe('Deployment')" . Diantaranya, unit test mengecek apakah nama kontrak sesuai dengan yang diharapkan, apakah simbol sesuai dengan yang diharapkan, apakah jumlah desimal sesuai dengan yang diharapkan dan apakah jumlah total sesuai dengan yang diharapkan.
Unit test ini akan dijalankan sebelum setiap unit test yang berada di dalam blok "describe('Deployment')" dijalankan , untuk mengambil kontrak dari blockchain dan menyimpan dalam variabel token. Kemudian, sebelum setiap unit test dijalankan, fungsi tersebut akan mengecek apakah properti kontrak sesuai dengan yang diharapkan dengan menggunakan perintah expect() dari Chai.
npx hardhat test
