买不起2.6亿一只的加密猫, 他用10分钟生了一窝

不知道多少人和营长一样,在结束一天的工作后,就想瘫在沙发上玩玩游戏,一扫一天的疲惫。不过现在的游戏都越来越氪金了,就像玩家们常说的:不充钱你怎么能变强!!!

买不起2.6亿一只的加密猫,

不知道多少人和营长一样,在结束一天的工作后,就想瘫在沙发上玩玩游戏,一扫一天的疲惫。不过现在的游戏都越来越氪金了,就像玩家们常说的:不充钱你怎么能变强!!!

但要说氪金,很少有哪个游戏能比得上区块链游戏,因为区块链上的游戏都建立在一笔笔真实的加密货币交易之上。

就拿最火的去中心化游戏加密猫来说,其刚上线时一只加密猫能卖到上千元人民币,最贵的一只竟卖到了 125673 个以太币,在当时约合人民币 2.6 亿元(太可怕了)。

买不起2.6亿一只的加密猫,

当时最贵的一只加密猫

不禁让人直呼:玩不起,玩不起。

玩不起又想玩怎么办?

手把手开发一款区块链游戏,不就OK了,何况又那么简单,10分钟就够了

这是一款怎样的 DApp?

从现在开始,我们将构建一个类似于加密猫的简单 DApp,我们称之为加密毒蛇

你可能会问为什么是蛇呢,但为什么不能是蛇呢?Python 翻译过来也是蛇呀。

在这个 DApp 中,你可以购买毒蛇和养殖毒蛇,应用页面是这样的:

买不起2.6亿一只的加密猫,

加密毒蛇程序的页面

其功能列表如下:

  • 创造毒蛇 – 用户能够通过购买或让两条毒蛇交配来创造新的毒蛇。

  • 查看毒蛇的详细信息 – 用户应该能够查看自己拥有的毒蛇的详细信息并进行显示。

创建加密毒蛇,你至少需要用到以下工具

  • 智能合约相关:

  • 智能合约编程语言 Solidity

  • 开源智能合约开发环境 Remix

  • 用于调试和测试智能合约的 Metamask

  • 前端技术相关:

  • 用于与本地以太坊节点进行通信的 js 库 Web3.js

  • 构建用户界面的渐进式框架 Vue.js

  • 用于创建 vue 项目的 Vue-cli

  • 前端框架 Boostrap-vue

此外,你还需要使用 Git 来克隆一些代码模板。

在进行编程之前,这里先假定你已经对以下的知识有了基本的了解。

  • 了解智能合约及其编程语言 Solidity 。

  • 了解使用 MetaMask 进行智能合约的调试和测试。

  • 了解使用 Remix IDE 进行智能合约的编译和部署。

当然了,如果你对这一些知识还有欠缺,也不用担心,本文会详细介绍每一个细节。

深入了解 ERC-721 标准

ERC-721 是一个用来描述如何在以太坊区块链上制造不可替代 token 的标准。满足 ERC-721 标准的每个 token 或其他数字资产都是唯一的,这意味着它不等同于任何其他 token。你可以把它们想象成一种特殊的,独一无二的收藏品。(如果你已了解 ERC-721,可选择跳过这一部分)

ERC-721 标准的接口

根据标准的官方文档,ERC-721 规定了智能合约用以管理、持有和交易唯一 token 必须实现的最小接口:

  • balanceOf(_owner) - 返回特定所有者 _owner 钱包中的 token 余额。

  • ownerOf(_tokenId) - 返回特定 token 所有者的钱包地址。

  • totalSupply() - 返回创建的 token 总数。

  • transfer(_to,_tokenId) - 将 _tokenId 标记的 token 从发送者的钱包转移到指定接收者的钱包。

  • takeOwnership(_tokenId) - 声明给定 ID 的 token 的所有权。

  • approve(_to,_tokenId) - 批准另一个地址来声明给定 ID 的 token 所有权。

此外,它还定义了两个事件:Transfer 和 Approval。当 token 从一个钱包转移到另一个钱包时,会触发转移事件。另一方面,当一个账户批准另一个账户声明他拥有的某个 token 的所有权时,会触发批准事件。

OpenZeppelin 的 ERC-721 token 实现

OpenZeppelin 是一款开源智能合约开发框架,它提供了可重复使用的智能合约模板,包括 ERC-20 和 ERC-721 等标准 token 的实现模板。在这里,我们将导入他们的 ERC-721 token 实现,这样我们就不必从头开始编写它,避免了重复造轮子。

创建智能合约

此 DApp 是基于以太坊平台开发,所以需要使用 Solidity 语言发行 token。

首先,在开源智能合约开发环境 Remix 中,创建一个名为 ViperToken.sol 的新文件并在其中添加以下代码:

 1// We will be using Solidity version 0.5.3
 2pragma solidity 0.5.3;
 3// Importing OpenZeppelin's ERC-721 Implementation
 4import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol";
 5// Importing OpenZeppelin's SafeMath Implementation
 6import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol";
 7
 8
 9contract ViperToken is ERC721Full {
10    using SafeMath for uint256;
11    // This struct will be used to represent one viper
12    struct Viper {
13        uint8 genes;
14        uint256 matronId;
15        uint256 sireId;
16    }
17
18    // List of existing vipers
19    Viper[] public vipers;
20
21    // Event that will be emitted whenever a new viper is created
22    event Birth(
23        address owner,
24        uint256 viperId,
25        uint256 matronId,
26        uint256 sireId,
27        uint8 genes
28    );
29
30    // Initializing an ERC-721 Token named 'Vipers' with a symbol 'VPR'
31    constructor() ERC721Full("Vipers""VPR"public {
32    }
33
34    // Fallback function
35    function() external payable {
36    }
37
38    /** @dev Function to determine a viper's characteristics.
39      * @param matron ID of viper's matron (one parent)
40      * @param sire ID of viper's sire (other parent)
41      * @return The viper's genes in the form of uint8
42      */

43    function generateViperGenes(
44        uint256 matron,
45        uint256 sire
46    )

47        internal
48        pure
49        returns (uint8)
50    
{
51        return uint8(matron.add(sire)) % 6 + 1;
52    }
53
54    /** @dev Function to create a new viper
55      * @param matron ID of new viper's matron (one parent)
56      * @param sire ID of new viper's sire (other parent)
57      * @param viperOwner Address of new viper's owner
58      * @return The new viper's ID
59      */

60    function createViper(
61        uint256 matron,
62        uint256 sire,
63        address viperOwner
64    )

65        internal
66        returns (uint)
67    
{
68        require(viperOwner != address(0));
69        uint8 newGenes = generateViperGenes(matron, sire);
70        Viper memory newViper = Viper({
71            genes: newGenes,
72            matronId: matron,
73            sireId: sire
74        });
75        uint256 newViperId = vipers.push(newViper).sub(1);
76        super._mint(viperOwner, newViperId);
77        emit Birth(
78            viperOwner,
79            newViperId,
80            newViper.matronId,
81            newViper.sireId,
82            newViper.genes
83        );
84        return newViperId;
85    }
86
87    /** @dev Function to allow user to buy a new viper (calls createViper())
88      * @return The new viper's ID
89      */

90    function buyViper() external payable returns (uint256) {
91        require(msg.value == 0.02 ether);
92        return createViper(00, msg.sender);
93    }
94
95    /** @dev Function to breed 2 vipers to create a new one
96      * @param matronId ID of new viper's matron (one parent)
97      * @param sireId ID of new viper's sire (other parent)
98      * @return The new viper's ID
99      */

100    function breedVipers(uint256 matronId, uint256 sireId) external payable returns (uint256) {
101        require(msg.value == 0.05 ether);
102        return createViper(matronId, sireId, msg.sender);
103    }
104
105    /** @dev Function to retrieve a specific viper's details.
106      * @param viperId ID of the viper who's details will be retrieved
107      * @return An array, [viper's ID, viper's genes, matron's ID, sire's ID]
108      */

109    function getViperDetails(uint256 viperId) external view returns (uint256, uint8, uint256, uint256) {
110        Viper storage viper = vipers[viperId];
111        return (viperId, viper.genes, viper.matronId, viper.sireId);
112    }
113
114    /** @dev Function to get a list of owned vipers' IDs
115      * @return A uint array which contains IDs of all owned vipers
116      */

117    function ownedVipers() external view returns(uint256[] memory) {
118        uint256 viperCount = balanceOf(msg.sender);
119        if (viperCount == 0) {
120            return 

生成图片
5

发表评论

买不起2.6亿一只的加密猫, 他用10分钟生了一窝

星期六 2019-05-04 14:13:44

买不起2.6亿一只的加密猫,

不知道多少人和营长一样,在结束一天的工作后,就想瘫在沙发上玩玩游戏,一扫一天的疲惫。不过现在的游戏都越来越氪金了,就像玩家们常说的:不充钱你怎么能变强!!!

但要说氪金,很少有哪个游戏能比得上区块链游戏,因为区块链上的游戏都建立在一笔笔真实的加密货币交易之上。

就拿最火的去中心化游戏加密猫来说,其刚上线时一只加密猫能卖到上千元人民币,最贵的一只竟卖到了 125673 个以太币,在当时约合人民币 2.6 亿元(太可怕了)。

买不起2.6亿一只的加密猫,

当时最贵的一只加密猫

不禁让人直呼:玩不起,玩不起。

玩不起又想玩怎么办?

手把手开发一款区块链游戏,不就OK了,何况又那么简单,10分钟就够了

这是一款怎样的 DApp?

从现在开始,我们将构建一个类似于加密猫的简单 DApp,我们称之为加密毒蛇

你可能会问为什么是蛇呢,但为什么不能是蛇呢?Python 翻译过来也是蛇呀。

在这个 DApp 中,你可以购买毒蛇和养殖毒蛇,应用页面是这样的:

买不起2.6亿一只的加密猫,

加密毒蛇程序的页面

其功能列表如下:

  • 创造毒蛇 – 用户能够通过购买或让两条毒蛇交配来创造新的毒蛇。

  • 查看毒蛇的详细信息 – 用户应该能够查看自己拥有的毒蛇的详细信息并进行显示。

创建加密毒蛇,你至少需要用到以下工具

  • 智能合约相关:

  • 智能合约编程语言 Solidity

  • 开源智能合约开发环境 Remix

  • 用于调试和测试智能合约的 Metamask

  • 前端技术相关:

  • 用于与本地以太坊节点进行通信的 js 库 Web3.js

  • 构建用户界面的渐进式框架 Vue.js

  • 用于创建 vue 项目的 Vue-cli

  • 前端框架 Boostrap-vue

此外,你还需要使用 Git 来克隆一些代码模板。

在进行编程之前,这里先假定你已经对以下的知识有了基本的了解。

  • 了解智能合约及其编程语言 Solidity 。

  • 了解使用 MetaMask 进行智能合约的调试和测试。

  • 了解使用 Remix IDE 进行智能合约的编译和部署。

当然了,如果你对这一些知识还有欠缺,也不用担心,本文会详细介绍每一个细节。

深入了解 ERC-721 标准

ERC-721 是一个用来描述如何在以太坊区块链上制造不可替代 token 的标准。满足 ERC-721 标准的每个 token 或其他数字资产都是唯一的,这意味着它不等同于任何其他 token。你可以把它们想象成一种特殊的,独一无二的收藏品。(如果你已了解 ERC-721,可选择跳过这一部分)

ERC-721 标准的接口

根据标准的官方文档,ERC-721 规定了智能合约用以管理、持有和交易唯一 token 必须实现的最小接口:

  • balanceOf(_owner) - 返回特定所有者 _owner 钱包中的 token 余额。

  • ownerOf(_tokenId) - 返回特定 token 所有者的钱包地址。

  • totalSupply() - 返回创建的 token 总数。

  • transfer(_to,_tokenId) - 将 _tokenId 标记的 token 从发送者的钱包转移到指定接收者的钱包。

  • takeOwnership(_tokenId) - 声明给定 ID 的 token 的所有权。

  • approve(_to,_tokenId) - 批准另一个地址来声明给定 ID 的 token 所有权。

此外,它还定义了两个事件:Transfer 和 Approval。当 token 从一个钱包转移到另一个钱包时,会触发转移事件。另一方面,当一个账户批准另一个账户声明他拥有的某个 token 的所有权时,会触发批准事件。

OpenZeppelin 的 ERC-721 token 实现

OpenZeppelin 是一款开源智能合约开发框架,它提供了可重复使用的智能合约模板,包括 ERC-20 和 ERC-721 等标准 token 的实现模板。在这里,我们将导入他们的 ERC-721 token 实现,这样我们就不必从头开始编写它,避免了重复造轮子。

创建智能合约

此 DApp 是基于以太坊平台开发,所以需要使用 Solidity 语言发行 token。

首先,在开源智能合约开发环境 Remix 中,创建一个名为 ViperToken.sol 的新文件并在其中添加以下代码:

 1// We will be using Solidity version 0.5.3
 2pragma solidity 0.5.3;
 3// Importing OpenZeppelin's ERC-721 Implementation
 4import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol";
 5// Importing OpenZeppelin's SafeMath Implementation
 6import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol";
 7
 8
 9contract ViperToken is ERC721Full {
10    using SafeMath for uint256;
11    // This struct will be used to represent one viper
12    struct Viper {
13        uint8 genes;
14        uint256 matronId;
15        uint256 sireId;
16    }
17
18    // List of existing vipers
19    Viper[] public vipers;
20
21    // Event that will be emitted whenever a new viper is created
22    event Birth(
23        address owner,
24        uint256 viperId,
25        uint256 matronId,
26        uint256 sireId,
27        uint8 genes
28    );
29
30    // Initializing an ERC-721 Token named 'Vipers' with a symbol 'VPR'
31    constructor() ERC721Full("Vipers""VPR"public {
32    }
33
34    // Fallback function
35    function() external payable {
36    }
37
38    /** @dev Function to determine a viper's characteristics.
39      * @param matron ID of viper's matron (one parent)
40      * @param sire ID of viper's sire (other parent)
41      * @return The viper's genes in the form of uint8
42      */

43    function generateViperGenes(
44        uint256 matron,
45        uint256 sire
46    )

47        internal
48        pure
49        returns (uint8)
50    
{
51        return uint8(matron.add(sire)) % 6 + 1;
52    }
53
54    /** @dev Function to create a new viper
55      * @param matron ID of new viper's matron (one parent)
56      * @param sire ID of new viper's sire (other parent)
57      * @param viperOwner Address of new viper's owner
58      * @return The new viper's ID
59      */

60    function createViper(
61        uint256 matron,
62        uint256 sire,
63        address viperOwner
64    )

65        internal
66        returns (uint)
67    
{
68        require(viperOwner != address(0));
69        uint8 newGenes = generateViperGenes(matron, sire);
70        Viper memory newViper = Viper({
71            genes: newGenes,
72            matronId: matron,
73            sireId: sire
74        });
75        uint256 newViperId = vipers.push(newViper).sub(1);
76        super._mint(viperOwner, newViperId);
77        emit Birth(
78            viperOwner,
79            newViperId,
80            newViper.matronId,
81            newViper.sireId,
82            newViper.genes
83        );
84        return newViperId;
85    }
86
87    /** @dev Function to allow user to buy a new viper (calls createViper())
88      * @return The new viper's ID
89      */

90    function buyViper() external payable returns (uint256) {
91        require(msg.value == 0.02 ether);
92        return createViper(00, msg.sender);
93    }
94
95    /** @dev Function to breed 2 vipers to create a new one
96      * @param matronId ID of new viper's matron (one parent)
97      * @param sireId ID of new viper's sire (other parent)
98      * @return The new viper's ID
99      */

100    function breedVipers(uint256 matronId, uint256 sireId) external payable returns (uint256) {
101        require(msg.value == 0.05 ether);
102        return createViper(matronId, sireId, msg.sender);
103    }
104
105    /** @dev Function to retrieve a specific viper's details.
106      * @param viperId ID of the viper who's details will be retrieved
107      * @return An array, [viper's ID, viper's genes, matron's ID, sire's ID]
108      */

109    function getViperDetails(uint256 viperId) external view returns (uint256, uint8, uint256, uint256) {
110        Viper storage viper = vipers[viperId];
111        return (viperId, viper.genes, viper.matronId, viper.sireId);
112    }
113
114    /** @dev Function to get a list of owned vipers' IDs
115      * @return A uint array which contains IDs of all owned vipers
116      */

117    function ownedVipers() external view returns(uint256[] memory) {
118        uint256 viperCount = balanceOf(msg.sender);
119        if (viperCount == 0) {
120            return