浅谈 Web3.0:动手做一个去中心化 APP
2022-8-2 18:1:18 Author: 腾讯技术工程(查看原文) 阅读量:21 收藏

作者:sophiafwang,腾讯 PCG 前端开发工程师

目前 Web3.0 的发展正在越来越火热,关于 Web3.0 的文章也层出不穷。本人在调研的时候阅读了很多文章,但很多概念还是有点模糊,因此自己实践并总结了一番,才有了比较深的理解。文章主要对 Web3.0 进行一个整体的介绍,包括 Web3.0 相关基础概念以及动手实践了一个 DAPP,实践出真理,鼓励大家都可以尝试一番~

1.简介

1.1 web 的发展史

Web 1.0 静态时代:网站只是带有文本和图像的静态页面,只能阅读文本,其他的事情都不能做;

Web 2.0 大数据时代:用户可以和网络进行交互,包括发帖子、留言评论、买卖物品等等。但是数据拥有权不属于每个用户,由公司负责存储数据、管理数据;

Web 3.0 区块链时代:用户变成了数据的拥有者!去中心化的区块链网络让这变成现实,服务是开源的、协议是大家有共识的、传输是私密安全的、版权是受保护的。

1.2 web3.0 的发展史

早在 2012 年,有大佬就已经对 web3.0 相关概念进行总结,但是当时并没有一个明确的定义:

Web3.0——下一个互联网时代的进化与传承

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 应用开发者提供服务

1.3 web3.0 的概念

以太坊联合创始人 Gavin Wood 提出的 Web3.0 概念——在区块链公有链上运行的去中心化的应用程序所形成的生态系统。—简单的说,就是利用区块链,使用户可以对其内容、数据、资产拥有所有权。

Web 3.0 应用程序叫做 DApp ,全名是 Decentralized Application (去中心化应用程序)。DApp 的主要特点包括:去中心化、不可篡改、每条数据都归用户所有、数据可以买卖等。以去中心化为例,不管是微博、微信阅读还是腾讯文档,他们有互联网产品的共同特征:所有的数据都由一家互联网公司单独收集、存储、使用。这种中心化的互联网产品,往往只有一个或者两个节点,一旦被破坏,这些数据也将有消失的风险。

而在 Web3 版本的微博或微信阅读上,人们发布的每一条“微博”和“书籍”,都可以铸造成 NFT(非同质化代币),而这些 NFT 都在以太坊等区块链上。区块链相当于千千万万个数据库的集合,它有无数个节点,所以数据难以被盗取、破坏。

下面简单介绍两个 Web3 的应用和工具。

1.NFT,非同质化代币(Non-Fungible Token)的简称。基于以太坊区块链进行交易。NFT 代币的最大特点在于其唯一性,“非同质化”,每一块 NFT 都独一无二,不可互换,人们可以将特殊资产绑定在 NFT 上,其可以让许多物品成为一种数字化抽象物,变成所有者的“数字资产”;

图中的猴子叫做无聊猿。无聊猿是 Yuga Labs 发行的 NFT 项目,通过随机程序生成了一万只神态各异的猿猴,稀有度也各不相同。可以作为 NFT 被收藏,堪称目前为止最出圈的 NFT 项目。在国外,NFT 交易的火热已经催生了专门的大型交易平台,比如OpenSea

2.DAO,Decentralized Autonomous Organization,即去中心化自治组织。DAO 也是建立在区块链技术上的,相对于中心化的组织,比如公司。DAO 没有董事会,成员共同拥有权益和资产,在公开的规则下进行投票、根据群体的意见进行民主决策。对于 Web3.0 项目,尤其是涉及资产投资的 Web3.0 项目,一个开放、公正、透明的 DAO 组织,是帮助项目增加公信力的有效手段。

2.相关概念

2.1 区块链

2.1.1 定义

区块链本质上是一个去中心化的分布式账本数据库,由多个服务器组成,不可更改和伪造,类似于银行系统,不同的是区块链可以使每个人手上都有这个账本,账本公开所有人都可以查看;

2.1.2 特点
  • 防篡改——密码学
  • 分布式、去中心化——共识算法
  • 匿名、隐私性——私钥
  • 可溯源——区块的链式结构

区块链中,交易信息以一个个信息块的形式记录,这些块以链条方式,按时间顺序连接起来。新生成的交易信息记录块,不断地被加到区块链中,交易一旦写入区块链中就不能被修改;

2.1.3 公有链

公有链(Public Blockchain)通常也称为非许可链(Permissionless Blockchain),公有链是区块链的一种,无官方组织及管理机构,无中心服务器,参与的节点按照系统规格自由接入网路、不受控制,节点间基于共识机制开展工作。

公有链一般适合于虚拟货币、面向大众的电子商务、互联网金融等 B2C、C2C 或 C2B 等应用场景,比特币和以太坊等就是典型的公有链。

2.1.4 区块链的发展

区块链的应用发展,大致可分为 3 个阶段:

  • 区块链 1.0:虚拟币
  • 区块链 2.0: 智能合约
  • 区块链 3.0: DApp

2.2 虚拟币

虚拟货币是指非真实的货币。在国内比较有代表性的虚拟货币有腾讯 Q 币、新浪 U 币、百度币、盛大元宝等。比特币就属于虚拟货币,是区块链技术的产物。比特币不依靠特定货币机构发行,它依据特定算法,通过大量的计算产生,比特币经济使用整个 P2P 网络中众多节点构成的分布式数据库来确认并记录所有的交易行为,并使用密码学的设计来确保货币流通各个环节安全性。

2.3 智能合约

比特币带来的主要问题是浪费计算资源,以及缺乏网络可扩展性。为了克服这些问题,区块链 2.0 阶段引入了智能合约,将比特币的概念扩展到了货币之外。

智能合约是在区块链中“实时”运行的小型程序,它使得区块链是可编程的。智能合约最突出的例子是**以太坊(Ethereum)**虚拟币,它提供了一个平台,开发人员可以在这个平台上,为区块链网络创建分布式应用程序。

以太坊的智能合约就是一段由 EVM 虚拟机执行的字节码,常都是由编译器负责把高级语言编译为字节码。当智能合约被编译成二进制文件后,被部署到区块链上。用户通过调用智能合约的接口,来触发智能合约的执行操作。EVM 执行智能合约的代码,修改当前区块链上的数据(状态),被修改的数据,会被共识,确保一致性

智能合约主要是为了解决信任问题而产生的,由于智能合约存放在区块链,并且区块链不可抵赖,不能篡改,因此智能合约比现实中任何一个机构的公信力都强,而区块链的去中心化思想的最大优势就是解决了信任问题。

但是如果智能合约出错后,可能会造成代币被盗或者消耗大量的 gas,必须去修复错误,而修复 bug 只能重新部署合约,就会产生一个问题:原来的合约已经有很多人在使用,如果部署新的合约,老合约的数据就丢失。

2.4 去中心化

去中心化(Decentralized)的意思就是用户可以不通过 Google、Facebook、微博等中介的服务访问互联网上的数据和信息,而是由个人自己拥有和控制互联网的各个部分。也就是说,在 Web3 上,开发者不需要在一个单独的服务器上建立和部署应用,也不用在一个单独的数据库中储存数据,极大降低了单点故障的风险。

区块链是真正去中心化互联网的核心,它改变了数据存储和管理的方式,其独特的架构允许多个节点在没有一个集中的事实来源的情况下就数据集的当前状态保持一致。作为用户为去中心化执行而激活的自动执行代码,智能合约是加密难题的重要组成部分,这允许两方在彼此不知情的情况下进行价值转移。

2.5 gas 费用

以太坊中交易需要手续费,手续费被称为 gas(汽油),gas 是用于评估在以太坊区块链上执行特定操作所需的计算工作量的单位。

gas 只是一个抽象单位,它仅存在于以太坊虚拟机中,用户实际上总是在以太坊网络中使用 ETH(以太币)进行交易。

为什么要引入 gas 呢?

以太坊虚拟机可以执行任意代码,但它也更容易受到 halting problem 的影响。halting problem 是指从一个任意计算机程序的代码和输入来确定该程序是会结束运行,还是会永远继续运行。如果没有 gas,用户就可以执行一个永远不会停止的程序,为了防止这种情况发生,以太坊引入了与每个操作相关的 gas 成本,这将防止程序处于永远运行的状态,最终使整个网络陷入停滞状态。

3. DAPP 开发

3.1 去中心化应用和中心化应用的区别

3.2 DApp 的整体框架

去中心化 app 可以由多个智能合约组成,每个智能合约都有各自的地址,类似于以太坊上的一个账户,可以存取以太币;

3.2.1 DApp 的基本架构图:

主要分为三个部分:

1、区块链以及本身提供的能力

2、三方钱包等提供的能力

3、我们要写的 DApp 部分----分为三个部分:

(1)和 EVM 交互的合约层-- solidity 编写;(2)和合约层、钱包交互的交互层-web3js, 其和 Ajax 类似,可以用来读取以太坊区块链,主要使用的 JSON RPC 和区块链进行通信,对区块链网络进行数据的读写操作;(3) 前端代码业务层-vue、react 等编写;DAPP 可以使用

3.2.2 开发 dapp 的步骤

1、开发智能合约:一般使用 solidity 语言进行开发,选用以太坊合约、bsc 合约等;

2、部署智能合约:一般使用 remix 工具进行部署,先在测试环境中进行部署智能合约,申请对应的测试币;

3、开发 dapp 前端:使用前端框架进行开发,前端设计到和钱包的连接、调用合约、数据查询等内容;

3.2.3 环境搭建

主要需要解决的问题是模拟链(毕竟真链上的操作都是要花钱的)、钱包和合约的问题;

1、链可以用ganache进行模拟

2、钱包用 MetaMask

3、solidity 既然是一个编程语言,并且要跑再 EVM 上,那就有 编写、编译、测试和调试的地方,这里推荐使用remix

3.2.4 部署和调用

DApp 在被调用之前需要先部署到以太坊上,主要分为部署和调用两部分;

(1)部署

一个 DApp 可以由多个智能合约组成,因此部署一个 DApp 也就是同时部署多个智能合约,那么部署一个智能合约的流程图如下:

  • 智能合约使用 RPC 调用以太坊的钱包、Web3.js 等工具;
  • Web3.js 将合约部署到以太坊中的 Solc 编译器中;
  • 编译器将编译后的字节码返回;
  • 将合约字节码以及相关参数发送到以太坊的节点中;
  • 以太坊部署节点后返回合约地址以及二进制接口(ABI)

(2)调用

部署好的合约可以进行调用,前端调用主要依赖 MetaMask 插件,前端的 Web3 Provider 是与特定的以太坊节点相连,可以直接使用

web3.currentProvider 调用,下图展示了前端调用合约的一般流程。


智能合约: 存在于区块链上的代码片段。它们在区块链内操作,且不可更改。

节点/Web3 提供者: 要从区块链获取数据,需要节点或 Web3 提供者;节点运行区块链的副本。节点是 web3 开发人员栈的重要组成部分,因为没有节点,web3 库就无法与智能合约交互。它们充当进入区块链领域的门户。

4 DAPP 初体验

4.1 创建项目

本文借鉴了网上的例子进行如下的实践,具体的流程如下:

DAPP 框架可以使用 truffle 进行编写

4.1.1 使用 truffle 创建项目

npm install -g truffle

  1. 使用 truffle version 检查是否安装成功;

  2. truffle 框架中本身存在几个项目,可以直接使用自带的 pet-shop 项目进行开发,用 truffle unbox 命令解压缩这个框架到我们的文件夹下。

truffle unbox pet-shop

  1. 创建后的项目文件夹:

contracts/:智能合约 Solidity 的源文件,包含一个迁移合约 Migrations.sol;

migrations/:Truffle 使用迁移系统来处理智能合约部署。迁移是一种额外的特殊智能合约,可以跟踪变化;

test/:包含智能合约的 JavaScript 和 Solidity 测试;

truffle-config.js:包含 truffle 配置文件;

4.1.2 Ganache

Ganache 是一个运行在本地的个人区块链,通过Ganache官网可以下载,其前身是 TestRPC 可以用来开发以太坊的个人区块链;

Ganache 可以部署合同,开发应用程序以及进行测试;

Ganache 中可以免费提供 10 个账号,分别记录了各自的地址以及余额,并且需要关注 RPC SERVER 的地址;

4.2 编写智能合约

主要是在 contracts 中去新建 Adoption.sol 文件,pragma solidity ^0.5.0; //控制智能合约编译器的版本

pragma solidity ^0.5.0//控制智能合约编译器的版本

contract Adoption {

  address[16public 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;
  }

}

4.3 编译和迁移智能合约

Solidity 是一种编译语言,需要编译成字节码,才可以执行在以太坊虚拟机(EVM);

truffle compile

编译成功合约之后需要迁移到区块链中,在 migrations 目录中创建新文件;

//创建自己的迁移文件-2_deploy_contracts.js var

//创建自己的迁移文件-2_deploy_contracts.js var
var Adoption = artifacts.require("Adoption");

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

 //在端口7454上运行本地区块链
 truffle migrate

上述操作完成后,会发现在 Ganache 中存在 4 个区块;

4.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进行测试可以判断用例是否通过;

4.5 创建用户界面并和智能合约进行交互

在 src 文件夹中进行界面的开发,主要是补充以太坊的功能,web3 是一个实现了与以太坊节点通信的库,我们利用 web3 来和合约进行交互。优先使用 MetaMask 提供的 Web3 实例,truffle-contract 会帮我们保存合约部署的信息;

//app.js  初始化Web3以及实例化合约
 initWeb3: function() {
    // 先判断是否存在web3
    if (typeof web3 !== 'undefined') {
      App.web3Provider = window.ethereum;
    } else {
      // 如果没有检测到注入的 web3 实例,则回退到 Ganache
      App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
    }
    web3 = new Web3(App.web3Provider);

    return App.initContract();
  },

  initContract: function() {
    // 加载Adoption.json,保存Adoption的ABI(接口说明)信息及部署后的网络(地址)信息,它在编译合约的时候生成ABI,在部署的时候追加网络信息
    $.getJSON('Adoption.json', function(data) {
      // 用Adoption.json数据创建一个可交互的TruffleContract合约实例。
      var AdoptionArtifact = data;
      App.contracts.Adoption = TruffleContract(AdoptionArtifact);

      // 设置合约提供者
      App.contracts.Adoption.setProvider(App.web3Provider);

      // 使用自己定义的合约标记已经收养的宠物
      return App.markAdopted();
    });
    return App.bindEvents();
}

4.6 浏览器启动项目并进行交互

npm run dev 启动项目

4.7 安装 MetaMask 和配置区块链网络

MetaMask 是一款插件形式的以太坊轻客户端,可以在官网直接下载https://metamask.io/。

  1. 为了连接本地的网络,需要添加新网络;

在连接 metaMask 需要新增网络,网络的链 ID 和 RPC URL 是必须填写的项目,那么链 ID 一般可以使用 1337,如果有占用可以删除后再使用;在连接对应网络的时候,需要保持 Ganache 是打开的状态;

  1. 创建新用户,并使用 Ganache 中其中一个地址的私钥导入账户,导入成功就会发现有免费的 100ETH 可以进行交易;

-注意这里在和钱包进行连接的时候,需要先将对应的账户连接到目标网络后才能进行通讯,并使用钱包;

  1. 启动项目

4.点击 Adopt,进行领养,成功将为 Success。

从活动中可以看到对应的交易信息:

5 总结

长远看来,去中心化 App 应该是商业体系中比较重要的部分但不是全部,Web3.0 以后的发展具体是如何,个人觉得应该更加提倡用户和平台之间平等的关系,而完全的去中心化是否可以成为现实应该是一个值得期待和探讨的事情。

参考链接:

metamask

为什么 Web3 与区块链有关

以太坊 DApp 系列(二)---从入门到出家


文章来源: http://mp.weixin.qq.com/s?__biz=MjM5ODYwMjI2MA==&mid=2649772097&idx=1&sn=3022360a1ba410b59c776354c63e418a&chksm=beccc33a89bb4a2cce70c8b406d9545f893fa08cb310c8fd2066dec207bea662c17006cc2210#rd
如有侵权请联系:admin#unsafe.sh