Đoạn code bên dưới sẽ giúp Ethereum không bị trapped trong smart contract khi có người dùng vô tình gửi Ethereum vào.
//We don't let any trapped in this contract
function () public payable {
revert();
}
Từ Solidity 0.4.21
thì việc dùng constructor
sẽ thay thế cho việc sử dụng function có cùng tên với smart contract.
//Empty constructor
constructor () public {}
Cùng xét function sau:
//Creator able to cancel his own jobs
function cancel(uint256 jobId)
public onlyCreator(jobId) onlyAvailableJob(jobId) onlyValidId(jobId) returns(bool)
{
//Job will become unavailable due to end isn't equal to 0
jobData[jobId].end = block.timestamp;
//Smart contract have to return mortgage
jobData[jobId].creator.transfer(jobData[jobId].salary);
emit CancelCreatedJob(jobId, msg.sender);
return true;
}
Có những điểm đáng chú ý như sau:
returns(bool)
vàreturn true;
: Nhiều bạn sẽ tự hỏi đoạn này có cần thiết không, câu trả lời sẽ là có vì nếu smart contract của bạn được trigger từ bên ngoài. Khi người dùng muốn đảm bảo rằng lời gọi của họ đã được trigger thì cách an toàn nhất là sữ dụngrequire(PartTime.cancel(2));
. Nếu việc gọicancel()
là thất bại, thìrevert()
sẽ được gọi đảo ngược các thay đổi của bạn.- Mình đặt
jobData[jobId].end = block.timestamp;
ở đầu, điều này sẽ thay đổi trạng thái của blockchain, nhưng nếu transfer thất bạijobData[jobId].creator.transfer(jobData[jobId].salary);
thì toàn bộ changed sẽ được đảo ngược vìaddress.transfer(value)
tương đươngrequire(address.send(value));
.
Việc mình viết thế này sẽ an toàn hơn cách viết sau:
//Creator able to cancel his own jobs
function cancel(uint256 jobId)
public onlyCreator(jobId) onlyAvailableJob(jobId) onlyValidId(jobId)
{
emit CancelCreatedJob(jobId, msg.sender);
//Smart contract have to return mortgage
jobData[jobId].creator.transfer(jobData[jobId].salary);
//Job will become unavailable due to end isn't equal to 0
jobData[jobId].end = block.timestamp;
}
Vì vậy bạn nên cân nhắc là nên viết gì trước và nên viết gì sau, điều gì sẽ quan trọng nhất trong code của bạn(?).
Cùng xét function sau:
//Creator pay money
function pay(uint256 jobId)
public onlyValidId(jobId) onlyCreator(jobId) onlyNotCompleted(jobId) returns(bool) {
uint256 value;
//Fund = salary + mortgage
value = jobData[jobId].salary;
value = value + (value/10);
//Mark job as completed
jobData[jobId].completed = true;
//Transfer fund and mortgage to labor
jobData[jobId].labor.transfer(value);
emit Paid(jobData[jobId].creator, jobData[jobId].labor, value);
return true;
}
Trong đoạn này khi creator
trả lương cho labor
, mình cần đảm bảo là creator
trả đúng vì ngoài tiền công salary
còn một khoản thế chấp salary/10
mình dùng để đảm bảo anonymous
không spam bằng cách trigger take()
.