区块链DApp从零开始学 (二) | 超详细 DApp创建 | 发行代币token | 宠物领养
初学记录 · 欢迎交流
区块链DApp从零开始学 (一) | DApp抓包
区块链DApp从零开始学 (二) | 超详细 DApp创建 | 发行代币token |宠物领养区块链知识 (一) | 实例化合约Contract
区块链报错1 | npm run dev 无法解析json格式 | npm ERR JSON.parse Failed to parse json
区块链报错2 | 区块链npm run dev失败lite-server
区块链报错3 | truffle unbox 报错 | downloading失败 | unbox failed
区块链报错4 | 区块链玄学 | truffle unbox下载downloading步骤失败
区块链报错5 | Contract has not been deployed to detect network (network/artifact mismatch)
区块链报错6 | Failed to load resource: the server responded with a status of 404 (Not Found)
目录
- 先验知识
- 环境配置
- truffle
- web3js
- Ganache
- Atom
- 案例1 | 代币token发行
- tutorialtoken
- jQuery
- 项目架构
- openzeppelin
- 案例2 | 宠物领养
- 公网部署
先验知识
官网的中文手册 truffle / solidity / web3js 及 官网box的代码 是最好的学习方式
关于solidity:
它是一门编程语言,可实现分布式数据库/账本,
但是不能直接与前端交互,故需要web3做桥梁关于truffle:
它对solidity实现了封装,可以实现环境开发、部署、测试等
它是一个web框架,使用JavaScript编写关于web3:
它提供了智能合约实例化,和合约调用的工程(RPC 远程过程调用);
它有js版、python版等各种语言编写版本,多用webjs一定要建立起truffle、solidity、web3js的宏观概念,对项目组成部分有大致了解
环境配置
truffle
① 安装 nodejs
(js运行时环境)并配置PATH环境变量,nodejs默认安装npm(npm是js的包管理工具,类似python中pip)
② 安装cnpm
(国内镜像,比npm命令快;也默认装到nodejs下):
npm install cnpm -g --registry=https://registry.npmmirror.com
③ 全局 (-g)安装 truffle
框架(truffle默认安装webjs):
npm install -g truffle
④ 执行truffle命令时,要以管理员身份打开控制台(不易报错)
truffle命令:
truffle init
创建空工程
truffle compile
编译sol文件生成abi文件(调用contract的使用手册)
truffle develop
搭建本地以太坊测试网络(提供10个账户和密钥)
truffle deploy
/ truffle migrate
部署 (–reset从头迁移部署)
一般命令的执行顺序为:
truffle develop -> compile -> deploy / migrate [–reset]
ps:如果不compile,部署时会自动编译
关于部署:
① 部署前需要改下 truffle-config
truffle-config中一般改这俩部分即可:
代码里有个坑,开发者环境是’develop’,而不是’development’,要改成develop,
否则最直观的一个显示就是develop端口和项目端口不同
② 必须有网络才能部署,即在develop开发者环境下,而develop提供的网络可以直接命令行显示,也可以连上Ganache可视化,这需要在项目config文件中改端口为Ganache的端口7545即可
③ 迁移脚本(migrations/1_initial_migration.js等js文件)暂存部署任务,帮助将合约部署到以太坊网络
④ truffle要求初始化的迁移脚本 migrations/1_initial_migration.js不可删除,且按文件名打头数字顺序部署,如先部署1_xxx.js,再部署2_xxx.js,再部署3_xxx.js
web3js
安装truffle时会自动安装web3
web3js常用命令 | 详细见 中文手册
web3.eth.getAccounts()
返回账户列表
web3.eth.getBalance()
返回帐号曰
web3.eth.defaultAccount()
设置默认账户
web3.eth.sendTransaction
({from:’ ‘},{to:’ ‘},{value:’ ’ }) 向网络提交交易
web3.utils.toWei
(‘1’,‘ether’) 位和以太币相互转换(1 ether = 2……18 wei)
web3.utils.fromWei
(‘200000000000000000’,‘ether’)
ps:注意是函数还是属性,是否需要带括号
官网的中英文手册是最好的学习资料,建议查阅
Ganache
模拟区块链除了使用develop命令,还可以使用Ganache(更直观地看账号与交易)
根据操作系统下载安装包,如我下windows的如下,建议下载exe版本,下载appex版本操作起来很麻烦
ps:想连Ganache时,先打开Ganache,再进入develop开发者模式,否则Ganache会报错7545端口已被占用,要求修改端口
Atom
官方推荐的编辑器是Atom,下载插件(File -> settings -> install)language-ethereum和autocomplete-solidity,作用分别是高亮和补全
Atom中内置控制台、debug等好像需要下载插件,我没下载成功,就直接使用cmd控制台了,不知道其内置的能不能用
案例1 | 代币token发行
tutorialtoken
下载官方写好的代币框架
truffle unbox tutorialtoken
进入开发者模式
truffle develop
会出现这个问题,是因为官方有个bug,需要把config.js改成truffle-config.js
顺便把package.json (配置文件)中 “main”: "truffle-config.js"也改掉
可以不compile而直接migrate
compile
migrate
提供一个本地的服务器端口(默认3000)(浏览器页面)
该语句需要在develop开发者模式外
npm run dev
port可以在bs-config.js中更改:
可以在控制台(管理员身份)查看所使用端口占用情况:
netstat -ab
jQuery
index.html中引入的jQuery是google站点的,自己本地下一个
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
jquery1和2有较大区别,遂下1就OK
下载到 src\js 目录下(所有js文件都抛到这)
则语句可修改为
<script src="js/jquery.min.js"></script>
项目架构
项目架构(部分):
├─build
│ └─contracts
├─contracts
├─migrations
├─node_modules:依赖包
├─src
│ ├─css :组件美化(不必动)
│ ├─fonts :字体、图标(不必动)
│ ├─index.html:用户展示页面(编辑)
│ └─js
│ ├─app.js:后续编写业务逻辑的js文件(编辑)
│ ├─truffle-contract.js:truffle框架(不用动)
│ └─web3.min.js:web3(不用动)
├─test
├─truffle-config.js
├─package.json:重要配置文件
├─bs-config.json:重要配置文件(server有关)
分析app.js文件,发现其缺少部分待补充的定义如下:
① 缺少一个TutorialToken.sol文件
② 缺少一个transfer()函数
③ 缺少一个balanceOf()函数
这些缺失的定义通过下载TutorialToken框架,继承其中的ERC20得以补充
openzeppelin
使用cnpm命令为项目局部安装
cnpm install openzeppelin-solidity@2.5.1
ps:这里安装必须制定版本,否则现在默认安装版本是3,3版本框架使用的solidity版本是0.8.0,常用一般0.5.0写,会不兼容,编译报错
在Contract目录下创建TutorialToken.sol文件,文件内容如下:
pragma solidity >=0.4.22 <0.9.0;import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol"; //发行代币的协议contract TutorialToken is ERC20{ //ERC20中有transfer函数和getBalanceof函数的定义,继承ERC20后不需重写string public name = "TutorialToken";string public symbol = "TT";//代币符号uint8 public decimals = 2;//代币精度//发行代币的总量uint public INITIAL_SUPPLY = 12000; //构造函数constructor() public{_mint(msg.sender,INITIAL_SUPPLY);}
}
在migration下创建2_xxx.js文件,内容如下:
var Migrations = artifacts.require("TutorialToken");module.exports = function(deployer) {deployer.deploy(TutorialToken);
};
truffle-config中端口号改掉(以便接下来连接Ganache):
develop: {host: "127.0.0.1", // Localhost (default: none)port: 7545, // Standard Ethereum port (default: none)network_id: "*", // Any network (default: none)},
执行命令:
truffle develop
migrate --reset
npm run dev
浏览器显示如下:
发现Balance余额没显示,检查控制台,发现其报错"web3 is not defined"
这是个官方的bug,错误在app.js中,如果从else语句进入,没有对web3的定义,则底下就没发调用,加上红框中这一句:
OK,balance正常显示了
ps:还有一种balance不显示的原因是开了metamask插件,关上就好了
界面显示有问题,说到底就是合约交互的问题,有意识地往这方面思考就ok了
在Ganache中找个账户转账后:
对于页面交互的显示,要擅用控制台检查功能,
可以在js文件中添加一些console.log()等语句辅助检查
案例2 | 宠物领养
truffle unbox pet-shop
ps:如果unbox命令失败,可使用git下载
参照token案例,改下jquery、端口等
truffle develop
compile
deploy
npm run dev
但是框架只能显示页面,不能实现领养功能,也不能与网页交互,因为box没写业务逻辑,需要自行填充
contracts下建立Adoptation.sol:
pragma solidity >=0.4.22 <0.8.0;contract Adoption{address[16] public adopters;function adopt(uint petId) public returns (uint){require(petId<=15 && petId>=0);adopters[petId] = msg.sender;//记录领养者地址return petId;}/*此处该数组若未声明为memory变量会报错因为memory表示值变量,即只是复制副本;而默认为storage是引用变量,所有的引用都实际只想一处如果这里是storage变量,则外部可以修改该变量,这显然不符合区块链的安全性原则view只读 pure不读写*/function getAdopters() public view returns (address[16] memory){return adopters;}
}
有返回值的函数一定要定义为view / pure 格式,这里涉及到区块链中关于读和写的操作,补充一下:
因为以太坊修改数据的手续费很高,所以数据分为严格的读和写。读取数据为调用(call),写入数据为交易(transaction),二者区别很大。
交易会改变网络状态,消耗Gas费用,需要较长的响应时间处理。所以在执行合约的函数时,无法及时获得该函数的返回值,仅仅可以获得一个交易ID。
call不改变网络状态,免费,立刻执行,有返回值。
这里如果不加pure在app.js中调用该函数时会出现错误
migration下写迁移文件2_adoption.js:
var Adoption = artifacts.require("Adoption");module.exports = function(deployer){deployer.deploy(Adoption);
};
补全app.js中初始web3部分内容:
initWeb3: async function() {if(typeof web3 ==! undefined){//如果有MetaMask(连接公有链/私有链/主网),则已有web3console.log('if');App.web3Provider = new web3.currentProvider;}else{console.log('else');App.web3Provider = new Web3.providers.HttpProvider('http://127.0.0.1:7545');web3 = new Web3(App.web3Provider);}return App.initContract();},
补全app.js中初始化合约的内容:
initContract: function() {/*合约初始化逻辑:获取json文件 -> 解析json数据 -> 初始化web3 -> 初始化合约界面*/$.getJSON('Adoption.json', function(data) {var AdoptionArtifact = data;App.contracts.Adoption = TruffleContract(AdoptionArtifact);//解析json数据App.contracts.Adoption.setProvider(App.web3Provider);//初始化,其他人浏览页面时应显示有哪些已经被领养了,不能再被领养了return App.markAdopted();});return App.bindEvents();},
补全app.js中宠物领养状态显示功能(相当于代币项目中浏览页面balance功能):
markAdopted: function(adopters, account) {console.log("markAdopted");var adoptionInstance;App.contracts.Adoption.deployed().then(function(Instance){adoptionInstance = Instance;return adoptionInstance.getAdopters();}).then(function(adopters){console.log(adopters.length);for(i=0;i<adopters.length;i++){//如果当前宠物领养地址不为 空(0x0)if(adopters[i] != '0x0000000000000000000000000000000000000000') //0x (40个0){//当前宠物已被领养,通过jQuery设置按钮状态为不可见$('.panel-pet').eq(i).find('button').text('adopted').attr('disabled',true);//eq(i) 获取第i个div}}}).catch(function(err){console.log(err.message);});},
补全app.js中宠物领养功能:
handleAdopt: function(event) {// 获取当前单击按钮对应宠物的idvar petId = parseInt($(event.target).data('id'));console.info('宠物的ID为:' + petId);// 此变量用来存储实例化的合约var adoptionInstance;web3.eth.getAccounts(function(error, accounts) {// 异步调用:if (error) {console.log(error);}// 拿到测试的第一个账户var account = accounts[0];console.info('account --->' + account);web3.eth.defaultAccount = account;// 由于当前采用的是truffle 4.x + web3 0.x的版本,因此选择合适API查看App.contracts.Adoption.deployed().then(function(instance) {// 获取已经实例化的智能合约对象adoptionInstance = instance;return adoptionInstance.adopt(petId);}).then(function(result) {console.info('result %o', result);// 调用标记宠物状态函数return App.markAdopted();}).catch(function(err) {console.log(err.message);});});}};
老一套
truffle develop
migrate
npm run dev
公网部署
不同测试网络大致相同,无非是共识机制和挖矿算法的不同
测试网络为测试使用,其测试币没有太大价值,挖矿也更容易
首先get一些测试币:
如果从水管获取测试币失败,即显示下面红色的字,可以从 这个网址 获取
记得先
当将自己的dapp连到测试网络时,面多众多有自己规则的测试网络,如果都遵循它们的规则来写会很麻烦,所以有了一个中间平台——infura的诞生,它可以使得dapp快速接入以太坊平台。
infura就像我们和银行之间要经过支付宝一样,每个银行的页面、按钮位置啥都不同,但是我们只要熟悉支付宝,就可以通过支付宝与各个银行进行交易。infura在公网和私有链之间充当的就是支付宝的作用。
infura免费,且还可以方便地接入IPFS。
IPFS:分布式存储系统,适合存储多媒体等
进入官网 后无脑注册一下,创建一个项目:
获得ID:
测试下infura能用不:
truffle develop
web3.setProvider('https://ropsten.infura.io/v3/yourID')
web3.currentProvider
web3.eth.getBalance('acountAdress')
修改下配置文件truffle-config.js:
const HDWalletProvider = require('@truffle/hdwallet-provider'); //取消注释
const memonic = "你的记词助";//取消注释
ropsten: {provider: () => new HDWalletProvider(memonic, https://ropsten.infura.io/v3/你的infrualID),network_id: 3, // Ropsten's idgas: 5500000, // Ropsten has a lower block limit than mainnetconfirmations: 2, // # of confs to wait between deployments. (default: 0)timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)skipDryRun: true // Skip dry run before migrations? (default: false for public nets )},
node-gyp:
node中需要调用其它语言编写的一些程序,甚至windows的动态链接库dll
如果下载的是编译后的程序,则移植性不好,如在linux下编译的程序在windows下就用不了了,
所以下载原码,再用node中自带的node-gyp编译一下,生成c++模块,嵌入程序中
一般新版nodejs里都自带了,如果没有自己下一下:
install -g node-gyp
在项目路径下安装:
cnpm install @truffle/hdwallet-provider
truffle develop
deploy --reset --network ropsten
如果部署一直timeout,这里面有非常多解决方法
对我有效的是:
将 https://ropsten.infura.io/v3/
改成 wss://ropsten.infura.io/ws/v3/
npm run dev
收官
区块链DApp从零开始学 (二) | 超详细 DApp创建 | 发行代币token | 宠物领养相关推荐
- 听TED唐.泰普史考特讲区块链(从零开始学区块链 199)
今天看到这个带字幕的TED视频还是有点小激动的,立刻找到最近的带座位的地方写了这篇文章 这个视频真的很难得,虽然短,但里面说清楚了大量关于区块了的本质,也解决了我的很多困扰,远远超过这几天炒的很热的什 ...
- 【区块链 | Solidity】以太坊Solidity如何实现海量空投代币?
以太坊Solidity如何实现海量空投代币? 1. 摘要 通证token项目启动时,短期内繁荣生态,要舍得给粉丝们打币,把利益分出去.本文聚焦在技术层面,实现如何快速完成TOKEN海量空投,既要节约时 ...
- eos区块链 java客户端_在EOS区块链上使用EOSJS和scatter开发dApp
由于我一直在深入研究EOS dApp的开发,我看了不少好文章.在这里,我汇总了下做一些研究后得到的所有知识.在本文中,我将解释如何使用EOSJS和scatter.我假设你对智能合约以及如何在EOS区块 ...
- 区块链需要学习哪些东西_区块链入门需要学哪些知识?
区块链入门需要学哪些知识? 区块链技术近年来发展迅速,全球范围内都掀起了区块链的热潮. 那么区块链入门需要学哪些知识? 首先学习区块链需要知道区块链与编程语言之间的关系 1.区块链是一种编程思想,使用 ...
- 【链块技术10期】区块链基础语言(二)——GO语言开发环境搭建
原文链接:区块链基础语言(二)--Go语言开发环境搭建 一.操作系统位数的查询方法 在安装前首先要了解个人的电脑系统位数是32位还是64位. 1.1Windows系统查询方法 右击"计算 ...
- 看完就能出去神侃,来自研发第一线的“区块链”扫盲文(二)
(图片出自网络,版权归原作者所有) 原文摘自公众号,<区什么块什么链啊>之<看完就能出去神侃,来自研发第一线的"区块链"扫盲文(二)> 共识机制,是不是听上 ...
- 谈谈区块链入门技能(二):以太坊区块链浏览器如何使用?
上一期我们介绍了比特币浏览器如何使用,本期我们来谈一谈什么是以太坊以及以太坊浏览器如何使用. 什么是以太坊? 以太坊是一个合作运行的.全球性的.透明的数据库.通过共同努力,来自世界各地的参与者维护了以 ...
- BlockChain:2020年7月10日世界人工智能大会WAIC《链智未来 赋能产业区块链主题论坛》(二)
BlockChain:2020年7月10日世界人工智能大会WAIC<链智未来 赋能产业区块链主题论坛>(二) 导读: 区块链和人工智能融合的影响力:人工智能喜欢干净的大数据,区块链系统生成 ...
- 区块链攻击方式总结二
目录 一.总述 二.第一个维度:双花攻击 1.51%算力攻击 (1)贿赂攻击 (2)币龄累计攻击 (3)通用挖矿攻击 2.芬尼攻击 3.种族攻击 4.分割攻击 5.重放攻击 (1)一条链上的重放攻击 ...
最新文章
- 基础 | 深度学习与神经网络-介绍
- Java5的 线程并发库
- Hinton's Dark Knowledge
- ie 不执行回调函时_「Excel VBA操作IE篇」10分钟内设置完成,3句代码打开IE浏览器
- VTK:vtkArrayToTable用法实战
- Java Observer Pattern(观察者模式)
- [召集令]-Dijkstra的单源最短路径算法
- 1秒后跳转页面(延时setTimeout)
- Springboot+vue项目疫情社区防控系统
- arcgis出比例尺大小相同的图
- MSTAR数据集处理
- 关于神经网络中的shape问题
- ibm tivoli_集成Tivoli Federated Identity Manager和Tivoli Identity Manager
- 程序员如何写好技术简历 —— 实例、模板及工具
- 计算机毕业设计(附源码)python中小型企业工作日志管理系统APP
- 【冰糖R语言】Pearson、Spearman相关性及其显著性 cor() rcorr()
- 《网络安全法》内容以及解读
- HTML5边框的设置(border)
- CSS3 基本属性 浅析(含选择器、背景阴影、3D转换、动画等)
- 帝国CMS仿精美的茶杯狐电影网站源码+手机电脑自适应+电影电视剧动漫演员剧情综艺
热门文章
- 【设计模式】模板模式——jdbc案例
- ImageMagick将多张图片拼接成一张图片_只有一张图片,也能做出一整套PPT!
- Miktex2.9使用Wondows系统字体相关设置
- 给你的员工一个可期许的未来(by leo)
- Linux内核版本和发行版本
- VS2017 函数模板和类模板的声明、定义和使用
- java 如何防止恶意注册表,如何防止恶意网页篡改注册表
- 电脑软件测试英雄联盟,lol电脑配置检测,如何测试自己的网络玩lol的具体情况?...
- 【Banana PI Leaf S3开发板试用体验】MicroPython环境搭建
- PCIe的内存地址空间、I/O地址空间和配置地址空间