基于ethers.js连接小狐狸快速开发

2024-04-13 14:36

本文主要是介绍基于ethers.js连接小狐狸快速开发,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1:安装
以太坊中各种类和函数都可以从@ethersproject下的子库中手动进行导入,但对于大多数项目来说,用完整的总库是最简单的入门方式。

npm install --save ethers

2:导入

const { ethers } = require("ethers");
import { ethers } from "ethers";

3.Web 浏览器

出于安全,通常较好的方式是将这个库复制到你的web服务器中来进行各种操作。但若想快速构建实例展示,可以将我们的CDN加载到你的web应用程序中。

在浏览器中通过ES6的方式
<script type="module">import { ethers } from "https://cdn.ethers.io/lib/ethers-5.2.esm.min.js";// Your code here...
</script>
在浏览器中通过ES3 (UMD)的方式
<script src="https://cdn.ethers.io/lib/ethers-5.2.umd.min.js"type="application/javascript"></script>

常用术语

Provider(提供者)是一个用于连接以太坊网络的抽象类,提供了只读形式来访问区块链网络和获取链上状态。
Signer(签名器)通常是以某种方式直接或间接访问私钥,可以签名消息和在已授权网络中管理你账户中的以太币来进行交易。
Contract(合约)是一个运行在以太坊网络上表示现实中特定合约的抽象,应用可以像使用JavaScript对象一样使用它。

方式1:连接以太坊: MetaMask
在以太坊上去开发和测试的最快、最简单的方法是使用MetaMask, 它是一个基于浏览器的扩展程序,提供了:
连接以太坊网络 (a Provider)
保存你的私钥并且可以签名 (a Signer)

连接 MetaMask
// A Web3Provider wraps a standard Web3 provider, which is
// what MetaMask injects as window.ethereum into each page

const provider = new ethers.providers.Web3Provider(window.ethereum)

// The MetaMask plugin also allows signing transactions to
// send ether and pay to change state within the blockchain.
// For this, you need the account signer…

const signer = provider.getSigner()

方式2:连接以太坊: RPC
JSON-RPC API 另一种与以太坊交互的比较流行的方式,用在所有主要的以太坊节点 (如 Geth 和 Parity) 以及许多第三方web服务 (如 INFURA)。 它通常提供了:

**连接以太坊网络 (Provider)
保存你的私钥并且可以签名 (Signer)** 

连接一个 RPC 客户端
// If you don’t specify a //url//, Ethers connects to the default
// (i.e. http:/\/localhost:8545)

const provider = new ethers.providers.JsonRpcProvider();
const signer = provider.getSigner()

查询区块链

当你有了Provider之后, 你就可以通过只读的方式连接区块链, 此外,你还可以使用它来查询当前状态、获取历史日志、查找部署的代码等等。
基础查询

// Look up the current block number
**await provider.getBlockNumber()**
// 16383845// Get the balance of an account (by address or ENS name, if supported by network)
**balance = await provider.getBalance("ethers.eth")**
// { BigNumber: "182334002436162568" }// Often you need to format the output to something more user-friendly,
// such as in ether (instead of wei)
**ethers.utils.formatEther(balance)**
// '0.182334002436162568'// If a user enters a string in an input field, you may need
// to convert it from ether (as a string) to wei (as a BigNumber)
**ethers.utils.parseEther("1.0")**
// { BigNumber: "1000000000000000000" }
写入区块链
发送 Ether
// Send 1 ether to an ens name.
const tx = signer.sendTransaction({to: "ricmoo.firefly.eth",value: ethers.utils.parseEther("1.0")
});

合约

合约(Contract)是以太坊区块链中程序代码的抽象。

合约 (Contract) 对象使得链上的合约可以简单地作为一个普通的JavaScript对象, 通过映射的方法来编码和解码数据。

如果你熟悉数据库, 你会发现这与对象关系映射器 (ORM)是相似的。

为了与链上的合约进行通信,这个类需要知道哪些方法是可用的,以及如何编码和解码数据,这些通过应用程序二进制接口 (ABI)来提供。

这个类是一个 元类(meta-class), 这意味着它的方法是在运行时构造的, 当你将ABI传递给构造函数时,它来确定要添加哪些方法。

尽管链上的合约有许多可用的方法,但是你可以安全地忽略你认为不需要或者不使用的方法,这样合约里面的ABI就是一个较小的子集。

ABI通常来自于Solidity或Vyper编译器,但是你可以在代码中使用人类可读的ABI格式(Human-Readable),如下例所示:
连接 DAI 合约

// You can also use an ENS name for the contract address
const daiAddress = "dai.tokens.ethers.eth";// The ERC-20 Contract ABI, which is a common contract interface
// for tokens (this is the Human-Readable ABI format)
const daiAbi = [// Some details about the token"function name() view returns (string)","function symbol() view returns (string)",// Get the account balance"function balanceOf(address) view returns (uint)",// Send some of your tokens to someone else"function transfer(address to, uint amount)",// An event triggered whenever anyone transfers to someone else"event Transfer(address indexed from, address indexed to, uint amount)"
];// The Contract object
const daiContract = new ethers.Contract(daiAddress, daiAbi, provider);

只读方法
查询 DAI 合约

// Get the ERC-20 token name
await daiContract.name()
// 'Dai Stablecoin'// Get the ERC-20 token symbol (for tickers and UIs)
await daiContract.symbol()
// 'DAI'// Get the balance of an address
balance = await daiContract.balanceOf("ricmoo.firefly.eth")
// { BigNumber: "2413468059122458201631" }// Format the DAI for displaying to the user
ethers.utils.formatUnits(balance, 18)
// '2413.468059122458201631'

改变状态的方法
发送 DAI

// The DAI Contract is currently connected to the Provider,
// which is read-only. You need to connect to a Signer, so
// that you can pay to send state-changing transactions.
const daiWithSigner = contract.connect(signer);// Each DAI has 18 decimal places
const dai = ethers.utils.parseUnits("1.0", 18);// Send 1 DAI to "ricmoo.firefly.eth"
tx = daiWithSigner.transfer("ricmoo.firefly.eth", dai);

监听事件
监听事件

// Receive an event when ANY transfer occurs
daiContract.on("Transfer", (from, to, amount, event) => {console.log(`${ from } sent ${ formatEther(amount) } to ${ to}`);// The event object contains the verbatim log data, the// EventFragment and functions to fetch the block,// transaction and receipt and event functions
});// A filter for when a specific address receives tokens
myAddress = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
filter = daiContract.filters.Transfer(null, myAddress)
// {
//   address: 'dai.tokens.ethers.eth',
//   topics: [
//     '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
//     null,
//     '0x0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72'
//   ]
// }// Receive an event when that filter occurs
daiContract.on(filter, (from, to, amount, event) => {// The to will always be "address"console.log(`I got ${ formatEther(amount) } from ${ from }.`);
});

查询历史事件
过滤历史事件

// Get the address of the Signer
myAddress = await signer.getAddress()
// '0x8ba1f109551bD432803012645Ac136ddd64DBA72'// Filter for all token transfers from me
filterFrom = daiContract.filters.Transfer(myAddress, null);
// {
//   address: 'dai.tokens.ethers.eth',
//   topics: [
//     '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
//     '0x0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72'
//   ]
// }// Filter for all token transfers to me
filterTo = daiContract.filters.Transfer(null, myAddress);
// {
//   address: 'dai.tokens.ethers.eth',
//   topics: [
//     '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
//     null,
//     '0x0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72'
//   ]
// }// List all transfers sent from me a specific block range
await daiContract.queryFilter(filterFrom, 9843470, 9843480)
// [
//   {
//     address: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
//     args: [
//       '0x8ba1f109551bD432803012645Ac136ddd64DBA72',
//       '0x8B3765eDA5207fB21690874B722ae276B96260E0',
//       { BigNumber: "4750000000000000000" },
//       amount: { BigNumber: "4750000000000000000" },
//       from: '0x8ba1f109551bD432803012645Ac136ddd64DBA72',
//       to: '0x8B3765eDA5207fB21690874B722ae276B96260E0'
//     ],
//     blockHash: '0x8462eb2fbcef5aa4861266f59ad5f47b9aa6525d767d713920fdbdfb6b0c0b78',
//     blockNumber: 9843476,
//     data: '0x00000000000000000000000000000000000000000000000041eb63d55b1b0000',
//     decode: [Function],
//     event: 'Transfer',
//     eventSignature: 'Transfer(address,address,uint256)',
//     getBlock: [Function],
//     getTransaction: [Function],
//     getTransactionReceipt: [Function],
//     logIndex: 69,
//     removeListener: [Function],
//     removed: false,
//     topics: [
//       '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
//       '0x0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72',
//       '0x0000000000000000000000008b3765eda5207fb21690874b722ae276b96260e0'
//     ],
//     transactionHash: '0x1be23554545030e1ce47391a41098a46ff426382ed740db62d63d7676ff6fcf1',
//     transactionIndex: 81
//   },
//   {
//     address: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
//     args: [
//       '0x8ba1f109551bD432803012645Ac136ddd64DBA72',
//       '0x00De4B13153673BCAE2616b67bf822500d325Fc3',
//       { BigNumber: "250000000000000000" },
//       amount: { BigNumber: "250000000000000000" },
//       from: '0x8ba1f109551bD432803012645Ac136ddd64DBA72',
//       to: '0x00De4B13153673BCAE2616b67bf822500d325Fc3'
//     ],
//     blockHash: '0x8462eb2fbcef5aa4861266f59ad5f47b9aa6525d767d713920fdbdfb6b0c0b78',
//     blockNumber: 9843476,
//     data: '0x00000000000000000000000000000000000000000000000003782dace9d90000',
//     decode: [Function],
//     event: 'Transfer',
//     eventSignature: 'Transfer(address,address,uint256)',
//     getBlock: [Function],
//     getTransaction: [Function],
//     getTransactionReceipt: [Function],
//     logIndex: 70,
//     removeListener: [Function],
//     removed: false,
//     topics: [
//       '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
//       '0x0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72',
//       '0x00000000000000000000000000de4b13153673bcae2616b67bf822500d325fc3'
//     ],
//     transactionHash: '0x1be23554545030e1ce47391a41098a46ff426382ed740db62d63d7676ff6fcf1',
//     transactionIndex: 81
//   }
// ]//
// The following have had the results omitted due to the
// number of entries; but they provide some useful examples
//// List all transfers sent in the last 10,000 blocks
await daiContract.queryFilter(filterFrom, -10000)// List all transfers ever sent to me
await daiContract.queryFilter(filterTo)
签名消息
签名消息
// To sign a simple string, which are used for
// logging into a service, such as CryptoKitties,
// pass the string in.
signature = await signer.signMessage("Hello World");
// '0x776d4dbf69ee5ed47b3250c56dbcec7ac3a59fb64447a480dcbfe05e2431547b02cf5200876ea6a9e018680dda31a9283cb0230196782f3d48dba450f0176d141b'//
// A common case is also signing a hash, which is 32
// bytes. It is important to note, that to sign binary
// data it MUST be an Array (or TypedArray)
//// This string is 66 characters long
message = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"// This array representation is 32 bytes long
messageBytes = ethers.utils.arrayify(message);
// Uint8Array [ 221, 242, 82, 173, 27, 226, 200, 155, 105, 194, 176, 104, 252, 55, 141, 170, 149, 43, 167, 241, 99, 196, 161, 22, 40, 245, 90, 77, 245, 35, 179, 239 ]// To sign a hash, you most often want to sign the bytes
signature = await signer.signMessage(messageBytes)

这篇关于基于ethers.js连接小狐狸快速开发的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/900408

相关文章

基于Python开发PDF转PNG的可视化工具

《基于Python开发PDF转PNG的可视化工具》在数字文档处理领域,PDF到图像格式的转换是常见需求,本文介绍如何利用Python的PyMuPDF库和Tkinter框架开发一个带图形界面的PDF转P... 目录一、引言二、功能特性三、技术架构1. 技术栈组成2. 系统架构javascript设计3.效果图

IDEA连接达梦数据库的详细配置指南

《IDEA连接达梦数据库的详细配置指南》达梦数据库(DMDatabase)作为国产关系型数据库的代表,广泛应用于企业级系统开发,本文将详细介绍如何在IntelliJIDEA中配置并连接达梦数据库,助力... 目录准备工作1. 下载达梦JDBC驱动配置步骤1. 将驱动添加到IDEA2. 创建数据库连接连接参数

Win32下C++实现快速获取硬盘分区信息

《Win32下C++实现快速获取硬盘分区信息》这篇文章主要为大家详细介绍了Win32下C++如何实现快速获取硬盘分区信息,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实现代码CDiskDriveUtils.h#pragma once #include <wtypesbase

基于Python开发PDF转Doc格式小程序

《基于Python开发PDF转Doc格式小程序》这篇文章主要为大家详细介绍了如何基于Python开发PDF转Doc格式小程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用python实现PDF转Doc格式小程序以下是一个使用Python实现PDF转DOC格式的GUI程序,采用T

使用Python开发一个图像标注与OCR识别工具

《使用Python开发一个图像标注与OCR识别工具》:本文主要介绍一个使用Python开发的工具,允许用户在图像上进行矩形标注,使用OCR对标注区域进行文本识别,并将结果保存为Excel文件,感兴... 目录项目简介1. 图像加载与显示2. 矩形标注3. OCR识别4. 标注的保存与加载5. 裁剪与重置图像

Spring AI与DeepSeek实战一之快速打造智能对话应用

《SpringAI与DeepSeek实战一之快速打造智能对话应用》本文详细介绍了如何通过SpringAI框架集成DeepSeek大模型,实现普通对话和流式对话功能,步骤包括申请API-KEY、项目搭... 目录一、概述二、申请DeepSeek的API-KEY三、项目搭建3.1. 开发环境要求3.2. mav

Python如何快速下载依赖

《Python如何快速下载依赖》本文介绍了四种在Python中快速下载依赖的方法,包括使用国内镜像源、开启pip并发下载功能、使用pipreqs批量下载项目依赖以及使用conda管理依赖,通过这些方法... 目录python快速下载依赖1. 使用国内镜像源临时使用镜像源永久配置镜像源2. 使用 pip 的并

pycharm远程连接服务器运行pytorch的过程详解

《pycharm远程连接服务器运行pytorch的过程详解》:本文主要介绍在Linux环境下使用Anaconda管理不同版本的Python环境,并通过PyCharm远程连接服务器来运行PyTorc... 目录linux部署pytorch背景介绍Anaconda安装Linux安装pytorch虚拟环境安装cu

SpringBoot快速接入OpenAI大模型的方法(JDK8)

《SpringBoot快速接入OpenAI大模型的方法(JDK8)》本文介绍了如何使用AI4J快速接入OpenAI大模型,并展示了如何实现流式与非流式的输出,以及对函数调用的使用,AI4J支持JDK8... 目录使用AI4J快速接入OpenAI大模型介绍AI4J-github快速使用创建SpringBoot

Node.js net模块的使用示例

《Node.jsnet模块的使用示例》本文主要介绍了Node.jsnet模块的使用示例,net模块支持TCP通信,处理TCP连接和数据传输,具有一定的参考价值,感兴趣的可以了解一下... 目录简介引入 net 模块核心概念TCP (传输控制协议)Socket服务器TCP 服务器创建基本服务器服务器配置选项服