Trang chủ Blockchain Hợp Đồng Thông Minh (Smart Contract) Lập trình smart contract: Phần 5 — Viết test case cho smart contracts

Lập trình smart contract: Phần 5 — Viết test case cho smart contracts

Tiếp tục loạt bài thực tế phát triển dApp, giờ chúng ta sẽ nâng độ khó lên một chút xíu khi đi vào hoàn thiện nội dung của smart contracts và viết test case kiểm thử.

Smart contracts

Events

Các smart contracts được thực thi trong môi trường của EVM, hoàn toàn tách biệt với môi trường bên ngoài. Để có thể trigger một sự kiệu ra bên ngoài EVM ta gửi các events được định nghĩa trước:

//New job append
 event NewJob(
 uint256 indexed id,
 address creator,
 uint256 salary,
 uint256 timeOut);

//An woker start working
 event TakeJob(
 uint256 indexed id,
 address indexed labor);

Các event này có thể lắng nghe thông qua các filter cung cấp bởi web3js, việc này sẽ cung cấp thêm thông tin, trigger các hệ thống third party hoặc đơn giản là điều chỉnh lại front-end.

Modifier

Để smart contract của mình bảo mật hơn, mình thêm các modifier. Mục tiêu là kiểm tra arguments trước khi method được trigger (Ethereum là một hệ hoàn toàn thụ động, không có khả năng tự tính toán).

//Transaction must contant Ethereum
 modifier onlyHaveFund {
 require(msg.value > MINIUM_SALARY);
 _;
 }

Trên đây bạn có thể đọc thấy modifier rất rõ nghĩa, với modifier này mình check số Ethereum có trong transaction. Biến msg sẽ chứa vài thông tin hữu ích của transaction (eg. msg.sender: address của người gửi, msg.value: số ethereum tính bằng wei). Để biết rõ thêm global variable các bạn xem ở đây.

Smart contract

Mình viết lại smart contract, thêm hai function mới takeJob() và viewJob():

//Take job

function

takeJob (uint256 jobId)

public onlyValidMortgage(jobId) onlyValidId(jobId) onlyValidJob(jobId)

{

//Trigger event to log labor

TakeJob(jobId, msg.sender);



//Change working state

jobData[jobId].start = block.timestamp;

}



//Veiw job data

function

viewJob(uint256 jobId)

public onlyValidId(jobId) constant returns (

uint256 id,

address creator,

uint256 salary,

uint256 start,

uint256 end,

uint256 timeOut,

bytes title,

bytes description)

{

Job memory jobReader = jobData[jobId];

return (jobReader.id,

jobReader.creator,

jobReader.salary,

jobReader.start,

jobReader.end,

jobReader.timeOut,

jobReader.title,

jobReader.description);

}

Trong phần struct mình cũng update thêm các biến liên quan tới thời gian, và để tiện xử lý mình sẽ sữ dụng Unix timestamp (Solidity không có kiểu datime nên dùng Unix time là tiện nhất):

uint256 start;

uint256 end;

uint256 timeOut;

Chúng ta có toàn bộ mã nguồn như sau:

pragma solidity ^0.4.18;





contract PartTime {



//Job structure

struct Job {

uint256 id;

address creator;

uint256 salary;

uint256 start;

uint256 end;

uint256 timeOut;

bytes title;

bytes description;

}



//New job append

event NewJob(uint256 indexed id,

address creator,

uint256 salary,

uint256 timeOut);



//An woker start working

event TakeJob(

uint256 indexed id,

address indexed labor);



//Minium accept salary

uint256 constant public MINIUM_SALARY = 0.1 ether;



//The number of jobs

uint256 public totalJob;



//Mapped data

mapping (uint256 => Job) public jobData;



//Transaction must contant Ethereum

modifier onlyHaveFund {

require(msg.value > MINIUM_SALARY);

_;

}



//Valid timeOut should be greater than 3 days

modifier onlyValidTimeOut(uint256 timeOut) {

require(timeOut > 3 days);

_;

}



//Check valid job Id

modifier onlyValidId(uint256 jobId) {

require(jobId < totalJob);

_;

}



//Mortgage should be greater than 1/10

modifier onlyValidMortgage(uint256 jobId) {

require(msg.value > jobData[jobId].salary/10);

_;

}



//Check is it a taked job

modifier onlyValidJob(uint256 jobId) {

require(jobData[jobId].end == 0);

require(jobData[jobId].start == 0);

_;

}



//Append new job to mapping

function

createJob (uint256 timeOut, bytes title, bytes description)

public onlyHaveFund onlyValidTimeOut(timeOut) payable returns(uint256 jobId)

{

// Saving a little gas by create a temporary object

Job memory newJob;



// Assign jobId

jobId = totalJob;



newJob.id = jobId;

newJob.id = timeOut;

newJob.title = title;

newJob.description = description;

newJob.salary = msg.value;

newJob.creator = msg.sender;



//Trigger event

NewJob(jobId, msg.sender, msg.value, timeOut);



// Append newJob to jobData

jobData[totalJob++] = newJob;



return jobId;

}



//Take job

function

takeJob (uint256 jobId)

public onlyValidMortgage(jobId) onlyValidId(jobId) onlyValidJob(jobId)

{

//Trigger event to log labor

TakeJob(jobId, msg.sender);



//Change working state

jobData[jobId].start = block.timestamp;

}



//Veiw job data

function

viewJob(uint256 jobId)

public onlyValidId(jobId) constant returns (

uint256 id,

address creator,

uint256 salary,

uint256 start,

uint256 end,

uint256 timeOut,

bytes title,

bytes description)

{

Job memory jobReader = jobData[jobId];

return (jobReader.id,

jobReader.creator,

jobReader.salary,

jobReader.start,

jobReader.end,

jobReader.timeOut,

jobReader.title,

jobReader.description);

}



}

Và mình viết thêm test case bằng JavaScript:

var Partime = artifacts.require("./PartTime.sol");



function createTx(from, to, value = 0, gas = 1000000, gasPrice = 20000000) {

return {

from: from,

to: to,

gas: gas,

gasPrice: gasPrice,

value: value

};

}



contract('Partime', function (accounts) {



it('should have 0 total part time job', function () {

return Partime.deployed().then(function (instance) {

return instance.totalJob.call();

}).then(function (totalJob) {

assert.equal(totalJob.valueOf(), 0, 'Total job was not equal to 0');

});

});



it('should able to add new job', function () {

return Partime.deployed().then(function (instance) {

return instance.createJob(((new Date()).getTime() / 1000 + 432000),

"This is tittle",

"This is description",

createTx(accounts[0], instance.address, web3.toWei('1', 'ether')));

}).then(function (totalJob) {

assert.equal(typeof (totalJob.valueOf()), 'object', 'Transaction was not triggered success');

});

});



it('should have total part time job geater than 0', function () {

return Partime.deployed().then(function (instance) {

return instance.totalJob.call();

}).then(function (totalJob) {

assert.equal(totalJob.valueOf() > 0, true, 'Total job was equal to 0' );

});

});



});

Bạn chú ý thấy mình đang thêm 1 job mới:

return instance.createJob(((new Date()).getTime() / 1000 + 432000),

"This is tittle",

"This is description",

createTx(accounts[0], instance.address, web3.toWei('1', 'ether')));

Đoạn code này có nghĩa là mình tạo ra 1 job có

  • Timeout: 5 ngày
  • Title: This is tittle
  • Description: This is description
  • Value: 1 Ethereum

Thực thi kiểm thử:

Smart contracts

Mình đã update source code tại https://github.com/chiro-hiro/part-time-dapp. Các bạn có thể clone về hoặc fork về viết cùng mình cho vui.

Dislaimer: Đây là thông tin cung cấp dưới dạng blog cá nhân, không phải thông tin tổng hợp hay lời khuyên đầu tư. Chúng tôi không chịu trách nhiệm về các quyết định đầu tư của bạn.

MỚI CẬP NHẬT

Xu hướng săn presale của Slothana trên Twitter

Xu hướng săn presale của Slothana trên Twitter, meme coin mới trên Solana sẽ...

 Đợt presale của Slothana (SLOTH) đang là xu hướng trên Twitter do có nhiều người nghĩ nó sẽ trở thành đồng meme coin tiếp...

Tin vắn Crypto 28/03: Bitcoin vẫn có khả năng thiết lập ATH mới trước...

Từ nhận định Bitcoin có thể chứng kiến một đợt tăng giá lớn trước halving đến cá voi ẩn danh di chuyển lượng lớn...
Ethereum

13.900 node của Ethereum đang chạy 1 triệu trình xác thực, với 26% nguồn...

Theo thống kê, 13.900 node hỗ trợ mạng Ethereum hiện đang chạy hơn 1 triệu trình xác thực. Việc tăng số lượng trình xác thực...

Giá Qredo (QRDO) có thể tăng gần 300% trong thời gian tới

Giá Qredo (QRDO) đã bứt phá lên trên một đường kháng cự dài hạn và cho thấy các tín hiệu tăng giá quyết định....

VP Messari: Memecoin sẽ là “con ngựa thành Troia” tiếp theo của không gian...

Memecoin đang ngày càng thể hiện tầm quan trọng trong bối cảnh tiền điện tử và từ đầu năm đến nay, các token mang...
altcoin

Nhà phân tích nổi tiếng tiết lộ mùa altcoin sẽ bắt đầu sau 45...

Khi đường chân trời bừng sáng với những dự đoán về mùa altcoin khác, các nhà đầu tư đang tìm kiếm loại tiền điện...
he-lo-ly-do-nha-dau-tu-solana-va-cardano-xon-xao-ve-dot-ban-truoc-cua-algotech

Hé lộ lý do nhà đầu tư Solana và Cardano quan tâm đến đợt...

Trong bối cảnh thị trường tăng trưởng mạnh mẽ, Solana và Cardano, cùng với nhiều cryptocurrency khác, cũng đã gia tăng đáng kể trong...

Giá PEPE đang chuẩn bị cho một bước nhảy vọt khác, đây là lý...

Nguồn cung PEPE trên các sàn giao dịch tập trung (CEX) đã giảm đáng kể chỉ trong một ngày, báo hiệu rằng các holder...

TVL SUI đạt mức cao nhất mọi thời đại trên 724 triệu đô la...

Quan sát các token được xây dựng bằng ngôn ngữ lập trình Move, Sui (SUI) là một ngoại lệ, vượt trội so với Aptos...

Giá và TVL của Pendle đều đạt đỉnh mới khi trader đổ xô vào...

Trong bối cảnh các trader đổ xô đặt cược vào lợi suất của các token khác nhau và suy đoán về xu hướng point...

Ethereum blob đang được sử dụng để tạo ra chữ khắc với tốc độ...

Sau khi bản nâng cấp Dencun của Ethereum đi vào hoạt động trên mainnet giúp phí gas của các layer 2 giảm 10 lần,...

KuCoin công bố airdrop 10 triệu đô la BTC và KCS sau rắc rối...

Nhằm nâng cao lợi ích cho nhóm khách hàng trung thành trong bối cảnh phải đối mặt với những rắc rối pháp lý mới,...
xrp-giam

Triển vọng giá XRP: Dấu hiệu áp lực bán cho thấy xu hướng giảm...

Giá Ripple (XRP) đã có xu hướng giảm trong nửa tháng qua và những tín hiệu giảm giá này ngày càng mạnh hơn. Liệu altcoin...
bitcoin etf

Hashdex ra mắt Bitcoin ETF giao ngay “DEFI” tại Hoa Kỳ với hoạt động...

Quỹ Bitcoin ETF giao ngay của công ty quản lý tài sản Hashdex bắt đầu giao dịch vào hôm qua trên thị trường Hoa...

Lý do token MNT của Mantle đạt ATH mới

Token gốc MNT của Mantle, giải pháp khả năng mở rộng layer 2 được xây dựng trên Ethereum, đã tăng 55% lên mức cao...

ETHFI của Ether.fi tăng 60% lên đỉnh mới

ETHFI, token quản trị của giao thức restaking thanh khoản Ether.fi đã tăng lên mức cao kỷ lục vào thứ Tư khi sự cường...