ethers.js2:provider提供商

1、Provider

Provider类是对以太坊网络连接的抽象,为标准以太坊节点功能提供简洁、一致的接口。在ethers中,Provider不接触用户私钥,只能读取链上信息,不能写入,这一点比web3.js要安全。

除了之前介绍的默认提供者defaultProvider以外,ethers中最常用的是jsonRpcProvider,可以让用户连接到特定节点服务商的节点。

jsonRpcProvider

2、创建节点服务商的API Key

首先,需要去节点服务商的网站注册并创建API Key,有Infura和Alchemy两家公司API Key的创建方法。

Infura API Key

Infura API Key

3、连接Infura节点 

我们用Infura节点作为例子。在创建好Infura API Key之后,就可以利用ethers.provider.JsonRpcProvider()方法来创建Provider变量。JsonRpcProvider()以节点服务的url作为参数。

 在下面这个例子中,我们分别创建连接到ETH主网和Goerli测试网的provider

// 利用Infura的rpc节点连接以太坊网络
// 填入Infura API Key, 教程:https://github.com/AmazingAng/WTFSolidity/blob/main/Topics/Tools/TOOL02_Infura/readme.md
const INFURA_ID = ''
// 连接以太坊主网
const providerETH = new ethers.providers.JsonRpcProvider(`https://mainnet.infura.io/v3/${INFURA_ID}`)
// 连接Goerli测试网
const providerGoerli = new ethers.providers.JsonRpcProvider(`https://goerli.infura.io/v3/${INFURA_ID}`)

4、利用Provider读取链上数据

Provider类封装了一些方法,可以便捷的读取链上数据:

1. 利用getBalance()函数读取主网和测试网V神的ETH余额:

    // 1. 查询vitalik在主网和Goerli测试网的ETH余额console.log("1. 查询vitalik在主网和Goerli测试网的ETH余额");const balance = await providerETH.getBalance(`vitalik.eth`);const balanceGoerli = await providerGoerli.getBalance(`vitalik.eth`);// 将余额输出在console(主网)console.log(`ETH Balance of vitalik: ${ethers.utils.formatEther(balance)} ETH`);// 输出Goerli测试网ETH余额console.log(`Goerli ETH Balance of vitalik: ${ethers.utils.formatEther(balanceGoerli)} ETH`);

V神余额

 2. 利用getNetwork()查询provider连接到了哪条链,homestead代表ETH主网:

  // 2. 查询provider连接到了哪条链console.log("\n2. 查询provider连接到了哪条链")const network = await providerETH.getNetwork();console.log(network);

getNetwork

 3. 利用getBlockNumber()查询当前区块高度:

    // 3. 查询区块高度console.log("\n3. 查询区块高度")const blockNumber = await providerETH.getBlockNumber();console.log(blockNumber);

getBlockNumber

 4. 利用getGasPrice()查询当前gas price,返回的数据格式为BigNumber,可以用BigNumber类的toNumber()toString()方法转换成数字和字符串。

    // 4. 查询当前gas priceconsole.log("\n4. 查询当前gas price")const gasPrice = await providerETH.getGasPrice();console.log(gasPrice);

getGasPrice

5. 利用getFeeData()查询当前建议的gas设置,返回的数据格式为BigNumber

    // 5. 查询当前建议的gas设置console.log("\n5. 查询当前建议的gas设置")const feeData = await providerETH.getFeeData();console.log(feeData);

getFeeData

6. 利用getBlock()查询区块信息,参数为要查询的区块高度:

    // 6. 查询区块信息console.log("\n6. 查询区块信息")const block = await providerETH.getBlock(0);console.log(block);

getBlock

 7. 利用getCode()查询某个地址的合约bytecode,参数为合约地址,下面例子中用的主网WETH的合约地址:

    // 7. 给定合约地址查询合约bytecode,例子用的WETH地址console.log("\n7. 给定合约地址查询合约bytecode,例子用的WETH地址")const code = await providerETH.getCode("0xc778417e063141139fce010982780140aa0cd5ab");console.log(code);

getCode

完整代码:

{/* <script src="https://cdn.ethers.io/lib/ethers-5.6.9.min.js"></script> */}
const ethers = require("ethers");
// import { ethers } from "ethers";
// import { ethers } from "https://cdn-cors.ethers.io/lib/ethers-5.6.9.esm.min.js";const INFURA_ID = '012dac20ba9f43c0ad4fd8be46ae2c37';const providerETH = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/012dac20ba9f43c0ad4fd8be46ae2c37');
const providerGeorli = new ethers.providers.JsonRpcProvider('https://goerli.infura.io/v3/012dac20ba9f43c0ad4fd8be46ae2c37');const main = async () => {//查询vitalik在主网和georli上的eth余额console.log('1、查询vitalik的ETH余额');const balanceETH = await providerETH.getBalance('vitalik.eth');const balanceGeorliETH = await providerGeorli.getBalance('vitalik.eth');console.log('ETH balance of vitalik:' + ethers.utils.formatEther(balanceETH) +'ETH' );console.log('GeorliETH balance of vitalik:' + ethers.utils.formatEther(balanceGeorliETH) + 'ETH');console.log('\n 2、查询现在是哪条链');const network = await providerETH.getNetwork();console.log(network);console.log('\n 3、查询当前区块高度');const blockNum = await providerETH.getBlockNumber();console.log(blockNum);console.log('\n 4、查询当前gasPrice');const gasPrice = (await providerETH.getGasPrice()).toString();console.log(gasPrice);console.log('\n5、查询当前区块信息');const blockInfo = await providerETH.getBlock(17969422);console.log(blockInfo);console.log('\n6、查询某个合约地址的代码字节码');const bytecode = await providerETH.getCode('0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984');console.log(bytecode);};main()

总结

ethers.js的Provider类,并用Infura的节点API Key创建了jsonRpcProvider,读取了ETH主网和Goerli测试网的链上信息。 

踩坑记录:

运行后仍然跟上一次一样报错:

import { ethers } from "https://cdn-cors.ethers.io/lib/ethers-5.6.9.esm.min.js";
^^^^^^SyntaxError: Cannot use import statement outside a moduleat internalCompileFunction (node:internal/vm:74:18)at wrapSafe (node:internal/modules/cjs/loader:1141:20)at Module._compile (node:internal/modules/cjs/loader:1182:27)at Module._extensions..js (node:internal/modules/cjs/loader:1272:10)at Module.load (node:internal/modules/cjs/loader:1081:32)at Module._load (node:internal/modules/cjs/loader:922:12)at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)at node:internal/main/run_main_module:23:47Node.js v18.13.0

原因是,在一个非模块化的环境中使用了ES6的 import 语句,导致了错误。代码运行在普通的JavaScript环境中,而不是模块化环境,您可以将 import 语句替换为传统的脚本引入方式。将以下代码:

import { ethers } from "ethers";

替换为:

const ethers = require("ethers");

另外再修改原来代码中的一些错误写法,比如少一个括号,把$去掉等。

就可以正常运行并得到结果:

ETH balance of vitalik:3933.795127185004997518ETH

2、报错:

const network = await ethers.providerETH.getNetwork(); ^ TypeError: Cannot read properties of undefined (reading 'getNetwork') 

 在const network = await ethers.providersETH.getNetwork();中语法错误,改为:

const network = await providersETH.getNetwork();
即可解决。

3、报错:

console.log('\n 4、查询当前gasPrice');const gasPrice = (await providerETH.getGasPrice()).toString;console.log(gasPrice);};


运行结果是:

[Function (anonymous)]

因为在代码中,toString我少写了一个括号,应该是:

    const gasPrice = (await providerETH.getGasPrice()).toString;

另外,有一次我的代码是:

console.log('\n 4、查询当前gasPrice');const gasPrice = await providerETH.getGasPrice().toString();console.log(gasPrice);};

运行得到的结果是:

undefined
原因是,const gasPrcie = await providerETH.getGasPrice().toString().要改为:
 

const gasPrcie = (await providers.getGasPrice()).toString();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/48769.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA免杀学习与实验

1 认识Webshell 创建一个JSP文件&#xff1a; <% page import"java.io.InputStream" %> <% page import"java.io.BufferedReader" %> <% page import"java.io.InputStreamReader" %> <% page language"java" p…

jmeter进行业务接口并发测试,但登录接口只执行一次

业务接口性能测试&#xff0c;往往都是需要登录&#xff0c;才能请求成功&#xff0c;通常只需要登录一次&#xff0c;再对业务接口多次并发测试。 在测试计划中&#xff0c;添加setUp线程组 把登录请求放入到该线程组中&#xff0c;设置HTTP信息头&#xff0c;JSON提取(提取登…

前端基础(ES6 模块化)

目录 前言 复习 ES6 模块化导出导入 解构赋值 导入js文件 export default 全局注册 局部注册 前言 前面学习了js&#xff0c;引入方式使用的是<script s"XXX.js">&#xff0c;今天来学习引入文件的其他方式&#xff0c;使用ES6 模块化编程&#xff0c;…

电路学习+硬件每日学习十个知识点(40)23.8.20 (希腊字母读音,阶跃信号和冲激信号的关系式,信号的波形变换,信号的基本运算,卷积积分,卷积和)

文章目录 1.信号具有时间特性和频率特性。2.模拟转数字&#xff0c;抽样、量化、编码3.阶跃信号和冲激信号4.信号的波形变换&#xff08;时移、折叠、尺度变换&#xff09;5.信号的基本运算&#xff08;加减、相乘、微分与积分、差分与累加&#xff09;5.1 相加减5.2 相乘5.3 微…

基础论文学习(1)——ViT

Vision Transformer&#xff08;ViT&#xff09; 模型架构是在 ICLR 2021 上作为会议论文发表的一篇研究论文中介绍的&#xff0c;题为“An Image is Worth 16*16 Words: Transformers for Image Recognition at Scale”。它由Neil Houlsby&#xff0c;Alexey Dosovitskiy和Goo…

springMVC之视图

文章目录 前言一、ThymeleafView二、转发视图三、重定向视图四、视图控制器view-controller五、补充总结 前言 SpringMVC中的视图是View接口&#xff0c;视图的作用渲染数据&#xff0c;将模型Model中的数据展示给用户。 SpringMVC视图的种类很多&#xff0c;默认有转发视图和…

vscode远程调试

安装ssh 在vscode扩展插件搜索remote-ssh安装 如果连接失败&#xff0c;出现 Resolver error: Error: XHR failedscode 报错&#xff0c;可以看这篇帖子vscode ssh: Resolver error: Error: XHR failedscode错误_阿伟跑呀的博客-CSDN博客 添加好后点击左上角的加号&#xff0…

【Python机器学习】实验16 卷积、下采样、经典卷积网络

文章目录 卷积、下采样、经典卷积网络1. 对图像进行卷积处理2. 池化3. VGGNET4. 采用预训练的Resnet实现猫狗识别 TensorFlow2.2基本应用5. 使用深度学习进行手写数字识别 卷积、下采样、经典卷积网络 1. 对图像进行卷积处理 import cv2 path data\instance\p67.jpg input_…

Linux 线程同步——条件变量

一、条件变量的概念 如果说互斥锁是用于同步线程对共享数据的访问的话&#xff0c;那么条件变量则是用于在线程之间同步共享数据的值。条件变量提供了一种线程间的通知机制&#xff1a;当某个共享数据达到某个值的时候&#xff0c;唤醒等待这个共享数据的线程。如下图所示&…

vue3中使用第三方插件mitt实现任意组件通讯

vue3中使用第三方插件mitt实现任意组件通讯 组件通讯是vue3组合式开发的核心之一&#xff0c;现在我在写代码时&#xff0c;一个组件的代码超过了200行&#xff0c;基本都会拆分组件。组件拆分后&#xff0c;组件之间的通讯就很重要&#xff0c;总结了一下&#xff0c;目前有这…

【SQL应知应会】索引(三)• MySQL版:聚簇索引与非聚簇索引;查看索引与删除索引;索引方法

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 本文收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习&#xff0c;有基础也有进阶&#xff0c;有MySQL也有Oracle 索引 • MySQL版 前言一、索引1.简介2.索引类型之逻…

【李沐】3.2线性回归从0开始实现

%matplotlib inline import random import torch from d2l import torch as d2l1、生成数据集&#xff1a; 看最后的效果&#xff0c;用正态分布弄了一些噪音 上面这个具体实现可以看书&#xff0c;又想了想还是上代码把&#xff1a; 按照上面生成噪声&#xff0c;其中最后那…

利用大模型反馈故障的解决方案

背景 观测云有两个错误巡检脚本&#xff0c;RUM 错误巡检和 APM 错误巡检&#xff0c;代码均开源。 错误巡检的主要目的是发现新出现的错误消息(error stack)&#xff0c;原有的巡检在上报了相应的事件报告后&#xff0c;只是定位了问题&#xff0c;并没有给出合适的解决方案。…

Pandas基础知识

文章目录 Pandas的数据结构Series --- 由数据和索引组成&#xff08;索引&#xff08;index&#xff09;在左&#xff0c;数据&#xff08;values&#xff09;在右&#xff09;DataFrame --- 索引包括行索引和列索引&#xff0c;每列数据可以是不同的类型 Pandas的索引操作 ---…

SpringMVC拦截器学习笔记

SpringMVC拦截器 拦截器知识 拦截器(Interceptor)用于对URL请求进行前置/后置过滤 Interceptor与Filter用途相似但实现方式不同 Interceptor底层就是基于Spring AOP面向切面编程实现 拦截器开发流程 Maven添加依赖包servlet-api <dependency><groupId>javax.se…

nginx代理webSocket链接,webSocket频繁断开重连

一、场景 1、使用nginx代理webSocket链接&#xff0c;消息发送和接收都是正常的&#xff0c;但webSocket链接会频繁断开重连 2、如果不使用nginx代理则一切正常 3、程序没有做webSocket心跳处理 如下图 二、nginx代理配置 upstream cloud_ass {#ip_hash;server 192.168.1.…

2023年国赛数学建模思路 - 案例:随机森林

文章目录 1 什么是随机森林&#xff1f;2 随机深林构造流程3 随机森林的优缺点3.1 优点3.2 缺点 4 随机深林算法实现 建模资料 ## 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 什么是随机森林&#xff…

从2023年世界机器人大会发现机器人新趋势

机器人零部件为何成2023年世界机器人大会关注热门&#xff1f; 在原先&#xff0c;机器人的三大核心零部件是控制系统中的控制器、驱动系统中的伺服电机和机械系统中的精密减速器。如今&#xff0c;机器人的主体框架结构已经落实&#xff0c;更多机器人已经开始深入到各类场景中…

Prompt本质解密及Evaluation实战(一)

一、基于evaluation的prompt使用解析 基于大模型的应用评估与传统应用程序的评估不太一样&#xff0c;特别是基于GPT系列或者生成式语言模型&#xff0c;因为模型生成的内容与传统意义上所说的内容或者标签不太一样。 以下是借用了ChatGPT官方的evaluation指南提出的对结果的具…

kali的一些使用和ms08-067、ms17-010漏洞

VM虚拟机-三种网络连接方式&#xff08;桥接、NAT、仅主机模式&#xff09; 虚拟机网络连接 一、Bridged&#xff08;桥接&#xff09; 二、NAT&#xff08;网络地址转换&#xff09; 三、Host-Only&#xff08;仅主机&#xff09; 在vmware软件中&#xff0c;选项栏的“编…