内容大纲:

本项目是在以太坊上开的一个宠物领养的DAPP,借助了truffle框架和ganache进行合约部署。同时实现web端与区块链的交互。

1.设置开发环境
2.使用 Truffle Box 创建一个 Truffle 项目
3.编写智能合约
4.编译和部署智能合约
5.测试智能合约
6.创建用户界面以与智能合约交互
7.在浏览器中与 dapp 交互

开发环境:

  1. Node.js v8+ LTS 和 npm(Node 自带)
  2. git
  3. ganache
  4. go开发环境
  5. chrome上的metamask钱包
  6. VS code

一、使用truffle box创建项目

1.安装truffle
npm install -g truffle
2.创建项目部署文件夹
mkdir pet-shop
cd pet-shop
3.下载pet-shop项目
truffle unbox pet-shop

文件的目录结构

二、编写并部署智能合约

1. 编写智能合约

在contracts目录中,创建一个名称为Adoption.sol的新文件。写入以下代码。

pragma solidity ^0.5.16;
contract Adoption{address[16] public adopters;  // 保存领养者的地址// 领养宠物function adopt(uint petId) public returns (uint) {require(petId >= 0 && petId <= 15);  // 确保id在数组长度内adopters[petId] = msg.sender;        // 保存调用这地址return petId;}// 返回领养者function getAdopters() public view returns (address[16] memory) {return adopters;}
}
2.编译智能合约

1.进入终端,并切换目录到pet-shop目录的根目录下,执行编译命令
truffle compile
看到下边输出:

===========================
> Compiling ./contracts/Adoption.sol
> Compiling ./contracts/Migrations.sol
> Artifacts written to /Users/cruzmolina/Code/truffle-projects/metacoin/build/contracts
> Compiled successfully using:- solc: 0.5.0+commit.1d4f565a.Emscripten.clang ```
3.部署智能合约

1.我们可以看到在migrations目录中已有一个 JavaScript 文件:1_initial_migration.js. 这处理部署Migrations.sol合约以观察后续智能合约迁移,并确保我们将来不会双重迁移未更改的合约。
2.我们需要在migrations目录中创建一个名为2_deploy_contracts.js的新文件,写入以下内容:

module.exports = function(deployer) {  deployer.deploy(Adoption);};

在我们将合约迁移到区块链之前,我们需要运行一个区块链。在本教程中,我们将使用Ganache,这是一个用于以太坊开发的个人区块链,可用于部署合约、开发应用程序和运行测试。如果您还没有,请下载>Ganache并双击该图标以启动该应用程序。这将生成在端口 7545 上本地运行的区块链。

4.在终端执行部署命令
truffle migrate

输出结果:

1_initial_migration.js======================Deploying 'Migrations'----------------------> transaction hash:    0x3b558e9cdf1231d8ffb3445cb2f9fb01de9d0363e0b97a17f9517da318c2e5af> Blocks: 0            Seconds: 0> contract address:    0x5ccb4dc04600cffA8a67197d5b644ae71856aEE4> account:             0x8d9606F90B6CA5D856A9f0867a82a645e2DfFf37> balance:             99.99430184> gas used:            284908> gas price:           20 gwei> value sent:          0 ETH> total cost:          0.00569816 ETH> Saving migration to chain.> Saving artifacts-------------------------------------> Total cost:          0.00569816 ETH2_deploy_contracts.js=====================Deploying 'Adoption'..........................................................
5. 我们可以看到在ganache中,区块链的状态已更改,区块链现在显示当前区块,之前45是 ,现在是49。此外,虽然第一个账户最初有 100 个以太币,但由于迁移的交易成本,它现在更低。

小结

我们现在已经编写了第一个智能合约并将其部署到本地运行的区块链。现在是时候与我们的智能合约进行交互以确保它执行我们想要的操作。

三、测试智能合约

1.编写测试合约

在test目录下新建一个TestAdoption.sol,将下边代码复制到该文件。
注:Assert.sol 及 DeployedAddresses.sol是Truffle 框架提供,在test目录下并不提供truffle目录。

pragma solidity ^0.5.0;import "truffle/Assert.sol";   // 引入的断言
import "truffle/DeployedAddresses.sol";  // 用来获取被测试合约的地址
import "../contracts/Adoption.sol";      // 被测试合约contract TestAdoption {Adoption adoption = Adoption(DeployedAddresses.Adoption());// 领养测试用例function testUserCanAdoptPet() public {uint returnedId = adoption.adopt(8);uint expected = 8;Assert.equal(returnedId, expected, "Adoption of pet ID 8 should be recorded.");}// 宠物所有者测试用例function testGetAdopterAddressByPetId() public {// 期望领养者的地址就是本合约地址,因为交易是由测试合约发起交易,//可能会出现的bug,我个人操作过程中遇到了:bug解决方案如下://这是因为编译器版本是0.5.0,代码之前编写是按照0.4.17的规范来写的,// 这些新特性真的坑啊,幸好不是大问题,// 将 address expected = this;改为address expected = address(this);address expected = address(this);address adopter = adoption.adopters(8);Assert.equal(adopter, expected, "Owner of pet ID 8 should be recorded.");}// 测试所有领养者function testGetAdopterAddressByPetIdInArray() public {// 领养者的地址就是本合约地址address expected = address(this);address[16] memory adopters = adoption.getAdopters();Assert.equal(adopters[8], expected, "Owner of pet ID 8 should be recorded.");}
}
2.执行测试合约
truffle test

如果测试成功,则有以下输出:

Using network 'develop'.
Compiling ./contracts/Adoption.sol...
Compiling ./test/TestAdoption.sol...
Compiling truffle/Assert.sol...
Compiling truffle/DeployedAddresses.sol...TestAdoption✓ testUserCanAdoptPet (62ms)✓ testGetAdopterAddressByPetId (53ms)✓ testGetAdopterAddressByPetIdInArray (73ms)3 passing (554ms)

四、编写与智能合约交互的web端

1.在Truffle Box的 pet-shop里,已经包含了应用的前端代码,代码在src/文件夹下。用vscode打开文件,进入app.js文件。
2.可以看到用来管理整个应用的App对象,init函数加载宠物信息,就初始化web3.web3是一个实现了与以太坊节点通信的库,我们利用web3来和合约进行交互。

1.初始化web3

编辑app.js修改initWeb3(): 删除注释,修改为:

  initWeb3: async function() {// Modern dapp browsers...if (window.ethereum) {App.web3Provider = window.ethereum;try {// Request account accessawait window.ethereum.enable();} catch (error) {// User denied account access...console.error("User denied account access")}}// Legacy dapp browsers...else if (window.web3) {App.web3Provider = window.web3.currentProvider;}// If no injected web3 instance is detected, fall back to Ganacheelse {App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');}web3 = new Web3(App.web3Provider);return App.initContract();}

新的Dapp浏览器或MetaMask的新版本,注入了一个ethereum 对象到window象里, 应该优先使用ethereum来构造web3, 同时使用ethereum.enable()来请求用户授权访问链接账号。

2.实例化合约

使用truffle-contract会帮我们保存合约部署的信息,就不需要我们手动修改合约地址,修改initContract()代码如下:

initContract: function() {// 加载Adoption.json,保存了Adoption的ABI(接口说明)信息及部署后的网络(地址)信息,它在编译合约的时候生成ABI,在部署的时候追加网络信息$.getJSON('Adoption.json', function(data) {// 用Adoption.json数据创建一个可交互的TruffleContract合约实例。var AdoptionArtifact = data;App.contracts.Adoption = TruffleContract(AdoptionArtifact);// Set the provider for our contractApp.contracts.Adoption.setProvider(App.web3Provider);// Use our contract to retrieve and mark the adopted petsreturn App.markAdopted();});return App.bindEvents();
}
3.处理领养

修改markAdopted()代码:

  markAdopted: function(adopters, account) {var adoptionInstance;App.contracts.Adoption.deployed().then(function(instance) {adoptionInstance = instance;// 调用合约的getAdopters(), 用call读取信息不用消耗gasreturn adoptionInstance.getAdopters.call();}).then(function(adopters) {for (i = 0; i < adopters.length; i++) {if (adopters[i] !== '0x0000000000000000000000000000000000000000') {$('.panel-pet').eq(i).find('button').text('Success').attr('disabled', true);}}}).catch(function(err) {console.log(err.message);});}

修改handleAdopt()代码:

  handleAdopt: function(event) {event.preventDefault();var petId = parseInt($(event.target).data('id'));var adoptionInstance;// 获取用户账号web3.eth.getAccounts(function(error, accounts) {if (error) {console.log(error);}var account = accounts[0];App.contracts.Adoption.deployed().then(function(instance) {adoptionInstance = instance;// 发送交易领养宠物return adoptionInstance.adopt(petId, {from: account});}).then(function(result) {return App.markAdopted();}).catch(function(err) {console.log(err.message);});});}
4.在浏览器中运行

(1)安装 MetaMask

这是一款可以以chrome插件运行的以太坊轻客户端,开发过程中使用MetaMask和我们的dapp进行交互是个很好的选择,安装完成后,浏览器工具条会显示一个小狐狸图标。

(2)在插件处打开,创建账户登录
(3)点击如图所示1处,自定义RPC

  • 名称:Custom RPC
  • RPC URL:http://127.0.0.1:7545
  • 链ID:写本地区块链的链ID (1337)

5.安装和配置lite-server

接下来需要本地的web 服务器提供服务的访问, Truffle Box pet-shop里提供了一个lite-server可以直接使用,我们看看它是如何工作的。
bs-config.json中设定了lite-server的工作目录。

{"server": {"baseDir": ["./src", "./build/contracts"]}
}
  • ./src 是网站文件目录
  • ./build/contracts 是合约输出目录

以此同时,在package.json文件的scripts中添加了dev命令:

"scripts": {"dev": "lite-server","test": "echo \"Error: no test specified\" && exit 1"
},

当运行npm run dev的时候,就会启动lite-server

6.启动服务
npm run dev

执行该命令后,将会启动web端项目,系统自动进入浏览器的宠物领养界面,

我们点击adopt按钮,系统将会调用metamask钱包,进行确认,之后本地区块链完成交易上链,则实现了宠物领养的过程。

(四)以太坊——运用truffle框架部署第一个DAPP ---- Pet-Shop相关推荐

  1. 【web3实践 | 以太坊开发框架Truffle使用】

    Truffle简介 Truffle是一个面向以太坊的开发框架,提供一整套构建.测试.部署以及管理智能合约的开发工具.Truffle可以与以太坊节点交互,使开发人员能够在本地开发.测试和部署智能合约. ...

  2. 区块链DAPP开发 以太坊智能合约框架有哪些

    一.truffle(JavaScript) Truffle 是一个在以太坊进行 DApp 开发的世界级开发环境.测试框架. 使用 Truffle 开发有一以下优点: 内置智能合约编译,链接,部署和二进 ...

  3. go打造以太坊合约测试框架

    传送门: 柏链项目学院 1 以太坊智能合约编译 以太坊智能合约编写使用solidity语言,一般情况下我们会在remix环境下进行编译测试,在线环境相对比较稳定.如果不想用在线环境,那我们就需要自己动 ...

  4. 以太坊开发入门,如何搭建一个区块链DApp投票系统

    点击关注异步图书,置顶公众号 每天与你分享 IT好书 技术干货 职场知识 第一节 概述 对于初学者,需要了解以太坊开发相关的基本概念,另外就是如何构建一个基于以太坊的完整去中心化应用例如一个区块链投票 ...

  5. 以太坊开发框架——Truffle的基础使用

    这里写目录标题 Truffle Truffle 简介 Truffle 的客户端 安装Truffle 创建项目 Migration artifacts.require() exports 的函数 dep ...

  6. 以太坊:Truffle 和 MetaMask 配合

    Truffle 和 MetaMask 配合 在浏览器中与智能合约进行交互之前,请确保合约已经编译及部署,并且我们是通过客户端JavaScript中的web3与合约进行交互. Truffle 建议使用t ...

  7. geth 转账_以太坊1 - 私有链部署、挖矿、转账

    总结一下以太坊私有链搭建的过程,已经遇到的问题. 我们使用了LINUX,MAC OSX,WINDOWS三种平台,运行go-ethereum. 一.go语言安装 LINUX 命令行输入sudo gedi ...

  8. 120 以太坊 ethereum truffle : 编写自动化智能合约测试

    • 介绍 • 关于测试 • 设置测试环境 • 编写单元测试 • 执行复杂的断言 • truffle Tutorials 教程 • Contact 联系方式 • 介绍 在区块链环境中,一个错误可能会花费 ...

  9. 不同类型的以太坊区块链及其部署:区块链类型:公有链,联盟链,私有链、安装部署以太坊。

    第三章 文章目录 第三章 一.区块链类型 1.公有链 2.联盟链 3.私有链 二.安装部署以太坊. 1. 安装 总结 一.区块链类型 根据区块链网络类型分类:私有链.联盟链.共有链. 1.公有链 主网 ...

最新文章

  1. shell脚本实现C程序日志分流和多Terminal显示
  2. 服务器架设笔记——多模块和全局数据
  3. 最好用的 Python 虚拟环境,没有之一
  4. php考试倒计时提交系统,AJAX_基于Ajax技术实现考试倒计时并自动提交试卷,1.概述在开发网络考试系统 - phpStudy...
  5. 为什么“支付宝里没钱了”和“微信里没钱了”给人两种不同的感觉
  6. Qt 生成bin文件
  7. Java API 设计清单
  8. PS特效:图像碎片化
  9. HowToDoInJava Spring 教程·翻译完成
  10. sublime3快捷键
  11. 04 Mysql之单表查询
  12. slz-servlet的引入
  13. 在嵌入式uClibc上移植valgrind
  14. 关系抽取;串联抽取和联合抽取论文总结
  15. Mac安装 MySQL 可视化工具MySQL Workbench
  16. cmos逻辑门传输延迟时间_电路基础:详解TTL和CMOS电平
  17. HTML的弹性布局用法
  18. 面试经典算法-上楼梯问题
  19. 英伟达Flex-unity插件
  20. 数据有效性做下拉菜单

热门文章

  1. html 块元素 css,HTML和CSS - 内嵌块元素的问题
  2. bzoj1022 约翰的游戏 反SG-博弈
  3. java poi 操作Excel 删除行内容和直接删除行
  4. 关于Ecshop小京东,手机管理后台,增加楼层右边分类不显示的问题
  5. CF1637E. Best Pair
  6. 使用IDEA 进行 安卓开发
  7. spring中自带的缓存springcache
  8. AD16实现板框挖空
  9. IDEA2020版本Bpmn文件无Editor属性设置编辑器问题的解决
  10. Ubuntu下磁盘管理