玩区块链游戏谜恋猫 CryptoKitties, 学习区块链技术



转载请注明 AIQ - 最专业的机器学习大数据社区  http://www.6aiq.com

AIQ 机器学习大数据 知乎专栏 点击关注

以太坊开发技术基础

以太坊概述

以太坊是可编程的区块链,是业内公认的区块链 2.0 代表项目。可以将以太坊理解为一个操作系统,使用 Solidity 等语言编写智能合约发布应用到链上,使用 Go、Java、Python、JavaScript 等语言在链下调用链上的智能合约读写区块链数据,通过这种方式实现各种各样的区块链应用。

比特币的总上限是 2100 万,而以太坊的内置代币以太币(Ether)没有确切的总量上限。目前以太坊大概每 15 秒出一个新块,一个新块奖励矿工 3 ETH 。以太坊的设计者认为随着时间流逝总会发生因为粗心和死亡等原因带来的币的遗失,假设币的遗失是每年货币供应量的一个固定比例,则最终总的流通中的货币供应量会稳定在一个等于年货币发行量除以遗失率的值上,使得供应量会趋于稳定。

比特币缺少图灵完备性,尽管比特币脚本语言可以支持多种计算,但是它不能支持所有的计算,如不支持 for 循环。以太坊是准图灵完备的,之所以增加“准”,是因为智能合约在以太坊区块链上执行时是受限的。在以太坊区块链上执行交易(转账、调用智能合约)需要消耗 Gas ,一般来说操作步骤越复杂需要的 Gas 越多,而一个块有 Gas 上限(目前约为 800 万)。向普通账户做 1 次转账操作目前消耗 2.1 万 Gas。

在块 Gas 上限为 800 万时,假设调用一个智能合约中某个函数时会向 400 个账户转账,因为会至少消耗 400 * 2.1 万 = 820 万 Gas,超出块的 Gas 上限 800 万,合约调用会失败。

关于以太坊更详细的介绍可以参考:以太坊白皮书和以太坊黄皮书。

Solidity

Solidity 是一种在语法上类似 JavaScript 的高级语言,编译 Solidity 代码可以生成以太坊虚拟机代码。Solidity 是静态类型语言,支持继承、库和复杂的用户定义类型等特性。使用 Solidity 可以很容易创建投票、众筹、封闭拍卖、多重签名钱包、谜恋猫游戏之类的智能合约。

由于以太坊区块链的限制,在链上无法读取链下数据,使用 Solidity 你也无法来调用传统的 API,例如你无法调用某天气网站提供的天气 API。另外在以太坊区块链上,无法让程序在指定时间自动运行。

谜恋猫游戏为了真实性,在猫怀孕后不是立即生出小猫,而是需要在满足一定条件后由外部来触发生猫函数为猫提供接生服务,一些开发者根据游戏的这个特性还可以赚猫的接生费,后文会有详细说明。

etherscan.io 提供了验证程序源码的服务。原理是使用公开的代码及指定的编译器版本再编译一次程序,然后和发布到区块链的以太坊的二进制代码做比对,如果一致说明公开的代码就是在区块链上运行的那份代码。下图是一份通过验证的代码截图。

可以访问这里,进一步了解 Solidity。

ERC-20 和 ERC-721

ERC-20 和 ERC-721 都是以太坊 EIP(Ethereum Improvement Proposal,以太坊改进协议),更多 EIP 见这里。

ERC-20 定义了一份代币标准,可以理解为定义了一个接口类,在实现具体的 ERC-20 代币时,要给出各个接口的具体实现,如获取代币名称、代币符号、总供应量、小数位数、转账等。使用 ERC-20,可以大幅度降低发币成本,发币方无需开发钱包和区块链浏览器,交易所也可以轻松支持新的代币充值提现等操作。

ERC-20 币是同质的,你的一个币和我的一个币是等价的。ERC-721 是非同质代币(Non-fungible Tokens),每个 ERC-721 有唯一的 ID,转账时,不再是转多少币,而是转某个 tokenId,如 transferFrom:

function transferFrom(address _from, address _to, uint256 _tokenId) external payable;

谜恋猫实现了 ERC-721 规范,每个猫有一个唯一的 ID,玩家花 ETH 买猫时,智能合约会调用 transferFrom 修改猫的所有者。

搭建以太坊全节点

我使用了以太坊 Go 客户端搭建的全节点,参考文档见这里,几个注意事项如下:

  • 电脑配置不能太低。我刚开始使用的是阿里云 1 核 CPU、2500 MHz 的 ECS,发现怎么也同步不到最新块,升级到了 4 核后同步正常了;

  • 第一次同步时使用 - -fast 选项,可以更快地同步到最新块,目前(2018-04-02)使用 - -fast 选项同步到最新块后预计占用 60G 空间;

  • geth 运行时间长了可能会有问题,我使用守护进程启动 geth,每 4 个小时 kill 掉 geth,目前基本上能一直同步到最新块;

  • 硬盘空间要足够大,建议至少 1T 以上。我 3 个月前使用 - -fast 同步完成后才占 40 多 G 空间,之后正常模式同步后硬盘占用空间快速增长,运行 3 个月左右已经 500G 了。

为了更方便、更快速的调用相关 API,建议在本地服务器上搭建一个以太坊全节点,并保持同步到最新区块高度。如果想通过程序买卖猫但又不想自己搭建全节点,可以使用 MetaMask 的节点,API 地址请访问这里,使用 MetaMask 的节点 API,监听事件可能会受到影响,一个方法是遍历某个区块的所有交易信息,然后选择自己关注的交易信息再做相关处理。

谜恋猫系统结构

yptokitties.co 买过猫,建议先买只猫后再阅读后续内容。一些入门攻略见这里,遇到问题可通过谜恋猫 QQ 群(728507998)咨询。

谜恋猫 DApp

谜恋猫是一个 DApp(Decentralized Application),部分程序部署在区块链上,部分程序部署在中心化的服务器上,总体架构如下图:

### 谜恋猫智能合约

谜恋猫在以太坊区块链上一共有 4 个智能合约:

  • CryptoKittiesCore :核心代码,已开源,2016 行代码;

  • CryptoKittiesSalesAuction :猫拍卖机制,已开源,604 行代码;

  • CryptoKittiesSiringAuction :配种拍卖机制,已开源,589 行代码;

  • geneScience :基因工程,未开源。

以玩家挂单卖猫为例,说明相关步骤:

  1. 玩家在自己某只猫的页面点击出售按钮,设置出售价格,通过 MetaMask 钱包操作后等待(页面上猫的状态是非在售;MetaMask 交易状态是 pending 中);

  2. MetaMask 将交易广播出去(页面上猫的状态是非在售;MetaMask 交易状态是 pending 中);

  3. 交易被矿工打包到区块中(页面上猫的状态是非在售;MetaMask 交易状态是 pending 中);

  4. 谜恋猫的以太坊节点监听到卖猫事件,更新数据库中猫的信息、更新缓存数据、更新搜索索引数据;MetaMask 的以太坊节点更新交易状态(页面上猫的状态是在售;MetaMask 交易状态是已完成);

用户卖猫后,在页面上不是立即可以看到猫处于在售中,而是需要等待一会儿才能看到,整个过程是异步的。这也为懂技术的玩家留下机会,可以在猫刚开卖还未在页面上显示出售中就能立即买下猫,详细方法见后文。

谜恋猫游戏规则

以太坊钱包就是用户的 ID

一般涉及到用户数据的网站或 App,都会要用户注册帐号,哪怕是使用第三方授权。而对于谜恋猫游戏,即使你之前从未访问过网站,只要有你的以太坊钱包地址,其他人就可以给你送猫。

安装 MetaMask 插件后第一次登陆网站,需要你按提示点击一个消息签名按钮,以便验证当前用户身份。原理是椭圆曲线加密算法,相关函数为 web3.eth.sign(address, dataToSign)、ecRecover,具体用法可以搜索下。

买猫

在谜恋猫页面,点击顶部导航“猫市”,默认就是待收养的猫猫。点击“筛选猫咪”可以通过多种方式做筛选,找到自己的目标猫咪。初期玩建议按价格从低到高排序,选两三只便宜的猫咪。搜索功能并不是直接从区块链读取数据的,而是通过同步区块链数据后在中心化服务器中建立的索引。

点击一只猫咪后,进入单个猫咪页面,再点击“立即购买”就可以买猫了。

 

在点击“立即购买”按钮时,会调用 web3js,触发弹出 MetaMask 插件窗口。MetaMask 插件中会显示 Amount(转账额度)、GasLimit(燃料上限)、GasPrice(燃料价格)等参数,部分数据做了隐藏,如购买猫调用的是 bid(uint256 _tokenId) 函数。

点击“submit”按钮后,MetaMask 会将交易数据提交到以太坊网络,等待矿工打包确认,当矿工将交易数据打包到某个区块中才算真正完成相关函数执行。但成功打包到区块中不一定能成功买到猫,因为交易过程是异步的,在这个过程中也可能有其他人购买同一只猫,如果他人的交易比你的交易优先被矿工打包,你就买不到猫了。另外,卖家也可以取消卖猫。


更多高质资源 尽在AIQ 机器学习大数据 知乎专栏 点击关注

转载请注明 AIQ - 最专业的机器学习大数据社区  http://www.6aiq.com