Update 2022 Feb: Kể từ solidity 0.5.0 trở đi nếu không khai báo là
storage
sẽ bị compile lỗi, nên level này coi như không còn hiệu lực, và đã được Ethernaut bỏ đi.
17. Locked
Nhiệm vụ: unlock contract
pragma solidity ^0.4.23;
// A Locked Name Registrar
contract Locked {
bool public unlocked = false; // registrar locked, no name updates
struct NameRecord { // map hashes to addresses
bytes32 name; //
address mappedAddress;
}
mapping(address => NameRecord) public registeredNameRecord; // records who registered names
mapping(bytes32 => address) public resolve; // resolves hashes to addresses
function register(bytes32 _name, address _mappedAddress) public {
// set up the new NameRecord
NameRecord newRecord;
newRecord.name = _name;
newRecord.mappedAddress = _mappedAddress;
resolve[_name] = _mappedAddress;
registeredNameRecord[msg.sender] = newRecord;
require(unlocked); // only allow registrations if contract is unlocked
}
}
Phân tích
Trong hàm register
có một lỗi cơ bản, đó chính là không có keyword memory
trước biến newRecord
, do đó biến newRecord
sẽ chính là biến trong storage
của contract.
Hay nói cách khác, newRecord
đang trỏ đến slot của unlocked
. Một chỉ dẫn rất rõ ràng phải không ?
Bạn có thể đọc thêm về storage trong smart contract tại bài viết này của mình.
Solution
Ta chỉ cần chạy hàm register
, vì kiểu của _name
là bytes32, nên ta sẽ chạy với tham số là _name=0x0000000000000000000000000000000000000000000000000000000000000001
để khi convert sang bool sẽ là true
, phần _mappedAddress
thì để địa chỉ bất kì là được
Trên chrome console, kiểm tra lại xem đã được unlock chưa
> await contract.unlocked()
true
Submit && all done!
Bình luận
Hãy luôn nhớ tới keyword memory
khi khai báo một struct mới trong hàm.
Bên cạnh đó, việc nắm chắc storage là điều tối cần thiết cho bất cứ ai muốn làm việc với smart contract nói chung và solidity nói riêng.
Enjoy coding!