天才程序员: "开发 CryptoKitties 难不难? 只需掌握这3点..."

2019-07-16 10:12:41 浏览数 (1)

来源 | 《以太坊技术详解与实战》

作者 | 闫莺、郑凯、郭众鑫

责编 | 乔治

出品 | 区块链大本营(blockchain_camp)

什么是以太坊上的数字资产? 你在 CryptoKitties 购买的猫咪就是一种数字资产; 那么,如何发行一种数字资产? 其实很简单。

你只需了解以下 3 部分内容:

  • 数字资产的定义及其发行和流通;
  • ERC 20 代币合约标准;
  • CryptoKitties 及 ERC 721 合约标准。

发行一款 CryptoKitties 简直是 so easy!还等什么?学起来吧!(文末有福利,免费送书)

◆ ◆ ◆ ◆ ◆

以太坊设计目标就是让各种数字资产以智能合约的形式运行在以太坊虚拟机上。目前,在以太坊上的众多智能合约之中,应用最为广泛的是代币合约(Token Contract)。代币合约是在以太坊上管理账户及其拥有的代币的智能合约,实质上可以理解为一张账户地址和对应账户代币余额的映射表。

从某种意义上讲,以太坊上的代币可以被称为数字资产,记录资产数据的代币合约就是一份账本。代币既可以表示某一虚拟货币的价值,又可以象征某些实际的物理量,甚至可用于记录账户持有者的信誉值。但归根结底,以太坊上的数字资产就是指以太坊上代币合约中记录的账户代币余额数据。

与以往搭建由区块链直接记录的加密货币(Cryptocurrency)不同,以太坊上的数字资产(Digital Asset on Ethereum)是记录在以太坊之上的代币合约中。一般意义上的加密货币,如比特币、以太币和莱特币等,是记录在账户状态中,直接存储在区块内的数据,伴随“挖矿”等机制发行,并通过交易的方式流通。而数字资产则是以以太坊区块链为平台,记录在更高一层的代币合约中,具体来讲是存储在以太坊交易消息数据字段的可执行代码中。

数字资产的发行无须经过复杂的“挖矿”程序,代币合约的创建者可以通过智能合约定义自己的代币发行标准,直接在合约代码中实现“铸币”功能。并且,代币的流通是通过在以太坊交易中调用智能合约的函数接口进行转账,代币合约创建者同样可以在这一过程中添加一些自定义的操作。相比之下,以太坊上的数字资产较加密货币拥有更高的灵活性,并且其安全性也由以太坊区块链机制和智能合约代码保证。

数字资产的发行和流通

以太坊上的代币作为一种数字资产,需要有它的发行和流通机制。相较于以太币等加密货币基于 PoW 和 PoS 共识算法的发行机制以及基于发送交易进行转账的流通机制,以太坊上数字资产的发行和流通更加简便灵活,相关的操作一般由代币合约创建者在代币合约中实现。常见的代币合约在记录账户及代币余额的基础上,还包含一些基本的数字资产管理操作,如铸造代币、销毁代币以及代币转账等。

代币转账是代币合约的一项基本功能,也是数字资产流通功能的具体实现。例如,账户 Alice 调用合约的转账功能函数,向账户 Bob 转入 50 个代币,此时合约中记录的 Alice 账户余额减少了 50,而 Bob 账户余额增加了 50。代币合约通过铸造代币和销毁代币来增加或减少代币供应总量,这两者是数字资产发行和回收功能的具体实现。

当其他账户通过向合约转入以太币或其他方式调用合约铸造功能时,该代币合约向账户对应的余额值增加相应数量的代币,代币的总供应量也相应增加,完成铸币。例如,账户 Charlie 调用代币合约的铸币功能函数,合约经验证后在将其余额增加 50 个代币,同时代币总供应量也增加 50 个代币。

与之类似,账户通过调用合约的销毁功能函数,销毁其账户余额中的代币,代币总供应量也相应地减少。但是,通常代币合约的代币销毁功能是通过向特殊的零地址 0x000...0000 中转入相应数量的代币来完成,此时 代币总供应量不会减少。

除了以上的转账、铸币、销毁等基本功能,代币合约还可以加入数字资产的查询、权限控制,甚至经济学公式计算等功能。那么,功能繁多的代币智能合约是否有共同点,或者对代币合约的基本功能进行一些规范呢?以太坊开发人员在以太坊改进计划(Ethereum Improvement Proposal,EIP)中提出了 ERC 20 代币合约标准,为以太坊代币合约制定了一套标准的接口。

ERC 20 代币合约标准

ERC 20 代币合约标准规定了一个以太坊代币合约所需实现的函数功能和事件记录。该标准满足了代币作为数字资产所必须具备的一些基本功能和要求,如注明代币名称、代币转账、本账户中允许链上第三方使用的代币限额等。ERC 20 的出现为以太坊上的代币合约提供了一个标准化的方案,也对以太坊上数字资产的实现进行了一定的规范。ERC 20 标准使得种类繁多的代币能够被更多的去中心化应用(DApp)、交易所等兼容。

代码语言:javascript复制
 1contract ERC20 {
 2    string public constant name = "Token Name";
 3    string public constant symbol = "SYM";
 4    uint8 public constant decimals = 18;
 5
 6    function totalSupply() constant returns (uint supply);
 7    function balanceOf( address who ) constant returns (uint value);
 8    function allowance( address owner, address spender ) constant returns (uint_allowance);
 9    function transfer( address to, uint value) returns (bool ok);
10    function transferFrom( address from, address to, uint value) returns (bool ok);
11    function approve( address spender, uint value ) returns (bool ok);
12
13    event Transfer( address indexed from, address indexed to, uint value);
14    event Approval( address indexed owner, address indexed spender, uint value);
15}

ERC 20 标准接口

自 2015 年提出以来,ERC 20 代币合约标准在以太坊开发社区的协商下逐步确定。这一标准的出现为 2017 年以太坊合约代币井喷式发展打下了基础。

随着智能合约和代币的兴起,以及 ERC 20 代币合约标准的提出,以太坊上涌现出了大量符合 ERC 20 标准的代币,如 EOS、BAT 和 REP 等。目前以太坊上市场份额较大的代币主要是由 DApp 发行的代币或者开发其他种类区块链之前众筹而发行的代币,包括 EOS 代币、BAT 代币和 REP 代币等。

EOS 代币

EOS 代币是由 Daniel Larime 等人开发的 EOS.IO 项目所发行的一种代币。EOS.IO 是一款新一代的区块链项目,针对以太坊现有的一些问题作出改进。EOS.IO 采用股权委托证明 (DPoS)的共识算法,提高吞吐量和用户数量,计划可支持每秒百万级别的交易量;将交易延迟降低至数秒,并且拥有冻结功能,更便于项目升级和问题修复。自 2017 年 6 月公布白皮书并开放众筹以来,EOS.IO 项目受到广泛关注,人们将其视为以太坊有力的竞争者。

该项目于 2017 年 9 月发布了 EOS.IO Dawn 1.0 版本,于 12 月发布了 Dawn 2.0 版本,截至笔者撰稿时,已完成了 P2P 网络的搭建、导入创世区块的测试等开发步骤。此外,该项目通过在以太坊上发行 ERC 20 标准代币 EOS,目前仍处于众筹阶段,众筹将于 2018 年 6 月结 束。此后,在 EOS.IO 区块链开发完成正式上线后,以太坊上的 EOS 代币会通过创世区块转移至 EOS 链上,以太坊用户的 EOS 代币可由此转换为 EOS 链上的数字货币。

BAT 代币

BAT 代币(Basic Attention Token)是以太坊上一款数字广告平台 DApp 在 2017 年 5 月 所发行的一种 ERC 20 代币。该 DApp 将前端浏览器上统计的用户网页广告停留时间换算成用户的“注意力”(attention),依此转换成 BAT 代币的价值,并让广告主由此向广告发行商支付相应的 BAT 代币。目前该 DApp 支持在 Brave 浏览器上实现广告统计功能,利用以太坊上的 ERC 20 代币实现了广告对用户的吸引力和广告价值之间的转化以及广告实际价值的流通,略去了广告主、发行商和用户之间的众多中间商,以更加透明高效的方式实现数字广告的升级。

REP 代币

REP 代币是由 Augur DApp 项目 2017 年 7 月发行的一种代币。Augur 是一个用于预测未来事件的、基于以太坊区块链的市场预测平台,用户可以通过该平台对未来的事件进行预测并押注,若预测正确则可以获得奖励,否则会有一定的损失。Augur 平台的智能合约中包括了一套 ERC 20 标准代币合约,其代币 REP 可用于预测过程中的交易。相比于一般的市场预测平台,Augur 将平台搭建于以太坊区块链之上,使用智能合约进行管理,实现了去中心化,更加安全可靠,并且使用符合 ERC 20 标准的 REP 代币,提高市场交易效率,增强了流通性。

ERC 721 代币合约标准

除了最为通用的 ERC 20 标准,目前有许多人在此基础上不断提出功能更为全面、内容更为细致的合约标准,如 ERC 721、ERC 223、ERC 644 以及 ERC 677 等。本文将主要介绍 ERC 721 合约标准。

1、标准定义

ERC 721 合约标准规定了一种不可替代的代币(Non-fungible Token,NFT)的合约接口。此类代币的最小单位为个,即在 ERC 20 标准中对应小数点位的 decimal 值为零。此类代币最重要的特点为每一个代币都是独一无二的。每一个代币拥有各自的 _tokenId 标号, 并且可以附上一些各不相同的特征值,这样使得每个代币都是“不可替代”的。ERC 721 代币合约标准的接口如下。

代码语言:javascript复制
 1contract ERC721 {
 2    // Required method
 3    function totalSupply() constant returns (uint256 totalSupply);
 4    function balanceOf(address _owner) constant returns (uint256 balance);
 5    function ownerOf(uint256 _tokenId) constant returns (address owner);
 6    function approve(address _to, uint256 _tokenId);
 7    function takeOwnership(uint256 _tokenId);
 8    function transfer(address _to, uint256 _tokenId);
 9
10    // Optional method
11    function name() constant returns (string name);
12    function symbol() constant returns (string symbol);
13    function tokenOfOwnerByIndex(address _owner, uint256 _index) constant returns (uint tokenId);
14    function tokenMetadata(uint256 _tokenId) constant returns (string infoUrl);
15
16    // Events
17    event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);
18    event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId);
19}

ERC 721 标准继承了 ERC 20 标准的一些基本功能接口,如 name( )、symbol( )、 totalSupply( )、balanceOf(),以 及 事 件 Transfer( )、Approval( ) 等,并在一些函数,如 transfer( )、approve( ) 中加入了 _tokenId 用以指定特定的代币。

除此之外,ERC 721 相比于 ERC 20 还新增了一些功能函数。其中,ownerOf( ) 和 tokenOfOwnerByIndex( ) 分别为根据代币 ID 查询该代币的持有者,以及根据持有者及其索引查询所持有的代币 ID;ERC 20 中的 transferFrom( ) 方法被更改为 takeOwnership( ),在限额 approve 允许的条件下,交易发起方 msg.sender 调用该函数可以将指定 _tokenId 的代币从他人处转至自己的账户中;tokenMetadata( ) 函数用于查看代币的元数据等,根据代币的 ID 查询到一个 URL 格式字符串,其中包含这一代币的名称、图像和描述等相关信息。

2、CryptoKitties DApp

近来一款养猫游戏 CryptoKitties 的 DApp 在以太坊上引起一阵热潮,上线仅两周,这款 DApp 便吸引了超过 150 000 名用户,买卖小猫的交易数额将近 15 000 000 美元,其中用户所发出的交易数量占到了以太坊网络中所有交易的 1/4,甚至一度造成了网络堵塞。

在这款 DApp 中,用户可以饲养、交易一只只可爱的小猫,每一只小猫都拥有独一无二的基因,并且外表也是各不相同。在游戏中,用户还可以让小猫进行繁殖,由不同父母繁育出的后代会产生出全新的基因和外表,这一有趣的特征吸引了许多以太坊用户纷纷饲养繁育自己的小猫。实际上,每只小猫形态各异的特点正是由 ERC 721 合约标准中的“不可替代的代币”NFT 所实现。

CryptoKitties DApp 是一套以太坊上的智能合约,其中一只只各不相同的小猫正是合约中的一个个 NFT 代币。CryptoKitties 合约应用了 ERC 721 标准定义了小猫代币,每个小猫代币拥有独一无二的 _tokenId,并且包含基因 genes、出生时间 birthTime、父亲 matronId、母亲 sireId 等信息。

合约根据 ERC 721 标准实现了 transfer( )、approve( )、ownerOf( ) 和 tokenOfOwner( ) 等函数功能。但该合约中仍保留了加上 _tokenId 后的 transferFrom( ) 函 数,相比 takeOwnership( ) 函数还能够实现(如向第三方转账等)更多的功能。以下是 CryptoKitties 合约中 ERC 721 接口部分的代码。

代码语言:javascript复制
 1/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens
 2/// @author Dieter Shirley <dete@axiomzen.co> (https://github.com/dete)
 3
 4contract ERC721 {
 5    // Required methods
 6    function totalSupply() public view returns (uint256 total);
 7    function balanceOf(address _owner) public view returns (uint256 balance); function ownerOf(uint256 _tokenId) external view returns (address owner); function approve(address _to, uint256 _tokenId) external;
 8    function transfer(address _to, uint256 _tokenId) external;
 9    function transferFrom(address _from, address _to, uint256 _tokenId) external;
10
11    // Events
12    event Transfer(address from, address to, uint256 tokenId);
13    event Approval(address owner, address approved, uint256 tokenId);
14
15    // Optional
16    // function name() public view returns (string name);
17    // function symbol() public view returns (string symbol);
18    // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds);
19    // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl);
20
21    // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165)
22    function supportsInterface(bytes4 _interfaceID) external view returns (bool);
23}

相比于普通的数字加密货币,以太坊上的数字资产利用了以太坊智能合约的灵活性,既保持了去中心化和安全等特性,又具有轻量化以及更强的流通性等特点。

更多参考:

https://github.com/cryptocopycats/awesome-cryptokitties

https://github.com/ethereum/EIPs/issues/721

https://dwz.cn/7iPm83ZG

0 人点赞