通过前述5篇博文的分析,分别介绍了以太猫的基础数据,权限控制,生产,拍卖,交易等相关合约代码分析,今天将介绍一下,以太猫游戏开始,宣传猫和一代猫的生成过程以及该休息的主合约。
宣传猫&一代猫
// 游戏刚开始时,有宣传猫和初代猫两种,宣传猫直接给账号,初代猫放大市场拍卖
contract KittyMinting is KittyAuction {
uint256 public constant PROMO_CREATION_LIMIT = 5000; // 宣传猫5000只,可以直接发给自己的朋友
uint256 public constant GEN0_CREATION_LIMIT = 45000; // 初代猫45000只
// 初代猫 最初的价格 和 存续期,相当于一个最低价
uint256 public constant GEN0_STARTING_PRICE = 10 finney;
uint256 public constant GEN0_AUCTION_DURATION = 1 days;
// 宣传猫和初代猫的数量
uint256 public promoCreatedCount;
uint256 public gen0CreatedCount;
//产生宣传猫,只有COO才能调用,可以直接指定基因和拥有者
function createPromoKitty(uint256 _genes, address _owner) external onlyCOO {
address kittyOwner = _owner;
if (kittyOwner == address(0)) {
kittyOwner = cooAddress;
}
require(promoCreatedCount < PROMO_CREATION_LIMIT);
promoCreatedCount++;
_createKitty(0, 0, 0, _genes, kittyOwner);
}
// 创建初代猫,直接的放入拍卖所
function createGen0Auction(uint256 _genes) external onlyCOO {
require(gen0CreatedCount < GEN0_CREATION_LIMIT);
uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this));
_approve(kittyId, saleAuction);
saleAuction.createAuction(
kittyId,
_computeNextGen0Price(),
0,
GEN0_AUCTION_DURATION,
address(this)
);
gen0CreatedCount++;
}
// 计算拍卖的初始价格
function _computeNextGen0Price() internal view returns (uint256) {
uint256 avePrice = saleAuction.averageGen0SalePrice(); // 计算最近五次拍卖的平均价格
require(avePrice == uint256(uint128(avePrice))); // 验证价格是否合法
uint256 nextPrice = avePrice + (avePrice / 2); // 价格上涨了50%
if (nextPrice < GEN0_STARTING_PRICE) { // 价格不能低于 初始价格
nextPrice = GEN0_STARTING_PRICE;
}
return nextPrice; // 返回最新的价格
}
}
游戏主合约
contract KittyCore is KittyMinting {
address public newContractAddress; // 设置新的合约地址,这是在游戏项目出现巨大的问题时,我们可以设置新的合约来升级
// 构造函数
function KittyCore() public {
paused = true; // 暂停
ceoAddress = msg.sender; // 合约的部署地址就是CEO
cooAddress = msg.sender; // 合约的部署地址也是COO
_createKitty(0, 0, 0, uint256(-1), address(0)); // 创建了一只猫
}
// 设置新的合约地址
function setNewAddress(address _v2Address) external onlyCEO whenPaused {
newContractAddress = _v2Address;
ContractUpgrade(_v2Address); // 触发合约变更事件
}
// 转账,必须是拍卖所的合约
// 匿名函数,用户直接给合约地址转账时,报错,这是为了防止误操作,只有交易所才能给合约转账
function() external payable {
require(
msg.sender == address(saleAuction) ||
msg.sender == address(siringAuction)
);
}
// 获取代币(猫)的信息
function getKitty(uint256 _id)
external
view
returns (
bool isGestating, // 是否正在怀孕
bool isReady, // 是否可以准备怀孕(从冷却时间/区块产生速度 预测下次可怀孕的区块数)
uint256 cooldownIndex, // 猫冷却的时间
uint256 nextActionAt, // 猫下次生育的最小区块号
uint256 siringWithId, // 猫当前是否怀孕
uint256 birthTime, // 猫出现的时间
uint256 matronId, // 猫母亲的ID
uint256 sireId, // 猫父亲的ID
uint256 generation, // 猫的代数
uint256 genes // 猫的基因
) {
Kitty storage kit = kitties[_id]; // 通过 _id 获取猫的数据
isGestating = (kit.siringWithId != 0);
isReady = (kit.cooldownEndBlock <= block.number);
cooldownIndex = uint256(kit.cooldownIndex);
nextActionAt = uint256(kit.cooldownEndBlock);
siringWithId = uint256(kit.siringWithId);
birthTime = uint256(kit.birthTime);
matronId = uint256(kit.matronId);
sireId = uint256(kit.sireId);
generation = uint256(kit.generation);
genes = kit.genes;
}
// 解锁暂停,只有ceo才能调用
function unpause() public onlyCEO whenPaused {
require(saleAuction != address(0));
require(siringAuction != address(0));
require(geneScience != address(0));
require(newContractAddress == address(0));
super.unpause();
}
// 转账到CFO address
function withdrawBalance() external onlyCFO {
uint256 balance = this.balance; // 本合约地址的金额
uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; // 计算怀孕猫的总的保证金
if (balance > subtractFees) {
cfoAddress.send(balance - subtractFees); // 总的金额减去 怀孕猫的保证金,这个是要返还的
}
}
}
KittyCore 合约是整个以太猫游戏的主合约,该合约通过继承的方式,通过继承其他合约来实现相关的功能。在下篇文章中我将介绍以太猫游戏各个合约间的关联,用图表的方式给大家呈现。