# 区块链综合应用开发实践

By [leaf](https://paragraph.com/@leaf-6) · 2022-12-06

---

在区块链的开发过程中，除了开发自己的区块链以及基于某个公链或框架进行开发外，还有一些第三方平台提供了工具可以快速生成数字加密资产并进行交易，如国外的Opensea（网址http：//opensea.io）和RareBits（网址https：//rarebits.io/），国内的BIGE（网址http：//bige.game/）等。

**3个开发实例，包括一个以太坊查询分析系统开发实例、一个ERC20代币的开发实例和一个基于OpenSea平台的数字加密资产开发实例。**

●了解以太坊测试网络Ropsten。

●掌握web3.py库的功能。

●掌握以太坊数据的基本查询和分析方法。

●了解ERC20代币的开发。

●学习加密资产的开发过程。

●了解OpenSea交易平台。

以太坊之DApp开发实战中搭建了一个以太坊的本地测试环境，但本地测试环境的数据比较少，无法体现真实的以太坊网络的数据情况。所以在选择以太坊的公开测试网络Ropsten作为测试环境。

Ropsten是2016年11月上线的一个以太坊测试网络，以斯德哥尔摩（瑞典首都）的一个地铁站命名。Ropsten采用工作量证明的共识机制，它是对以太坊现有生产环境的最好模拟，在以太坊主网的系统和网络状态等方面都比较近似。而且Ropsten测试网络上的以太币是免费的，通过对接Ropsten测试网络来对以太坊进行各种测试和开发成本极低，所以选择Ropsten测试网络性价比很理想。下面使用之前第5章介绍的MetaMask插件连接到Ropsten测试网络。

（1）连接Ropsten测试网络

单击MetaMask插件，打开选项界面，再单击网络选项更改连接网络为Ropsten测试网络，如图8-1所示。

（2）创建测试账户

切换网络成功后接着单击用户头像，选择创建用户在Ropsten测试网络中生成一个新的账户，

在弹出界面中输入用户名并单击“CREATE”按钮进行创建，如图8-3所示。

（3）查看账户余额

创建完成后进入账户详情页面，新的账户余额为0个以太币，如图8-4所示。

（4）获取以太币

为了进行对接测试，最好能在Rospten测试网络中获取一定数量的以太币（对以太坊网络进行更新操作需要消耗以太币）。在Rospten测试网络中获取以太币的方法主要有以下几种。

●在http：//faucet.ropsten.be：3001/上申请，需要输入在Ropsten网络上的账户地址就可以了，转币操作非常迅速，目前一次可申请3ETH。

●找朋友给自己转币。

●自己挖矿。

毫无疑问，第一种方式是最方便快捷的，下面进行申请操作

2.申请以太币

申请以太币需要输入账户地址。

（1）复制账户地址

单击账户左上角菜单可以看到账户详情，在地址右边有一个复制按钮，单击复制地址信息.

（2）在Ropsten上进行申请

得到账户地址后，在浏览器中访问http：//faucet.ropsten.be：3001/，打开的页面上输入刚才复制的账户地址，如图

![](https://storage.googleapis.com/papyrus_images/020268c8a72696f670311a5225e08967708538bf18333ef0cb231ecb2d1ffb15.png)

（3）申请成功

单击“Send me test Ether”按钮申请测试以太币即可。申请成功后，页面下部会出现申请成功信息和转账交易记录的哈希值，如图

![](https://storage.googleapis.com/papyrus_images/c98dc833049492d45df4fe23c3e79303376c5fa73956c4707940b6efffcf4b4c.png)

注意，申请到的以太币需要Ropsten网络中其他结点确认，故申请成功后一般还需要半天左右时间才能在MetaMask看到申请到的以太币信息。

已经使用MetaMask插件创建了Ropsten测试网络的测试账号，为了对接这个测试网络的接口进行数据的查询和获取，在这里将使用web3.py库与Ropsten测试网络进行对接。

1.web3.py介绍

web3.py是以太坊接口的Python封装，通过JSON-RPC连接以太坊网络进行交互。web3.py和web3.js类似，其中web3.js主要适合浏览器端的Dapp的开发，而web3.py是基于Python开发的，更适合在服务器使用。

2.web3.py的安装使用

web3.py可以使用Python的包管理工具pip进行安装，首先新建一个虚拟环境。

（1）新建虚拟环境

这里先新建一个名为ch8的Python虚拟环境（web3.py支持Python3.5以上版本），命令如下：

virtualenv venv-p python3

（2）安装web3.py

创建完成后激活这个虚拟环境，然后使用pip install web3命令安装web3.py，该命令会自动下载安装依赖库并打印安装信息，如图

web3.py提供了数据过滤接口、服务提供商、以太坊命名服务、网络信息、账户信息、区块信息等几个主要的功能接口，详情可以访问web3.py的官网https：//web3py.readthedocs.io/en/stable/index.html进行查询。

（3）申请测试结点

安装了web3.py后需要申请一个用于连接Ropsten测试网络的测试结点。这里使用Infura，Infura是一个以太坊结点服务提供商，它提供公开的Ethereum主网和测试网络结点，开发者可以到Infura官网进行申请。在浏览器中打开https：//infura.io/看到Infura的页面，如图

![](https://storage.googleapis.com/papyrus_images/643dc2da7ec86b26aef3f99bf7ccdc3b350afb808053b8c7bee18f22b11aa041.png)

单击页面上的“GET STARTED FOR FREE”按钮开始免费申请。免费申请需要填写姓名、邮箱和密码等基本信息信息填写完毕后，单击“SIGN UP”按钮进行注册。注册后提示已发送一份确认邮件到已填写的邮箱中，如未收到可以单击“RE-SEND VERIFICATION EMAIL”按钮重新发送确认邮件，所示。

单击邮件中的确认连接后会自动登录进入注册账户中。顺利登录后会提示用户新增一个项目，项目名任意，这里项目名为“自学区块链”，单击“CREATE PROJECT”按钮创建项目，如图

图8-12 创建项目

创建完成后进入项目详情页面。详情页面中显示了用来连接以太坊网络的API KEY、API SECRET和可连接的结点地址ENDPOINT，以及这个结点上智能合约的白名单列表。这里选择Ropsten测试网络的结点，如图8-13所示。

3.使用web3.py连接网络

在上面得到Ropsten测试网络的连接结点后可以使用web3.py进行连接。先从web3.py导入Web3和HTTPProvider，然后连接项目中的Ropsten测试结点，连接后使用isConnected方法检查连接状态，返回True说明连接成功，如图8-14所示。

连接成功后就可以使用web3.py提供的getTransartion等方法查询Ropsten网络数据了。

![  项目目录](https://storage.googleapis.com/papyrus_images/18c97b285802ffc36165cccde6c7ca7b797cbd5cfa91db16fc32851eb0afbd7c.png)

项目目录

（3）创建应用

初始化项目之后，可以开始实现功能代码。先新建一个Flask应用并初始化Web3进行连接，在app.py中编

![](https://storage.googleapis.com/papyrus_images/c3412d6941b1a435532277763659f7d1cf6cdeb965c8ff23c290576301ce60b3.png)

完成后执行python app.py命令就可以启动这个应用。启动的应用默认在5000端口进行监听，处理请求并返回结果。

（4）实现基础模板

创建应用后开始编写页面。在Flask中默认使用的是Jinja2模板语言来实现模板功能（Jinja2有个强大的功能即模板继承功能。模板继承允许开发者创建一个基础的骨架模板，这个模板包含网站的通用元素，在子模板中可以通过继承这个基础模板拥有这些通用元素，不同的页面元素可以通过重载来实现，就像Python类的继承和重载一样简单），因此可以先编写一个基础模板，将页面公共的部分都放到这个基础模板中，其他页面继承这个模板就会拥有这些公共的部分，再加上页面需要的定制内容并用bootstrap来美化页面样式就可以快速实现一个页面。这样做的好处是可以避免编写重复的内容，提高开发效率，具体操作为：在当前目录的templates文件夹新建一个layout.html的文件，在这个文件中引入bootstrap相关的css和js，代码

![](https://storage.googleapis.com/papyrus_images/a133491b18572070530e2a3f6471443b63e11351241681676905b74530092049.png)

![](https://storage.googleapis.com/papyrus_images/a1aec95b8ffeb5da7d2ca0b487ce8ad8ab17d5b0a50ab7b899e6f0d2dd51d5e3.png)

其中类似“{% block ×××%}{% endblock %}”的内容是供子模板中重载的区域，子模板可以通过重载添加自定义的内容。下面开始实现第1个功能，第1个功能是查询并显示Ropsten测试网络中的最新区块

查询Ropsten测试网络中的最新区块信息，可以通过web3.py的函数getBlock来实现，这个函数返回的格式是一个Json字符串，前端HTML页面负责将这个Json字符串显示出来。在app.py中实现一个名为get\_last\_block的函数，在函数中调用getBlock（“latest”）函数，然后从返回的区块信息中提取主要内容传递给模板进行显示，代码如下

![](https://storage.googleapis.com/papyrus_images/939ced2f432b89bea8afe7764fa695a80ada5bacc360dc1d0dae111e0b42ab81.png)

![](https://storage.googleapis.com/papyrus_images/d53733369737739a6f242feb25cfd3754843a23bdf8caa714436d20d0524e38c.png)

以上代码从获取到的区块信息中提取主要区块信息，并将这些信息封装到一个字典中传递给模板block.html。block.html模板先是继承layout.html模板，然后使用jquery.json-browse的jquery插件进行显示。jquery.json-browse的作用是美化Json数据的显示，并且可以对Json数据进行展开和折叠处理，block.html代码如下

![](https://storage.googleapis.com/papyrus_images/c8878ad59aa9e48b88ce510a931a17056d47ad348b97600f74d9d33546bb220d.png)

以上查询最新区块的代码编写完成后启动应用可查看效果，打开浏览器访问http：//127.0.0.1：5000，就可以看到最新区块的信息，如图8-16所示，显示了最新区块的信息，包括矿工地址（miner）、哈希值（hash）等。

2.查询区块的交易数据

在一个区块中往往存储了很多个交易记录。在图8-16中的区块信息中有一个transactions字段，其中包含了一系列哈希值，每一个哈希值对应的就是一个交易记录。在这一节中实现的功能是使用web3.py中的getTransaction函数查询哈希值对应的交易信息并将交易信息显示在HTML中。在app.py中实现一个handle\_transaction函数，该函数接收GET和POST两种请求方式。GET请求返回一个包含输入框和按钮的HTML页面，POST会传递一个交易信息的哈希值，函数内调用web3.py的getTransaction函数查询对应的交易并将结果返回，代码如下

![](https://storage.googleapis.com/papyrus_images/eea2f0ca2a9955572f837e51fb5266e4f7131447d34a1dfc36de0e89a4186cb9.png)

![](https://storage.googleapis.com/papyrus_images/c12ea76e0ca314d0720e5195c9ee2461b29d654e4c9b30be3bd8d4d83900f6fa.png)

![](https://storage.googleapis.com/papyrus_images/fe41816d77a2a95b7d1c1f2845e25fe5721891defd863a1b705e9ba79dc82187.png)

更新app.py后，再新建一个transaction.html模板文件，该模板文件依旧从layout.html继承而来。模板中显示一个输入框和按钮，在输入框输入交易哈希值后，单击“搜索交易”按钮会将交易哈希值的请求数据发送到应用，从应用得到交易数据后再使用jquery.json-browse命令显示Json数据，代码如下

![](https://storage.googleapis.com/papyrus_images/ad22022a3a4274c3f0878e74fda53408cbc5cd09cc7d58f400e8bc4f1209861d.png)

![](https://storage.googleapis.com/papyrus_images/41c0628813f5e8ac662e2419dcde938700fd2a010edffb4eeda68401fc9afd2d.png)

完成后重启应用，查看页面效果，可以看到一个用来搜索交易的页面。在浏览器中输入http：//127.0.0.1：5000/transaction，打开该页面，然后在输入框输入一个交易id，单击“搜索交易”按钮即可看到交易详情，如图所示

![](https://storage.googleapis.com/papyrus_images/957cdc350f1e42c7ba8d233083417102fec404e0891f0c5f693a3ba4ab04cd14.png)

完成了区块和交易数据的查询功能，再来实现查询账户余额的功能。查询账户余额的实现逻辑和查询交易数据类似。在app.py中实现一个get\_balance的函数，接收GET和POST两种请求方式。GET请求返回一个包含输入框和按钮的HTML页面，POST请求接收账户地址信息并通过web3.py的getBalance函数获取账户余额，代码可以根据“2.查询区块的交易数据”部分稍作修改即可。完成后在浏览器中打开http：//127.0.0.1：5000/balance，输入账户地址即可查询对应账户的余额，如图

![](https://storage.googleapis.com/papyrus_images/1f3ba14a15378702833dcf0a56f807be43c132e7f39c3c0445c5ba46721fce11.png)

区块信息分析
------

简单分析一下Ropsten测试网络中的区块信息。先写一个Python脚本下载Ropsten测试网络中的前10000个区块，并通过pickle模块将这些数据保存下来。pickle是Python用来将Python对象保存为文件的一个模块，使用pickle可以方便地存储和读取Python对象。

（1）下载区块数据

新建一个eth\_helper.py文件，在这个文件中新建一个download\_blocks函数用来循环下载区块数据，下载完成后，使用pickle将这些区块数据保存到一个名为block.pkl的文件中，代码如下

![](https://storage.googleapis.com/papyrus_images/914502acabc45cb6d8471a5c2c24d4caad9e4dd26e72f2a65d8390cbb2266ab5.png)

运行python eth\_helper.py命令执行脚本。脚本下载区块数据需要一段时间，下载完成后会在本地自动生成一个block.pkl的文件，里面包含了10000个区块数据，如图

![](https://storage.googleapis.com/papyrus_images/5fe5dfefc1612fa14d1114c23112e0d23cd8e552dcc240e52c9beda089b6e916.png)

2）加载区块数据

在app.py中新建一个名为visualization函数，用来加载已经下载好的区块数据并将其中的区块难度提取出来，放到一个列表中传递给HTML页面（visualization.html）以供展示，代码如下

![](https://storage.googleapis.com/papyrus_images/5ae758b2dd042db757eed3fbb117535210ca3def5927190e7de6cde46967c41b.png)

这里只是将区块难度提取出来做分析处理，有兴趣的读者也可以提取其他字段进行分析。为了方便通过HTML页面进行展示，这里将区块序号和区块难度分别放到一个独立的列表中。

（3）对数据进行可视化

最后一步是对数据进行可视化展示。这里使用ECharts进行可视化操作。ECharts是一款由百度前端技术部开发的、基于JavaScript的数据可视化图表库，可以提供直观、生动、可交互、可个性化定制的数据可视化图表。使用ECharts对数据进行可视化的方法也很简单，只需要在HTML页面中包含ECharts的js库文件，然后新建一个一定大小的div元素，再编写一段js代码加载数据，即可进行数据可视化显示。

新建一个visualization.html文件，这里选择折线图的形式进行区块难度数据的可视化。编写代码如下

![](https://storage.googleapis.com/papyrus_images/5b53580a1109b0cffb69303ac284f2827df16b6873bde2a09a9a9630e3a86702.png)

![](https://storage.googleapis.com/papyrus_images/50c636ef4343009c6d26fa4fe9802a35d4a77c46defe0e002911e2df12938dd7.png)

![](https://storage.googleapis.com/papyrus_images/1e7bbc01c9710eaaebda5d269364acff6560227bedb4d60f9682bf44af32624b.png)

代码编写完成后重启Flask应用，访问http：//127.0.0.1：5000/visualization就可以看到可视化效果，如图

![](https://storage.googleapis.com/papyrus_images/dae110bef6da24ab4ec286504f53886902752b846a7b48ebdf599c234e32745a.png)

从图中可以看到，在Ropsten测试网络中区块难度的值是直线上升的，这表明随着区块链的不断延长，生成区块的难度越来越大。

以上就是一个简单的以太坊查询分析系统，有兴趣的读者还可以进一步分析以太坊的其他数据，如区块的生成速度、区块每日生成的个数以及待确认的区块数目等。若要分析实际环境中的以太坊，只需要把上面的Ropsten测试结点地址（http：//ropsten.infura：io/v3/×××）换成正式结点地址就可以了。

ERC20可以简单理解成以太坊上的一个代币协议，所有基于以太坊开发的代币合约都遵守这个协议。遵守这个协议的代币叫作ERC20代币。本案例将开发一个名为Mini Token的ERC20代币。

密数字货币的种类纷繁复杂，比特币、瑞波币、小蚁币等众多老牌币种，都有独自的链，在自己的链上运行着自己的加密数字货币。除了这些之外，还有一种平台型代币，它们是依托以太坊而创建的，没有自己的链，而是运行在以太坊之上。当前市面上十有八九的数字货币都属于平台型代币。这些代币都遵守ERC20代币协议，都是标准化的代币，这些标准化的代币可以被各种以太坊钱包支持。被以太坊钱包支持的代币可用于各种项目的开发，也可以提交到各个交易所进行交易。

之所以叫ERC20代币，是因为ERC20是在2015年11月以太坊社区提出的代号为20的一项标准，符合这个标准的都是ERC20代币。在ERC20标准出现之前，代币的标准不统一，发行代币是一件非常麻烦的事，对开发者来说既需要单独开发智能合约，还并不能做到多种钱包的兼容。在ERC20标准出现后，发行基于ERC20标准的代币变得很简单，开发一个ERC20代币基本不超过10分钟，50行代码就能实现。

ERC20是各个代币的标准接口，开发者需要将这些标准接口集成到他们的智能合约中，以便能够执行以下操作：

●获得代币总供应量。

●获得账户余额。

●转让代币。

●批准花费代币。

ERC20让以太坊区块链上的其他智能合约和去中心化应用之间实现了无缝交互。ERC20标准的接口文件如下

![](https://storage.googleapis.com/papyrus_images/be582fcdc8c4fab731114a99295da2915f2ef0a296f504660f256cf868393791.png)

其中的含义如下。

●name是需要指定名字，比如可以叫作MyToken。

●symbol是代币的符号，类似于常见的BTC、ETH等。

●decimal是代币最少交易的单位，它表示小数点的位数，如果设置为1，那么最少可以交易0.1个代币。

●totalSupply是指总发行量。

●balanceOf返回某个地址（账户）的账户余额

●transfer实现转账一定数量（\_value）的代币到目标地址（\_to），它会提供一个返回值来说明是否转账成功，并且会触发Transfer事件。

●transferFrom从一个地址（\_from）转账一定数量（\_value）的代币到目标地址（\_to），也会提供一个返回值来说明是否转账成功，同样也会触发Transfer事件。

●approve授权第三方（\_spender）从发送者账户转移一定量（最多为\_value数量）的代币。第三方通常是某个智能合约，可以通过transferFrom（）函数来执行具体的转移操作。

●allowance返回\_spender仍然被允许从\_owner提取的金额。

●Transfer和Approval事件是为了记录日志用的。前者是在代币被转移时触发，后者是在调用approve方法时触发。

ERC20代币不是一个DApp，它是智能合约的重要应用之一，ERC20代币也使用Solidity语言进行开发，开发环境一般选择Remix（Remix是一个在线的、用来开发以太坊智能合约的IDE，地址是http：//remix.ethereum.org）。

这里要实现一个名为“Mini Token”的代币，符号为“MT”，总发行量为1000枚。实现的方法是修改ERC20标准接口中相应函数的内容，如将name改为“Mini Token”，symbol改为“MT”等，完整代码如下

![](https://storage.googleapis.com/papyrus_images/32d48bd3c8ec61d1779d1f6ac9f305dd9c29f3c527e0804be54b0d1c6d8c6578.png)

![](https://storage.googleapis.com/papyrus_images/16ed634cfd94b810b8c5c965d3b4162b543fa8f4bb94ed2179b49fb8af97aab9.png)

![](https://storage.googleapis.com/papyrus_images/16ed634cfd94b810b8c5c965d3b4162b543fa8f4bb94ed2179b49fb8af97aab9.png)

![](https://storage.googleapis.com/papyrus_images/3c0f293875d2b483ac5bc35af148c30ac38adf1e02cd38c428cad9649e19ef70.png)

![](https://storage.googleapis.com/papyrus_images/3c0f293875d2b483ac5bc35af148c30ac38adf1e02cd38c428cad9649e19ef70.png)

将上述代码复制粘贴到Remix的编辑器中，执行编译，并部署到本地测试环境中，这样Mini Token就发布成功了。从合约的详情中可以看到Mini Token的名称、符号和总发行量等信息，如图

![](https://storage.googleapis.com/papyrus_images/c72687bcf4c7583182e1bbba803739ab4616ce9e0672b97674c056111ae231a7.png)

单击合约右侧的复制按钮，将Mini Token的地址复制到剪切板。然后打开MetaMask的账户选项，选择“ADD TOKEN”，如图8-22所示。

在Add Tokens对话框中选择“Custom Token”，在“Token Address”文本框中填入刚才复制的Mini Token的地址，之后下面的符号栏和精度栏会自动补充，然后单击“Next”按钮继续，如图

最后，再单击“ADD TOKENS”按钮，将Mini Token添加到账号中，如图8-24所示。

完成以后，在账户界面就可以看到新创建的代币，并可以将这些代币进行交易或转账

2017年底，以太坊上发布了一款火爆的小游戏加密猫（CryptoKitties），它是加密猫的养成与繁殖游戏，利用以太币作为该游戏的唯一交易货币，两只加密猫交配而生出的子孙会从他们父母基因组中通过遗传算法获取新的基因，这些基因决定了外观、个性与特征等。每只猫都是独一无二的，100%归所有者拥有；加密猫不能被复制、带走或毁坏，但可以购买或出售它。加密猫可以作为一个收藏品并在区块链中被安全地记录。加密猫的作者Axion Zen后来还定义了一种代币标准ERC721，开发者可以基于这个标准发布数字资产。在ERC20中所有符合ERC20的代币都是相同的，任何两个ERC20代币之间没有区别；而在ERC721中每种数字资产都有它唯一的标识，没有两种符合ERC721标准的数字资产是完全相同的，这与ERC20有着明显的不同。

ERC721官方简要解释是“Non-Fungible Tokens”，翻译为不可互换的代币，英文简写为“NFT”，简单理解为每个代币都是独一无二的。以加密猫来解释的话，每一只加密猫都是独立的代币，而且每只加密猫都有它独一无二的特征，无法相互替换。而ERC721就是定义了这样一个标准来实现这一类的加密资产。

本节的实例就是实现一个类似于加密猫的数字资产——加密猪。要开发这类数字资产，需要实现符合ERC721标准的智能合约，然后基于这个智能合约实现一套用户界面来展示开发的数字资产。

随着类似加密猫之类数字资产的增多，有人就开始创建一个专门用来进行此类加密资产交易的平台，其中OpenSea是世界上最大的加密资产交易平台。开发者不再需要自己从头开发，只需要在OpenSea平台上按照流程进行操作就可以快速开发出一个ERC721数字资产。本节接下来首先介绍OpenSea，然后讲解如何在OpenSea上开发和交易数字资产。通过本案例可以学到如何开发一个符合ERC721标准的数字资产，以及如何对这类资产进行交易。

penSea是一个基于区块链的加密资产交易平台，为广大用户提供加密资产的购买和销售等服务，OpenSea首页如图

OpenSea提供了一份开发文档，让开发者在几分钟内就可以开发完成属于自己的店铺，可以访问https：//docs.opensea.io/docs进行查阅，OpenSea提供的示例是交易各种海洋生物加密资产，所示。

这里参照这个海洋生物加密资产的开发过程来开发自己的一个加密资产——加密猪。加密猪遵循以太坊ERC721标准，并加入权限控制的功能。开发步骤依次为创建和实现加密猪的智能合约、加密猪的展示页面和用户界面，以及加密猪交易功能。

本实例基于Truffle框架进行开发，开发过程中需要使用NodeJS包管理器npm安装依赖库，开发之前应确保系统中的npm工具可用，然后选择一个常用的文本编辑器（如VScode、Sublime）等就可以开发这个加密猪了。

这里智能合约的开发基于OpenZeppelin库。OpenZeppelin是用Soildity语言实现的一个开源库，里面包含了已知智能合约的最佳实践。OpenZeppelin提供了开发智能合约所需的各种重要功能，使我们可以基于它在更少的时间内创建更安全的智能合约。下面开始正式开发智能合约。

（1）初始化智能合约

这里先在本地任一目录下新建一个LittlePig的文件夹，创建完成后进入文件并使用truffle init命令初始化一个Truffle项目，如图

![](https://storage.googleapis.com/papyrus_images/56afa3cc69d96d4171a4d9a2d4d4fdc5b9c13774b2e074e66658e485066c5117.png)

初始化项目

初始化后再安装OpenZeppelin库，安装命令如下：

npm install openzeppelin-solidity

安装完成后开始实现智能合约的功能。

（2）实现LittlePig智能合约

LittlePig智能合约的功能实现比较简单，只需要基于openzeppelin-solidity库进行二次开发。在当前目录的contracts文件夹下新建一个LittlePig.sol的文件。在文件中编写一个LittlePig的类，这个类继承于ERC721Token和Ownable这两个基础类。其中ERC721Token是ERC721标准的基础类，Ownable提供了权限控制的功能。继承后在类的主体部分还需要实现tokenURI、baseTokenURI、isApprovedForll等函数。值得注意的是有两点，一是tokenURI函数，这个函数返回一个URI地址，这里是https：//little-pig-api.herokuapp.com/api/pig/，请求这个URI会返回每个ERC721资产的属性，如名称、描述和图片等，这些属性将被展示在OpenSea平台上；二是isApprovedForAll函数，它用来控制获取OpenSea数据的白名单列表，具体代码如下

![](https://storage.googleapis.com/papyrus_images/9ce99df2c1b2aebd9cd8e0307f61a301389e5aab6293dd34fac517797cad12f0.png)

实现智能合约代码后就可以开始发布智能合约了。

（3）发布智能合约

这里使用之前注册的Infura账户（参数8.1.2节对接以太坊接口中申请测试结点部分）发布到Ropsten测试网络上。发布的方法也比较简单，使用HDWalletProvider连接到Ropsten测试网络并进行发布操作。其中连接过程中需要配置钱包的助记词（用来推算钱包信息的十几个英文单词，讲过）和Infura的接口地址，在truffle.js文件中配置如下

![](https://storage.googleapis.com/papyrus_images/6389375828165f182585f0356b12f4a730a61ba7c9e865bfcef57943a2348408.png)

![](https://storage.googleapis.com/papyrus_images/270a47be7450c816a24abc3323f7795fa90adc63bbea81e0497ade5fe5e5f766.png)

配置完成后，使用truffle deploy--network ropsten命令将智能合约部署到Ropsten测试网络中，部署成功后可以看到交易哈希值（transaction hash）和合约地址（contract address）等信息

![](https://storage.googleapis.com/papyrus_images/1e1a3a9bd2f6eb8e4a04de3bfda62db6ebe7adec1777c2b825ce6901564b49c9.png)

4）生成加密资产

成功发布智能合约后，就可以调用智能合约生成属于自己的加密资产。生成的方法是使用HDWalletProvider连接到Ropsten测试网络，然后加载智能合约并调用mintTo函数生成加密数字资产。这里新建一个mint.js文件，在文件中编写代码如下

![](https://storage.googleapis.com/papyrus_images/8c8f0dff9a4a0002f81229335d6f5b988f90fb659d8af9c660090633627f4860.png)

![](https://storage.googleapis.com/papyrus_images/c909f1060603fb2ac4a82c7ddb6834106e0f01b7b919f17363e455b08dcd3684.png)

完成mint.js后通过在终端中执行node mint.js就可以生成加密资产，上述代码中设置生成12个加密猪。可以在终端上看到生成的12个哈希值，也就是12个加密猪如图

![](https://storage.googleapis.com/papyrus_images/f1237a67c40710b0a0894fcf549a6b9e7242167d5e86636e95bd5193f5a375e5.png)

生成加密猪的哈希值

以上生成的这样的加密猪就是属于自己的加密资产，可以进行交易和转让。为了让这些加密猪看起来更加直观和吸引人，可以给每个加密猪添加一些属性数据，这样在Opensea上每个加密猪都会展示出不同的形象。

前面的智能合约中实现了一个tokenURI（）方法，这个方法针对每个Token返回一个唯一的URI，请求这个URI就可以返回这个Token对应的属性数据。比如，对于Id为1的Token返回的URI是https：//little-pig-api.herokuapp.com/api/creature/1。请求这个URI会返回如下的Json数据：

![](https://storage.googleapis.com/papyrus_images/8903abfb820c19adc0cd11476413b96a869266aecdb818c7a0f99b27885cd143.png)

其中description字段是加密猪的描述，external\_url字段是加密猪的外部链接，image是加密猪的图片地址，name是加密猪的名称，attributes是加密猪的自定义属性列表。

添加好属性数据后，即可在Opensea平台上查看该加密资产的信息。查看的链接为https：//ropsten.opensea.io/assets/合约地址/tokenId，比如查看加密猪token Id为1的链接地址为https：//ropsten.opensea.io/assets/0x×××/1，效果如图

![](https://storage.googleapis.com/papyrus_images/e7119914aba8a1560e390466411c1ccef2254ebabeac33c7e02072f545266450.png)

交易加密猪有两种方式，一是定价销售（Fixed Price），二是在一定价格范围内进行拍卖（Auction）

以上就是加密猪的交易功能
============

完

---

*Originally published on [leaf](https://paragraph.com/@leaf-6/jt4Fs5vFnZIw5QiB5scT)*
