🐵15 DApp

[TOC]

DApp

以太坊社区将基于智能合约的应用称为去中心化的应用程序(Decentralized App,简称DApp)。DApp可以在一台与以太坊节点交互的中心化服务器上运行,也可以在任意一个以太坊平等节点上运行。

  • DApp 开发分两部分,首先要有提供服务接口的智能合约程序,而 DApp 是向用户提供友好 UI 操作界面。

  • 形式上看来,智能合约开发像传统的后端开发,负责后端业务并向 DApp 提供服务接口,而 DApp 则是访问智能合约接口并向用户提供操作界面,负责客户端的业务开发。

智能合约

智能合约是部署在区块链上的服务程序,数据存储在区块链。传统的服务端程序(如JAVA后端)部署在私有服务器,数据往往存储在一些数据库服务程序,如 MySQL、Redis等。

  • 智能合约也属于服务端程序,通过外部函数 external 或公开函数 public 的方式向外暴露接口。客户端通过 web3.jsethers.js 等使用 HTTP 或 IPC 连接和以太坊区块链节点交互,就是访问智能合约向外暴露的接口。

智能合约

智能合约

传统的服务端程序

传统的服务端程序

web3

DApp开发通常要用到 web3.js 和 MetaMask 钱包,web3.js 提供了一系列对区块链、智能合约、的操作API,而转账、支付 gas 等操作都需要调用到 MetaMask,DApp 的用户在默认下至少安装了一种或多种 MetaMask 这样的钱包插件。

web3.js

web3.js 库是由以太坊基金会构建的开源 JavaScript 库(GNU Lesser General Public License 第 3 版),包括通过 JavaScript 对象表示法 - Remote Procedure Call (JSON-RPC) 协议与以太坊节点进行通信的函数。它是与以太坊区块链进行交互的 JavaScript 库。

  • Web3.js 由一个主类 web3 和四个模块组成 web3-eth、web3-shh、web3-bzz、web3-utils

web3-eth 模块中包含函数,作用是让 web3.js 的用户可以与以太坊区块链进行交互。这些函数能够与智能合约、归外部所有的账户、节点、挖出的区块以及交易进行交互。

  • web3.eth.getBalance 函数是获得指定区块的某个地址的以太坊余额

  • web3.eth.signTransaction 函数是对交易签名

  • web3.eth.sendSignedTransaction 函数是将签名的交易发送到以太坊区块链。

web3-shh 模块的作用是使您可以与 Whisper 协议进行交互。Whisper 是一个消息传输协议,其目的是轻松广播消息以及进行低层异步通信。

  • web3.shh.post 将 whisper 消息发布到网络

  • web3.shh.subscribe 创建传入的 whisper 消息订阅

web3-bzz 模块的作用是使您可以与 Swarm 交互。Swarm 是一个去中心化存储平台和内容分发服务,它可以用来为去中心化应用存储图片或视频等文件。

  • web3.bzz.upload 的作用是使您可以将文件和文件夹上传到 Swarm

  • Web3.bzz.download 的作用是使您可以从 Swarm 下载文件和文件夹

web3-utils 包含实用程序函数,这些函数用于转换数字、验证值是否满足特定条件以及搜索数据集。

  • web3.utils.toWei 将以太转换为 Wei

  • web3.utils.hexToNumberString 将十六进制值转换为字符串

  • web3.utils.isAddress,校验特定字符串是否为有效的以太坊地址。

MetaMask API 的使用

MetaMask 提供了一些通过 web3.js 直接操作它的函数。

  • MetaMask 文档 https://docs.metamask.io/guide/#why-metamask 。

  • 另外,涉及转账的金额等数值操作需要用额外的库计算,因为智能合约中的 uint256 这样巨大的数值在 JavaScript 中是难以表示的,所以要使用 https://github.com/indutny/bn.js 来操作具体的数值。

  • js 代码判断是否安装了 MetaMask ,必须通过 HTTP 协议才能完成这个判断,如果是 file 协议打开的 html 文件是无法完成这个判断的,其它 API 多少也有这种限制,因此在本地开发时应使用 HTTP 访问测试页面。

  • MetaMask 例子:https://github.com/PandaManPMC/dapp/blob/main/example/demo1/page/index.html

web3.js 基本使用

引入 web3.js 后连接上节点生成对象,可以使用对象调用 API。

  • web3.js 提供的功能很齐全,能够做各种功能的DApp开发,如创建账户、转账、交易查询等等。

  • web3.js 的转账函数如 web3.eth.sendTransaction 需要私钥,这意味着用户要将私钥暴露给 DApp ,存在很高的风险的,所以除非是开发类似与 MetaMask 那样的钱包,否则不会直接使用这类函数,一般需要支付的场景会调用 MetaMask 这类钱包 DApp 授权支付,这样只有钱包 MetaMask 持有用户私钥,而不是用户使用的所有 DApp。

web3.js 连接节点的协议有 3 种,http/https、WebSocket ws/wssipc

  • HttpProvider: HTTP 提供者,不支持订阅。

  • WebsocketProvider:Websocket 提供程序是在旧版浏览器中使用的标准。

  • IpcProvider:运行本地节点时使用 IPC 提供程序 node.js dapps。提供最安全的连接。

Provider

  • 使用 Web3.givenProvider 会默认使用本地 MetaMask ,需要私钥签名的时候会调起 MetaMask 进行签名,就不需要在程序中进行签名,程序也无须保存私钥。

  • 如果额外设置,例如使用自行搭建的节点,就需要另外配置,并且需要私钥签名。

  • web3.js 常用函数

web3 其它语言库

web3 库除了 web3.js 还有其它语言库,如 web3j 是 java 语言库 https://github.com/web3j/web3j 。

  • Web3j 是一个轻量级、高度模块化、反应式、类型安全的 Java 和 Android 库,用于处理智能合约并与以太坊网络上的客户端(节点)集成。基于 HTTP 和 IPC的以太坊JSON-RPC客户端 API的完整实现,自动生成 Java 智能合约包装器,以从原生 Java 代码创建、部署、交易和调用智能合约(支持Solidity 和 Truffle 定义格式)。

  • 引入 Web3j

  • 基本函数的使用,除此之外,还有转账、部署合约、合约函数调用等API。

  • 在 Web3j 的调试可以使用 Ganache 模拟一个本地节点。

投票 DApp

合约提供一些列函数接口,前端通过 web3.js 调用合约接口。

投票合约

任何人可以自由调用合约发布投票项目,所有人在支付一定额度 ETH 后都可以参与投票,因此投票合约应该有增加投票项目的函数、投票函数、结束投票函数和合约拥有者可以转走投票收取的 ETH 的函数。

  • 投票合约:https://github.com/PandaManPMC/VoteDAppExample/blob/main/ethereum/vote.sol

前端

前端通过 web3.js 库实现与合约的交互,中间会调起 MetaMask 钱包支付 gas 或其它费用。

  • 完整源码 https://github.com/PandaManPMC/VoteDAppExample 。

  • 前端调用合约的函数用合约对象调用最为方便,创建合约对象需要 jsonInterface ,remix 编译合约以后会生成 vote_metadata.json 文件,文件中 output.abi 就是这个 jsonInterface

  • web3.jsweb3.eth.Contract 对象调用合约函数的方式除了 callsend 还有其它函数,包括调用事件等,文档 https://web3js.readthedocs.io/en/v1.7.0/web3-eth-contract.html

  • 所有函数调用都是异步的,涉及修改合约数据的函数需要等待到打包完成才会回调。

jsonInterface

读取 jsonInterface 创建合约对象

call 调用无须 gas 的函数

合约定义的函数

前端调用函数

send 调用需要支付或需要 gas 的函数

合约定义的函数

前端调用函数

  • 有要支付的在 send() 中增加 value 字段,无须支付就不需要加,但是 from 始终需要。

DAPP 登录的实现

DAPP 使用钱包作为会员账号,要在不知道用户钱包私钥的情况下确定操作登录的是用户本人,则可以调用 MateMask 这类保存了用户私钥的 DAPP 钱包提供的接口实现验证。

MetaMask 签名 personal_sign

MetaMask 这类遵循了 EIP-712 规范(类型化消息签名标准)的钱包 DAPP 提供有签名接口。

签名的使用

DAPP 调用 MetaMask 进行签名。

无密码登录流程

无密码登录流程

Last updated