In this article, we'll be checking out CryptoKitties' smart contract called "KittyCore", which everyone can view on EtherScan. Specifically, we'll be looking into the contract, "KittyAccessControl", and its role in the entire CryptoKitties code base.
自己紹介
こんにちは、サム (@sbenemerito) です。奥多摩の留学生です。日本語とブロクチェーン技術を勉強しています。2018年10月に日本にフィリピンから来ました。
CryptoKittiesとは
CryptoKittiesもポケモンのように、架空のキャラクターを集められます。CryptoKittiesでは、キャラクターはデジタル資産です。この資産は「ERC-721」を使って作ります。そして、売買することができます。
オフィシャルサイト
https://www.cryptokitties.co/
KittyAccessControlとは
KittyAccessControl is a smart contract within the CryptoKitties' KittyCore smart contract. This smart contract manages access restrictions through modifiers, and utility functions. Here, there are 4 levels of users: CEO, CFO, COO, and the normal user.
ContractUpgrade and variable definition
contract KittyAccessControl {
event ContractUpgrade(address newContract);
address public ceoAddress;
address public cfoAddress;
address public cooAddress;
bool public paused = false;
...
}
In this part, an event ContractUpgrade is being defined which will be emitted when a contract is upgraded. Then, we define address typed variables called: ceoAddress (stores the CEO's address), cfoAddress (stores the CFO's address), and cooAddress(stores the COO's address). Finally, we have a bool typed variable called paused which pauses all transactions if True (for emergency purposes, ie. bugs are found).
C-Level Access Modifiers
contract KittyAccessControl {
...
modifier onlyCEO() {
require(msg.sender == ceoAddress);
_;
}
modifier onlyCFO() {
require(msg.sender == cfoAddress);
_;
}
modifier onlyCOO() {
require(msg.sender == cooAddress);
_;
}
modifier onlyCLevel() {
require(
msg.sender == cooAddress ||
msg.sender == ceoAddress ||
msg.sender == cfoAddress
);
_;
}
...
}
There are operations in the KittyCore code where only the CEO, CFO, COO, or any of the three, are able to perform. With these modifiers, we are able to check if the current msg.sender is one of them, or the person in the specific position.
C-Level Access Setters
contract KittyAccessControl {
...
function setCEO(address _newCEO) external onlyCEO {
require(_newCEO != address(0));
ceoAddress = _newCEO;
}
function setCFO(address _newCFO) external onlyCEO {
require(_newCFO != address(0));
cfoAddress = _newCFO;
}
function setCOO(address _newCOO) external onlyCEO {
require(_newCOO != address(0));
cooAddress = _newCOO;
}
...
}
These functions are used to changed the person who holds the position CEO, CFO, or COO. Only the CEO is able to perform these functions.
Pause modifiers and toggles
contract KittyAccessControl {
...
modifier whenNotPaused() {
require(!paused);
_;
}
modifier whenPaused {
require(paused);
_;
}
function pause() external onlyCLevel whenNotPaused {
paused = true;
}
function unpause() public onlyCEO whenPaused {
// can't unpause if contract was upgraded
paused = false;
}
}
For emergency purposes, the developers added a bool type variable called pause. This variable, when set to true, stops all transactions in the platform. Transaction functions will be using the whenNotPaused() modifier.
C-Level users will be able to to pause transactions by using the pause() function. On the other hand, only the CEO can unpause transactions or use the unpause() function.
コード
contract KittyAccessControl {
event ContractUpgrade(address newContract);
address public ceoAddress;
address public cfoAddress;
address public cooAddress;
bool public paused = false;
modifier onlyCEO() {
require(msg.sender == ceoAddress);
_;
}
modifier onlyCFO() {
require(msg.sender == cfoAddress);
_;
}
modifier onlyCOO() {
require(msg.sender == cooAddress);
_;
}
modifier onlyCLevel() {
require(
msg.sender == cooAddress ||
msg.sender == ceoAddress ||
msg.sender == cfoAddress
);
_;
}
function setCEO(address _newCEO) external onlyCEO {
require(_newCEO != address(0));
ceoAddress = _newCEO;
}
function setCFO(address _newCFO) external onlyCEO {
require(_newCFO != address(0));
cfoAddress = _newCFO;
}
function setCOO(address _newCOO) external onlyCEO {
require(_newCOO != address(0));
cooAddress = _newCOO;
}
modifier whenNotPaused() {
require(!paused);
_;
}
modifier whenPaused {
require(paused);
_;
}
function pause() external onlyCLevel whenNotPaused {
paused = true;
}
function unpause() public onlyCEO whenPaused {
// can't unpause if contract was upgraded
paused = false;
}
}
結論
KittyAccessControl is a vital part in CryptoKitties' core smart contract. Without it, critical functions or actions in the platform may be performed by anyone.
EtherScanでこのコードを見ることもできます。
I hope you learned a lot from this article. You may even be able to apply the concepts you learned here, especially restricting who are able to access certain functions, to your own smart contracts! That is all :)