手把手实践一个DAPP,通往Web3.0之路!
The following article is from 腾讯云开发者 Author 王菲
导语| 目前Web3.0的发展正在越来越火热,关于Web3.0的文章也层出不穷。本人在调研的时候阅读了很多文章,但很多概念还是有点模糊,因此自己实践并总结了一番,才有了比较深的理解。文章主要对web3.0进行一个整体的介绍,包括Web3.0相关基础概念以及动手实践了一个DAPP,实践出真理,鼓励大家都可以尝试一番~
一、简介
(一)web的发展史
Web 1.0静态时代:网站只是带有文本和图像的静态页面,只能阅读文本,其他的事情都不能做。
Web 2.0大数据时代:用户可以和网络进行交互,包括发帖子、留言评论、买卖物品等等。但是数据拥有权不属于每个用户,由公司负责存储数据、管理数据。
Web 3.0区块链时代:用户变成了数据的拥有者!去中心化的区块链网络让这变成现实,服务是开源的、协议是大家有共识的、传输是私密安全的、版权是受保护的。
(二)web3.0的发展史
早在2012年,有大佬就已经对web3.0相关概念进行总结,但是当时并没有一个明确的定义,Web3.0——下一个互联网时代的进化与传承(https://www.digitaling.com/articles/10498.html)
2014年4月:以太坊的联合创始人Gavin Wood ,其也是Polkadot(波卡,是一个可扩展的异构多链区块链)的创始人,正式提出了web3.0的概念,即Web3.0是去中心化的,数字身份、隐私数据及数字资产完全归个人所有的全新互联网,且将打破平台垄断,催生出新的数字经济和商业模式。
2016年11月:Gavin Wood等人一起成立web3基金会,发布polkadots波卡网络,一个可扩展的异构多链区块链。
2022年3月8日:NFT初创公司Immutable完成2亿美元融资,腾讯参投。
2022年3月9日:拜登签署加密行政令。
2022年3月29日:Dapper Labs等11家加密项目成立加拿大Web3委员会。
2022年4月4日:英国政府确认将用作支付手段的稳定币纳入支付。
2022年5月8日:Google正组建新团队,为Web3应用开发者提供服务。
(三)web3.0的概念
以太坊联合创始人Gavin Wood提出的Web3.0概念——在区块链公有链上运行的去中心化的应用程序所形成的生态系统。—简单的说,就是利用区块链,使用户可以对其内容、数据、资产拥有所有权。
Web 3.0应用程序叫做DApp ,全名是Decentralized Application (去中心化应用程序)。DApp的主要特点包括:去中心化、不可篡改、每条数据都归用户所有、数据可以买卖等。以去中心化为例,不管是微博、微信阅读还是腾讯文档,他们有互联网产品的共同特征:所有的数据都由一家互联网公司单独收集、存储、使用。这种中心化的互联网产品,往往只有一个或者两个节点,一旦被破坏,这些数据也将有消失的风险。
而在Web3版本的微博或微信阅读上,人们发布的每一条“微博”和“书籍”,都可以铸造成NFT(非同质化代币),而这些NFT都在以太坊等区块链上。区块链相当于千千万万个数据库的集合,它有无数个节点,所以数据难以被盗取、破坏。
下面简单介绍两个Web3的应用和工具。
NFT
NFT,非同质化代币(Non-Fungible Token)的简称。基于以太坊区块链进行交易。NFT代币的最大特点在于其唯一性,“非同质化”,每一块NFT都独一无二,不可互换,人们可以将特殊资产绑定在NFT上,其可以让许多物品成为一种数字化抽象物,变成所有者的“数字资产”;
图中的猴子叫做无聊猿。无聊猿是Yuga Labs发行的NFT项目,通过随机程序生成了一万只神态各异的猿猴,稀有度也各不相同。可以作为NFT被收藏,堪称目前为止最出圈的NFT项目。在国外,NFT交易的火热已经催生了专门的大型交易平台,比如OpenSea。
DAO
DAO,Decentralized Autonomous Organization,即去中心化自治组织。DAO也是建立在区块链技术上的,相对于中心化的组织,比如公司。
DAO没有董事会,成员共同拥有权益和资产,在公开的规则下进行投票、根据群体的意见进行民主决策。对于Web3.0项目,尤其是涉及资产投资的Web3.0项目,一个公平以及透明的DAO组织,能帮助项目增加一定的公信力。
二、相关概念
(一)区块链
定义
区块链本质上是一个去中心化的分布式账本数据库,由多个服务器组成,不可更改和伪造,类似于银行系统,不同的是区块链可以使每个人手上都有这个账本,账本公开所有人都可以查看。
特点
防篡改——密码学。
分布式、去中心化——共识算法。
匿名、隐私性——私钥。
可溯源——区块的链式结构。
区块链中,交易信息以一个个信息块的形式记录,这些块以链条方式,按时间顺序连接起来。新生成的交易信息记录块,不断地被加到区块链中,交易一旦写入区块链中就不能被修改。
公有链
公有链(Public Blockchain)通常也称为非许可链(Permissionless Blockchain),公有链是区块链的一种,无官方组织及管理机构,无中心服务器,参与的节点按照系统规格自由接入网路、不受控制,节点间基于共识机制开展工作。
公有链一般适合于虚拟货币、面向大众的电子商务、互联网金融等B2C、C2C或C2B等应用场景,比特币和以太坊等就是典型的公有链。
区块链的发展
区块链的应用发展,大致可分为3个阶段:
区块链1.0:虚拟币。
区块链2.0: 智能合约。
区块链3.0: DApp。
(二)虚拟币
虚拟货币是指非真实的货币。在国内比较有代表性的虚拟货币有腾讯Q币、新浪U币、百度币、盛大元宝等。比特币就属于虚拟货币,是区块链技术的产物。比特币不依靠特定货币机构发行,它依据特定算法,通过大量的计算产生,比特币经济使用整个P2P网络中众多节点构成的分布式数据库来确认并记录所有的交易行为,并使用密码学的设计来确保货币流通各个环节安全性。
(三)智能合约
比特币带来的主要问题是浪费计算资源,以及缺乏网络可扩展性。为了克服这些问题,区块链2.0阶段引入了智能合约,将比特币的概念扩展到了货币之外。
智能合约是在区块链中“实时”运行的小型程序,它使得区块链是可编程的。智能合约最突出的例子是以太坊(Ethereum)虚拟币,它提供了一个平台,开发人员可以在这个平台上,为区块链网络创建分布式应用程序。
以太坊的智能合约就是一段由EVM虚拟机执行的字节码,常都是由编译器负责把高级语言编译为字节码。当智能合约被编译成二进制文件后,被部署到区块链上。用户通过调用智能合约的接口,来触发智能合约的执行操作。EVM执行智能合约的代码,修改当前区块链上的数据(状态),被修改的数据,会被共识,确保一致性。
智能合约主要是为了解决信任问题而产生的,由于智能合约存放在区块链,并且区块链不可抵赖,不能篡改,因此智能合约比现实中任何一个机构的公信力都强,而区块链的去中心化思想的最大优势就是解决了信任问题。
但是如果智能合约出错后,可能会造成代币被盗或者消耗大量的gas,必须去修复错误,而修复bug只能重新部署合约,就会产生一个问题:原来的合约已经有很多人在使用,如果部署新的合约,老合约的数据就丢失。
(四)去中心化
去中心化(Decentralized)的意思就是用户可以不通过Google、Facebook、微博等中介的服务访问互联网上的数据和信息,而是由个人自己拥有和控制互联网的各个部分。也就是说,在Web3上,开发者不需要在一个单独的服务器上建立和部署应用,也不用在一个单独的数据库中储存数据,极大降低了单点故障的风险。
区块链是真正去中心化互联网的核心,它改变了数据存储和管理的方式,其独特的架构允许多个节点在没有一个集中的事实来源的情况下就数据集的当前状态保持一致。作为用户为去中心化执行而激活的自动执行代码,智能合约是加密难题的重要组成部分,这允许两方在彼此不知情的情况下进行价值转移。
(五)gas费用
以太坊中交易需要手续费,手续费被称为gas(汽油),gas是用于评估在以太坊区块链上执行特定操作所需的计算工作量的单位。
gas只是一个抽象单位,它仅存在于以太坊虚拟机中,用户实际上总是在以太坊网络中使用ETH(以太币)进行交易。
为什么要引入gas呢?
以太坊虚拟机可以执行任意代码,但它也更容易受到halting problem的影响。halting problem是指从一个任意计算机程序的代码和输入来确定该程序是会结束运行,还是会永远继续运行。如果没有gas,用户就可以执行一个永远不会停止的程序,为了防止这种情况发生,以太坊引入了与每个操作相关的gas成本,这将防止程序处于永远运行的状态,最终使整个网络陷入停滞状态。
三、DAPP开发
(一)去中心化应用和中心化应用的区别
(二)DApp的整体框架
去中心化app可以由多个智能合约组成,每个智能合约都有各自的地址,类似于以太坊上的一个账户,可以存取以太币;
DApp的基本架构图
主要分为三个部分:
区块链以及本身提供的能力。
三方钱包等提供的能力。
我们要写的DApp部分---分为三个部分:
和EVM交互的合约层---solidity编写。
和合约层、钱包交互的交互层-web3js,其和Ajax类似,可以用来读取以太坊区块链,主要使用的JSON RPC和区块链进行通信,对区块链网络进行数据的读写操作。
前端代码业务层-vue、react等编写;DAPP可以使用。
开发dapp的步骤
开发智能合约:一般使用solidity语言进行开发,选用以太坊合约、bsc合约等。
部署智能合约:一般使用remix工具进行部署,先在测试环境中进行部署智能合约,申请对应的测试币。
开发dapp前端:使用前端框架进行开发,前端设计到和钱包的连接、调用合约、数据查询等内容。
环境搭建
主要需要解决的问题是模拟链(毕竟真链上的操作都是要花钱的)、钱包和合约的问题。
链可以用ganache进行模拟。
钱包用MetaMask。
solidity既然是一个编程语言,并且要跑再EVM上,那就有编写、编译、测试和调试的地方,这里推荐使用remix。
部署和调用
DApp在被调用之前需要先部署到以太坊上,可以直接使用remix进行部署,用来编写、编译和部署以太坊合约。主要分为部署和调用两部分。
部署
部署一个智能合约的流程图如下:
智能合约使用RPC调用以太坊的钱包、Web3.js等工具;
Web3.js将合约部署到以太坊中的Solc编译器中。
编译器将编译后的字节码返回。
将合约字节码以及相关参数发送到以太坊的节点中。
以太坊部署节点后返回合约地址以及二进制接口(ABI)
调用
部署好的合约可以进行调用,前端调用主要依赖MetaMask插件,前端的Web3 Provider是与特定的以太坊节点相连,可以直接使用web3.currentProvider调用。
下图展示了前端调用合约的一般流程。
四、DAPP初体验
(一)创建项目
本文借鉴了网上的例子进行如下的实践,具体的流程如下:
DAPP框架可以使用truffle进行编写
使用truffle创建项目
npm install -g truffle
使用truffle version检查是否安装成功。
truffle框架中本身存在几个项目,可以直接使用自带的pet-shop项目进行开发,用truffle unbox命令解压缩这个框架到我们的文件夹下。
truffle unbox pet-shop
创建后的项目文件夹:
contracts/:智能合约Solidity的源文件,包含一个迁移合约Migrations.sol。
migrations/:Truffle使用迁移系统来处理智能合约部署。迁移是一种额外的特殊智能合约,可以跟踪变化。
test/:包含智能合约的JavaScript和Solidity测试。
truffle-config.js:包含truffle配置文件。
Ganache
Ganache是一个运行在本地的个人区块链,通过Ganache官网可以下载,其前身是TestRPC可以用来开发以太坊的个人区块链。
Ganache可以部署合同,开发应用程序以及进行测试。
Ganache中可以免费提供10个账号,分别记录了各自的地址以及余额,并且需要关注RPC SERVER的地址。
(二)编写智能合约
主要是在contracts中去新建Adoption.sol文件
pragma solidity ^0.5.0; //控制智能合约编译器的版本
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;
}
}
(三)编译和迁移智能合约
Solidity是一种编译语言,需要编译成字节码,才可以执行在以太坊虚拟机(EVM);
truffle compile
编译成功合约之后需要迁移到区块链中,在migrations目录中创建新文件。
//创建自己的迁移文件-2_deploy_contracts.js var
var Adoption = artifacts.require("Adoption");
module.exports = function(deployer) {
deployer.deploy(Adoption);
};
//在端口7454上运行本地区块链
truffle migrate
上述操作完成后,会发现在Ganache中存在4个区块链。
(四)测试智能合约
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 {
// 期望领养者的地址就是本合约地址,因为交易是由测试合约发起交易,
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 = this;因为编译器版本是0.5.0,代码之前编写是按照0.4.17的规范来写的
address expected=address(this);
address[16] memory adopters = adoption.getAdopters();
Assert.equal(adopters[8], expected, "Owner of pet ID 8 should be recorded.");
}
}
//使用truffle test进行测试可以判断用例是否通过;
(五)创建用户界面并和智能合约进行交互
在src文件夹中进行界面的开发,主要是补充以太坊的功能,web3是一个实现了与以太坊节点通信的库,我们利用web3来和合约进行交互。优先使用MetaMask提供的Web3实例,truffle-contract会帮我们保存合约部署的信息。
(六)浏览器启动项目并进行交互
npm run dev启动项目
(七)安装MetaMask和配置区块链网络
MetaMask是一款插件形式的以太坊轻客户端,可以在官网直接下载https://metamask.io/
为了连接本地的网络,需要添加新网络。
在连接metaMask需要新增网络,网络的链ID和RPC URL是必须填写的项目,那么链ID一般可以使用1337,如果有占用可以删除后再使用;在连接对应网络的时候,需要保持Ganache是打开的状态。
创建新用户,并使用Ganache中其中一个地址的私钥导入账户,导入成功就会发现有免费的100ETH可以进行交易。
-注意这里在和钱包进行连接的时候,需要先将对应的账户连接到目标网络后才能进行通讯,并使用钱包。
启动项目
点击Adopt,进行领养,成功将为Success。
从活动中可以看到对应的交易信息:
五、小结
长远看来,去中心化App应该是商业体系中比较重要的部分但不是全部,Web3.0以后的发展具体是如何,个人觉得应该更加提倡用户和平台之间平等的关系,而完全的去中心化是否可以成为现实应该是一个值得期待和探讨的事情。
参考资料:
1.metamask
2.为什么Web3与区块链有关
作者简介
王菲
腾讯前端开发工程师
腾讯前端开发工程师,毕业于中国科学技术大学。目前负责腾讯新闻业务的前端开发的相关工作。
高可用架构建立了一个Web3的社群互相交流学习,对Web3、Move、Rust、NFT……感兴趣的开发者扫码进群。此二维码7天内有效,如果无法进群,请加管理员 Lily:jiagou01申请进群。
参考阅读:
本文由高可用架构转载。技术原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿。