通过https://etherscan.io/查看部署在以太坊主链上的ERC721合约,排在第一位是代币名为CryptoKitties (CK)的合约,其合约地址为:0x06012c8cf97bead5deae237070f9587f8e7a266d。经查询它就是大名鼎鼎的以太猫游戏的合约地址,接下来我们就来撸撸以太猫的源码。
接下里先来介绍一些以太猫基础部分的合约代码,主要包含权限控制合约代码,ERC721规范合约,基因接口合约。
权限控制合约
contract Ownable {
address public owner;
function Ownable() {
owner = msg.sender; //构造函数,owner 赋值为部署合约的账户地址
}
modifier onlyOwner() {
require(msg.sender == owner); //函数修改器,只有满足 msg.sender == owner 条件才会执行后续I的代码
_;
}
function transferOwnership(address newOwner) onlyOwner {
if (newOwner != address(0)) { //更改 owner 地址
owner = newOwner;
}
}
}
contract KittyAccessControl {
// CEO:
1.管理合约地址,包含转让交易拍卖合约、交配交易拍卖合约、基因合成外部合约、升级主合约
2.角色管理,可替换 CEO,CFO,COO地址
3.平台管理,平台的开启与关闭
// COO:
1.生成任意指定基因的营销猫
2.生成任意指定基本的Gen0猫
3.设置猫繁殖的最小花费
// CFO:
提取主合约的手续费
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 {
paused = false;
}
}
contract KittyAccessControl {
// CEO:
1.管理合约地址,包含转让交易拍卖合约、交配交易拍卖合约、基因合成外部合约、升级主合约
2.角色管理,可替换 CEO,CFO,COO地址
3.平台管理,平台的开启与关闭
// COO:
1.生成任意指定基因的宣传猫
2.生成任意指定基本的Gen0猫
3.设置猫繁殖的最小花费
// CFO:
提取主合约的手续费
address public ceoAddress;
address public cfoAddress;
address public cooAddress;
// 平台的开关控制
bool public paused = false; //false为开,ture为关
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 {
paused = false;
}
}
ERC721标准接口合约
contract ERC721 {
//获取发行猫的总量
function totalSupply() public view returns (uint256 total);
//获取 _owner 地址拥有的以太猫数量
function balanceOf(address _owner) public view returns (uint256 balance);
//查询 _tokenId 的以太猫的拥有者
function ownerOf(uint256 _tokenId) external view returns (address owner);
//合约调用者授权 _to 地址处理 _tokenId 以太猫的权限
function approve(address _to, uint256 _tokenId) external;
//合约调用者将 _tokenId 以太猫 转让给 _to
function transfer(address _to, uint256 _tokenId) external;
//将 _from 地址的 _tokenId 以太猫转让给 _to
function transferFrom(address _from, address _to, uint256 _tokenId) external;
//事件
event Transfer(address from, address to, uint256 tokenId);
event Approval(address owner, address approved, uint256 tokenId);
// 查询是否支持某个接口(ERC-165)
function supportsInterface(bytes4 _interfaceID) external view returns (bool);
}
基因接口合约
contract GeneScienceInterface {
// 是否为基因合成合约
function isGeneScience() public pure returns (bool);
// 传入父基因和母基因,返回下一代的基因
function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public returns (uint256);
}
该合约代码并未开源,以太猫交配的基因生成规则并不清楚,仅提供合约调用的接口