Xét đoạn code sau:
contract MyContract {
INumberInterface numberContract;
function setNumberContractAddress(address _address) external {
numberContract = INumberInterface(_address);
}
function someFunction() public {
uint num = numberContract.getNum(msg.sender);
}
}
Có thể thấy, hàm setNumberContractAddress
có visibility là external
. Dẫn đến, bất kỳ ai cũng có thể thay đổi địa chỉ của smart contract.
Để giải quyết vấn đề này, ta có thể sử dụng một contract có tên là Ownable
thuộc thư viện OpenZepplin1.
Contract Ownable
về cơ bản sẽ thực hiện hoặc hỗ trợ những tác vụ sau:
- Khi contract được tạo ra, constructor của nó sẽ gán giá trị của state variable
_owner
làmsg.sender
. Nói cách khác, địa chỉ của chủ sở hữu của contract chính là địa chỉ được dùng để tạo ra contract. - Nó tạo ra function modifier
onlyOwner
để giới hạn quyền truy cập đến hàm. Cụ thể, nó ngăn không cho các địa chỉ không phải là chủ sở hữu contract thực thi hàm. - Cho phép chủ sở hữu chuyển giao quyền sở hữu thông qua hàm
transferOwnership
.
Để giới hạn lại quyền truy cập của phương thức sao cho chỉ có chủ sở hữu mới được gọi thực thi, ta kế thừa contract Ownable
và sử dụng vào function modifier onlyOwner
như sau:
import "./Ownable.sol"
contract MyContract is Ownable {
INumberInterface numberContract;
function setNumberContractAddress(address _address) external onlyOwner {
numberContract = INumberInterface(_address);
}
function someFunction() public {
uint num = numberContract.getNum(msg.sender);
}
}
Khi gọi thực thi hàm setNumberContractAddress
, function modifier onlyOwner
sẽ được thực thi trước. Sau khi onlyOwner
được thực thi xong và đến dòng _;
, các câu lệnh bên trong hàm setNumberContractAddress
mới được thực thi.
Footnotes
-
Tham khảo Access Control - OpenZeppelin Docs. ↩