首页 > 矿场 > 【学习专栏】如何在以太坊上编写自己的CryptoKitties风格游戏
路安  

【学习专栏】如何在以太坊上编写自己的CryptoKitties风格游戏

摘要:CryptoKitties在展示区块链不仅可以用于简单的金融交易方面做得很好。 我希望将来我们会开始看到区块链在此类游戏中的更多创新用途,因此我想快速浏览一下 CryptoKitties 背后的代码,以展示它是如何在表面下实现的。 本文是为开发人员编写的,虽然它不是对 Solidity 的绝对初学者

CryptoKitties在展示区块链不仅可以用于简单的金融交易方面做得很好。

我希望将来我们会开始看到区块链在此类游戏中的更多创新用途,因此我想快速浏览一下 CryptoKitties 背后的代码,以展示它是如何在表面下实现的。

本文是为开发人员编写的,虽然它不是对 Solidity 的绝对初学者介绍,但我尝试包含指向文档的链接,以使所有级别的开发人员都可以访问它。

让我们开始……

加密猫源代码

几乎所有 CryptoKitties 代码都是开源的,因此了解其工作原理的最佳方法是通读源代码。

总共大约 2,000 行,所以在本文中,只介绍最重要的部分。

高级概述

如果你不熟悉 CryptoKitties 是什么,它基本上是一个购买、销售和繁殖数字猫的游戏。每只猫都有基因定义的独特外观,当 2 只猫一起繁殖时,它们的基因以独特的方式结合产生后代,然后您可以繁殖或出售后代。

CryptoKitties 的代码被拆分为多个较小的合约 ,以便将相关代码捆绑在一起,而不需要一个包含所有内容的巨型文件。

主 kitty 合约的分包继承如下所示:

合约KittyAccessControl

合约KittyBase是 KittyAccessControl

合约KittyOwnership是 KittyBase,ERC721

合约KittyBreeding是 KittyOwnership

合约KittyAuction是 KittyBreeding

合约KittyMinting是 KittyAuction

合约KittyCore是 KittyMinting

KittyCore应用程序最终指向的合约地址也是如此,它继承了之前合约的所有数据和方法。

让我们一一浏览这些合同。

1. KittyAccessControl: 谁控制合同?

该合约只能由特定角色执行操作的各种地址和约束来管理。即首席执行官、首席财务官和首席运营官。

这份合约是用来管理合约的,与游戏机制完全无关。它基本上具有“CEO”、“COO”和“CFO”的“setter”方法,它们是对合约的特定功能具有特殊所有权和控制权的以太坊地址。

KittyAccessControl 定义了一些函数修饰符,例如onlyCEO(它限制一个函数,以便只有 CEO 可以执行它),并添加方法来执行诸如暂停/取消暂停合约或提取资金之类的操作:

该pause()功能可能已添加,以便开发人员可以使用更新的版本对其进行更新,以防出现任何不可预见的错误……这实际上可以让开发人员完全冻结合约,使合约无人能转让、出售或繁殖他们的小猫!有趣的是,大多数人认为 DApp 完全去中心化只是因为它位于以太坊上。并不是。

继续…

2. KittyBase:能说清楚到底什么是小猫吗?

这是我们定义整个核心功能中最基本的共享代码的地方。这包括我们的主要数据存储、常量和数据类型,以及管理这些项目的内部函数。

KittyBase定义了很多应用的核心数据。首先,它将 Kitty 定义为struct:

struct Kitty {

uint256 基因;

uint64 出生时间;

uint64 冷却结束块;

uint32 matronId;

uint32 父亲身份;

uint32 siringWithId;

uint16 冷却指数;

uint16代;

}

所以一只小猫实际上只是一堆无符号整数......大概是这样。

分解每个部分:

genes— 一个 256 位整数,代表猫的遗传密码,决定猫长什么样的核心数据

birthTime— 猫出生时区块的时间戳

cooldownEndBlock— 这只猫可以再次进行繁殖的最小时间戳

matronId sireId——分别是猫的妈妈和爸爸的ID

siringWithId- 如果猫当前怀孕,则设置为父亲的 ID,否则设置为零

cooldownIndex- 这只猫的当前冷却时间(猫在繁殖后必须等待多长时间才能再次繁殖)

generation——这只猫的“世代号”。合约铸造的第一批猫有第 0 代;新猫的世代是它们父母世代中较大的一代,加1。

请注意,在 CryptoKitties 中,猫是无性的,任何 2 只猫都可以繁殖——因此猫没有性别。

然后KittyBaseKitty合约继续声明这些结构的数组:

这个数组保存了所有存在的 Kitties 的数据,所以它有点像一个 Master Kitty DB。每当创建一只新猫时,它就会被添加到这个数组中,它在数组中的索引成为猫的 ID,就像这里的Genesis的 ID 为“1”:

数组索引是“1”!

该合约还包含从猫的 ID 到其所有者地址的映射,以跟踪小猫的所有者:

映射(uint256 = 地址)公共kittyIndexToOwner;

还定义了一些其他映射,但为了使本文保持合理的长度,我不会详细介绍每个细节。

每当一只小猫从一个人转移到另一个人时,这个kittyIndexToOwner映射就会更新以反映新主人:

转移所有权会将 Kitty 的 ID 的 `kittyIndexToOwner` 设置为接收者的 `_to` 地址。

现在让我们看看创建新的小猫时会发生什么:

所以这个函数传递了父母的ID 、猫咪的代号、 256位的遗传密码和主人的地址。然后它创建小猫,将其推送到主Kitty阵列,然后调用_transfer()以将其分配给它的新所有者。

真的超酷的有没有——所以现在我们可以看到 CryptoKitties 如何将小猫定义为一种数据类型,它如何将所有小猫存储在区块链上,以及它如何跟踪谁拥有哪些小猫。

3. KittyOwnership:Kitties 作为代币

这部分内容提供了遵循 ERC721 规范草案的代币交易所需的基本方法。

CryptoKitties 符合ERC721 代币规范,这是一种不可替代的代币类型,非常适合跟踪数字收藏品的所有权,例如数字扑克牌或 MMORPG 中的稀有物品。

关于可替代性的注意事项:以太是可替代的,因为任何 5 ETH 都与任何其他 5 ETH 一样好。但是对于像 CryptoKitties 这样的不可替代代币,并非每只猫都是平等的,因此它们不能相互互换。

从它的合约定义可以看出,KittyOwnership 继承自 ERC721 合约:

合约 KittyOwnership 是 KittyBase,ERC721 {

并且所有 ERC721 代币都遵循相同的标准,因此KittyOwnership合约填写了以下功能的实现:

由于这些方法是公开的,这为用户与 CryptoKitties 代币进行交互提供了一种标准方式,就像他们与任何其他 ERC721 代币进行交互一样。您可以直接通过与以太坊区块链上的 CryptoKitties 合约进行交互来将您的代币转移给其他人,而无需通过他们的 Web 界面,因此从这个意义上说,您真正拥有您的小猫。(除非 CEO 暂停合同)。

4. KittyBreeding:猫开始混血

该文件包含将猫一起繁殖所需的方法,包括跟踪父亲的报价,并依赖于外部基因组合合同。

“外部基因组合合约”(geneScience)存储在单独的合约中,不是开源的。

KittyBreeding合约包含一个让 CEO 设置此外部合约地址的方法:

他们这样做是为了增加游戏难度——如果你能读懂一只小猫的 DNA 是如何确定的,就更容易知道要繁殖哪些猫才能得到一只“花哨的猫”。

这个外部geneScience合约稍后在giveBirth()函数中使用(我们稍后会看到)来确定新猫的 DNA。

现在让我们看看当两只猫一起繁殖时会发生什么:

所以这个函数获取母亲和父亲kitties的 ID,在主数组中查找它们,并将siringWithId母亲的 ID 设置为父亲的 ID。(当siringWithId非零时,表示母亲怀孕)。

它还让triggerCooldown对父母双方都执行,这使得他们在一定时间内无法再次繁殖。

接下来,我们有一个giveBirth()创建新猫的公共函数:

对代码的内嵌注释是不言自明的。基本上,代码首先执行一些检查以查看母亲是否准备好分娩。然后它使用 确定孩子的基因geneScience.mixGenes(),将新小猫的所有权分配给母亲的主人,然后调用_createKitty()我们在KittyBase中查看的函数。

请注意,该geneScience.mixGenes()函数是一个黑匣子,因为该合约是闭源的。所以我们实际上并不知道孩子的基因是如何决定的,但我们知道这是母亲基因、父亲基因和母亲基因的某种功能cooldownEndBlock。

5. KittyAuctions:猫的买卖和“配种”

在这里,我们有拍卖或竞标猫或“种公”父亲服务的方法。实际的拍卖功能在两个同级合同中处理(一个用于销售,一个用于分配),而拍卖创建和竞标主要通过核心合同的这一方面进行调解。

根据开发人员的说法,他们将此拍卖功能拆分为“兄弟”合约,因为“它们的逻辑有些复杂,并且总是存在细微错误的风险。通过将它们保留在自己的合同中,我们可以在不破坏跟踪小猫所有权的主合同的情况下对其进行升级。”

所以这个KittyAuctions合约包含了函数setSaleAuctionAddress()和setSiringAuctionAddress(),这些函数setGeneScienceAddress()只能由 CEO 调用,并设置了处理这些函数的外部合约的地址。

注意: “Siring”是指给你的猫“配种繁育”——把它拍卖,另一个用户可以用以太币支付给你,让你的猫和他们的猫一起繁殖。LOL。

这意味着即使 CryptoKitties 合约本身是不可变的,CEO 也可以灵活地更改这些拍卖合约的地址,这将改变拍卖规则。同样,这不一定是坏事,因为有时开发人员需要修复错误,但需要注意一些事情。

6. KittyMinting:Gen0 猫工厂

最后一个方面包含我们用于创建新的 gen0 猫的功能。我们最多可以制作 5000 只可以赠送的“促销”猫(当社区是新社区时尤其重要),而所有其他猫只能通过算法确定的起始价格创建并立即进行拍卖。无论它们是如何创建的,都有 50k gen0 猫的硬性限制。在那之后,一切都取决于社区来繁殖、繁殖、繁殖!

合约能够创建的促销猫和 gen0 猫的数量在这里是硬编码的:

uint256 公共常量 PROMO_CREATION_LIMIT = 5000;

uint256 公共常数 GEN0_CREATION_LIMIT = 45000;

下面是“COO”可以创建促销小猫和 gen0 小猫的代码:

因此createPromoKitty(),看起来首席运营官可以用他想要的任何基因创造一只新的小猫,并将它发送给他想要的任何人(最多 5000 只小猫)。我猜他们会将此用于早期的 beta 测试人员、朋友和家人,以免费赠送小猫进行促销等。

但这也意味着您的猫可能并不像您想象的那么独特,因为他可能会打印 5000 个相同的副本!

因为createGen0Auction(),首席运营官还提供了新小猫的遗传密码。但它并没有将其分配给特定人的地址,而是创建了一个拍卖,用户将竞标以太币购买这只小猫。

7. KittyCore:主合同

这是主要的 CryptoKitties 合约,它是在以太坊区块链上编译和运行的。这份合同将一切联系在一起。

由于继承结构,它继承了我们之前看到的所有合约,并添加了更多的 final 方法,例如使用它的 ID 获取所有 Kitty 数据的函数:

这个方法是公开的,它将从区块链返回特定小猫的所有数据。我想这是他们的网络服务器查询的内容,用于在网站上显示猫。

等等……我没有看到任何图像数据。是什么决定了小猫的长相?

正如我们从上面的代码中看到的那样,“小猫”基本上可以归结为一个 256 位的无符号整数,代表它的遗传密码。

Solidity 合约代码中没有任何内容可以存储猫的图像或其描述,或者确定 256 位整数的实际含义。该遗传密码的解释发生在 CryptoKitty 的网络服务器上。

因此,虽然这是一个非常聪明的区块链游戏演示,但它实际上并不是 100% 基于区块链的。如果将来他们的网站下线,除非有人备份了所有图像,否则您将只拥有一个毫无意义的 256 位整数。

在合约代码中,我确实找到了一个名为 的合约ERC721Metadata,但它永远不会被用于任何事情。所以我的猜测是他们最初计划将所有内容存储在区块链中,但后来决定反对它(在以太坊中存储大量数据成本太高?)因此他们最终需要将其存储在他们的网络服务器上。

综上所述

好的……总而言之,目前我们搞明白了:

小猫如何表示为数据

现有的所有小猫如何存储在一个智能合约中,以及它如何跟踪谁拥有什么

gen0 小猫是如何产生的

小猫如何繁殖形成新的小猫

这只是一个顶级概述。开始构建您自己的游戏吧,毫无疑问这是一个愉快的过程。

免责声明
世链财经作为开放的信息发布平台,所有资讯仅代表作者个人观点,与世链财经无关。如文章、图片、音频或视频出现侵权、违规及其他不当言论,请提供相关材料,发送到:2785592653@qq.com。
风险提示:本站所提供的资讯不代表任何投资暗示。投资有风险,入市须谨慎。
世链粉丝群:提供最新热点新闻,空投糖果、红包等福利,微信:juu3644。