主页 > imtokenusdt钱包 > 以太坊实践整理(五)DApp开发过程记录(上)
以太坊实践整理(五)DApp开发过程记录(上)
以太坊实践整理(一)区块链基础知识
以太坊实践整理(二)Geth客户端
以太坊实战(三)智能合约的Remix开发与部署
以太坊实践整理(四)Truffle智能合约开发框架
以太坊实践整理(五)DApp开发过程记录(上)
以太坊实战(五)DApp开发全过程记录(下)
以太坊实践整理(六)文件的去中心化存储
注:本文涉及的DAPP众筹需求及合约实现均来自登链社区
通过前面的内容,我们对如何使用Ganache + Truffle来开发智能合约有了一个大概的了解。 完整的应用程序还包括用户界面。 我们将基于智能合约构建的应用称为DAPP,即去中心化应用。
DAPP开发
传统的互联网应用都是前端向中心化服务器请求,服务器同步响应数据。 DAPP是对去中心化网络中任意节点的前端请求。 节点收到交易请求后,向全网广播,全网达成共识,完成交易。
在DAPP应用中,发送给节点的请求称为“交易”,需要关联钱包签名后才能发送给节点; 另外,由于交易需要等待网络共识,大部分交易都是异步的,一般通过事件回调获取结果。
前端与智能合约之间的通信
开发DAPP应用最重要的两个部分是前端应用和智能合约。 智能合约运行在以太坊虚拟机(EVM)上,前端通过向节点发送请求来调用智能合约。 前端部分与互联网前端应用相同。 你可以使用任何你擅长的前端框架如Vue或React进行开发,然后通过web3.js函数库调用智能合约。 以太坊提供了一个 JSON-RPC 接口用于与节点交互。 Web3函数库是对JSON-RPC的封装。 Web3 以主流语言实现。 JavaScript 是 web3.js,Java 是 web3j。
众筹项目需求分析
假设我要合作写一本书,但我不确定有多少人愿意购买。 因此,我发起了众筹活动。 如果我能在一个月内筹集到10个ETH,我就会开始写作以太坊需要会前端吗,每个众筹参与者都会得到一份。 如果筹集到的资金不足,用户可以取回投资资金。 同时,为了让用户积极参与,设置了阶梯价格。 一开始参与众筹的价格很低(0.02ETH)。 每募集1 ETH,价格将上涨0.002ETH。
从需求中可以总结出合约的三个外部动作(功能):
用户向合约汇款,通过实现合约的返还功能实现; 用户兑现汇款,众筹未达标后需要用户自行调用该函数; 启动器调用。
另外,进一步梳理逻辑后,发现需要保存一些状态变量,并添加相应的逻辑:
记录用户的众筹金额,可以使用映射类型保存; 记录众筹的当前价格,可以使用映射类型保存价格; 记录合约众筹的截止时间,使用uint类型保存截止时间,可以在构造函数中使用当前时间加上30天作为截止时间; 记录众筹受益人,使用地址类型记录,在构造函数中记录合约创建者; 记录当前众筹状态(是否已经关闭),如果众筹达标(创建者提现时应及时关闭状态),之后需要阻止用户参与。创建前端应用
我们使用vue开发前端。 如果你不了解 Vue.js,建议先阅读 Vue.js 官方教程。
如果没有安装 Vue CLI,请先安装:
npm install -g @vue/cli
创建众筹前端项目:
vue create crowdfunding
实现众筹合约
编写智能合约
松露初始化
cd crowdfunding
truffle init
根据合同创建 Crowdfunding.sol:
pragma solidity >=0.6.0 <0.7.0;
contract Crowdfunding {
// 创作者
address public author;
// 参与金额
mapping(address => uint) public joined;
// 众筹目标
uint constant Target = 10 ether;
// 众筹截止时间
uint public endTime;
// 记录当前众筹价格
uint public price = 0.02 ether;
// 作者提取资金之后,关闭众筹
bool public closed = false;
// 部署合约时调用,初始化作者及众筹结束时间
constructor() public {
author = msg.sender;
endTime = now + 30 days;
}
// 更新价格,这是一个内部函数
function updatePrice() internal {
uint rise = address(this).balance / 1 ether * 0.002 ether;
price = 0.02 ether + rise;
}
// 用户向合约转账时,触发的回调函数
receive() external payable {
require(now < endTime && !closed , "众筹已结束");
require(joined[msg.sender] == 0, "你已经参与过众筹");
require(msg.value >= price, "出价太低了");
joined[msg.sender] = msg.value;
updatePrice();
}
// 作者提取资金
function withdrawFund() external {
require(msg.sender == author, "你不是作者");
require(address(this).balance >= Target, "未达到众筹目标");
closed = true;
msg.sender.transfer(address(this).balance);
}
// 读者赎回资金
function withdraw() external {
require(now > endTime, "还未到众筹结束时间");
require(!closed, "众筹达标, 众筹资金已提取");
require(Target > address(this).balance, "众筹达标,你没法提取资金");
msg.sender.transfer(joined[msg.sender]);
}
}
编译智能合约
truffle compile
部署智能合约
在migrations下创建部署脚本,2_crowfunding.js:
const crowd = artifacts.require("Crowdfunding");
module.exports = function (deployer) {
deployer.deploy(crowd);
};
在 truffle-config.js 中配置要部署的网络,确保 Ganache 正在运行,并执行智能合约部署:
truffle migrate
众筹前端实现
Vue创建的脚手架项目默认会有一个HelloWorld.vue组件。 我们编写自己的 CrowdFund.vue 组件并替换 App.vue 中的 HelloWorld.vue。
App.vue 修改为:
然后在CrowdFund.vue中完成众筹接口和相应的逻辑。 界面需要显示以下部分:
当前众筹金额; 众筹截止日期; 当前众筹价格,参与众筹的按钮; 如果已经参与,则显示参与价格和兑换按钮; 如果是创建者,它会显示一个提取资金的按钮。
CrowdFund.vue 修改如下:
新书众筹
以最低的价格获取我的新书
已众筹资金:{{ total }} ETH
众筹已完成
众筹截止时间:{{ endDate }}
参与价格
{{ joinPrice }} ETH
当前众筹价格
{{ price }} ETH
继续写JavaScript逻辑部分,与合约交互需要truffle-contract和web3,先安装:
npm install --save truffle-contract web3
CrowdFund.vue 修改如下:
以此类推以太坊需要会前端吗,众筹案例全部完成。
DAPP运行
在项目目录中运行应用程序:
npm run serve
浏览器地址访问:8080 体验DAPP:
注意保证MetaMask连接的网络与合约部署的网络一致,这样DAPP才能通过web3 DAPP发布获取合约数据
npm run build
dist目录下构建了用户发布的完整前端代码。 复制到公网服务器对外服务即可。
以太坊实践整理(一)区块链基础知识
以太坊实践整理(二)Geth客户端
以太坊实战(三)智能合约的Remix开发与部署
以太坊实践整理(四)Truffle智能合约开发框架
以太坊实践整理(五)DApp开发过程记录(上)
以太坊实战(五)DApp开发全过程记录(下)
以太坊实践整理(六)文件的去中心化存储