币圈工具箱 bqbot.cn 月访问量达90whttps://bqbot.cn/jms.html (在线版地址)

Event事件

检索事件

const { ethers } = require("hardhat");
async function SearchEvent() {try {const provider = new ethers.JsonRpcProvider("http://127.0.0.1:8545");const signer = await provider.getSigner();const TokenAddress = "0xxxxx";//合约地址const TokenABI =[]//合约的abi;const TokenContract = new ethers.Contract(TokenAddress, TokenABI, signer);//创建合约//读取合约const name = await TokenContract.name();console.log("Contract Name:", name);const symbol = await TokenContract.symbol();console.log("Contract Symbol:", symbol);const totalSupply = await TokenContract.totalSupply();console.log("Total Supply:", totalSupply.toString());//合约转ethconst arr1="0xxxxxxxx"await TokenContract.transfer(arr1,10);//给arr1转10;const block = await provider.getBlockNumber()//得到当前blockconst transferEvents = await TokenContract.queryFilter('Transfer', block - x, block);//检索合约Transfer,从block - x,到block之间的解析事件console.log(`Transfer事件数量: ${transferEvents.length}`);//transferEvents是个数组,我们可以解析他的参数console.log(...transferEvents[0].args);//返回form,to ,value}catch (error) {console.error("Error:", error);}}

监听事件

//以上同上
TokenContract.on("Transfer", (from, to, value, event) => {console.log(`Transfer事件触发:`);console.log(`From: ${from}`);console.log(`To: ${to}`);console.log(`Value: ${value.toString()}`);console.log(` 从 ${from}=> 到 ${to} = ${value.toString()}`); console.log(`Event Details:`, event);   });

过滤事件

设置过滤规则:contract.filters.EVENT_NAME( ...args )说明:EVENT_NAME:过滤事件,...args:过滤规则

基础规则汇总

规则含义示例
null该位置不限制,匹配任意值contract.filters.Transfer(null, addr)
单个值必须完全匹配contract.filters.Transfer(addr)
数组至少匹配数组中任意一个值contract.filters.Transfer(null, [addr1, addr2])
以上代码如上
//设置规则
# 规则1
let addr1="0xf39Fd6e51aad88F6F4ce6axxxxxxx"
let addr2="0x70997970C51812dc3A010C7xxxxxx"
let addr3="0xb0997970C51812dcxxxxxxxxxxxxx"
let rule1 = TokenContract.filters.Transfer(addr1);//过滤来自`addr1`地址的`Transfer`事件
let rule2 = TokenContract.filters.Transfer(null,addr2);//过滤所有发给 addr2`地址的`Transfer`事件
let rule3 = TokenContract.filters.Transfer(addr1,addr2);//过滤所有从 `addr1`发给`addr2`的`Transfer`事件
let rule3 = TokenContract.filters.Transfer(addr1,addr2);//过滤所有从 `addr1`发给`addr2`的`Transfer`事件
let rule4 = TokenContract.filters.Transfer(null,[addr2,addr3]);//过滤所有发给 addr2`地址的或者addr3`的Transfer`事件
# 其他就是各种组合使用了
# 过滤使用
TokenContract.on(rule1, (res) => {console.log('---------监听开始过滤--------');console.log(`${res.args[0]} -> ${res.args[1]} ${res.args[2]}`)
})
# 其他同上 把过滤规则给监听事件即可

批量生成HD钱包

BIP汇总
BIP编号主要用途典型格式示例
BIP-32HD 钱包路径m/44'/0'/0'/0/0
BIP-39助记词生成种子12/24 个单词
BIP-44多币种路径m/44'/60'/0'/0/0
BIP-49隔离见证兼容地址m/49'/0'/0'/0/0
BIP-84原生隔离见证地址m/84'/0'/0'/0/0
BIP-173Bech32 地址编码bc1q...
BIP-350Taproot 地址编码bc1p...
以BIP-44为例代码实践
  • 助记词生成
 const mnemonic = ethers.Mnemonic.entropyToPhrase(ethers.randomBytes(32))
  • 创建HD基钱包
    BIP-44
    基路格式:"m / purpose' / coin_type' / account' / change"
    参数说明
    • m:主密钥(Master Key)
    • purpose':固定为 44'(表示遵循 BIP-44 多账户标准)
    • coin_type':币种标识(如 0' = BTC,60' = ETH,501' = SOL)详细可查看SLIP-44
    • account':账户编号(从 0' 开始)
    • change:比特币专用(0 = 外部地址,1 = 找零地址);其他链通常为 0
    • address_index:地址索引(从 0 开始)
 # BIP-44// 基路径:const basePath = "44'/60'/0'/0"# 生成第一对外的链接const baseWallet = ethers.HDNodeWallet.fromPhrase(mnemonic, basePath)
  • 批量生成
const WalletNumber = 10;//钱包数for (let i = 0; i < WalletNumber; i++) {let NewBaseWallet = baseWallet.derivePath(i.toString());console.log(`第${i+1}个钱包地址: ${baseWalletNew.address}`)wallets.push(baseWalletNew);//生成10个钱包}
console.log("钱包地址列表:", wallets.map(wallet => wallet.address));
  • 加密JSON保存
async function saveWalletJson() {const wallet = ethers.Wallet.fromPhrase(mnemonic);//助记词console.log("通过助记词创建钱包:")console.log(wallet)// 加密json用的密码,可以更改成别的const pwd = "XXXX";const json = await wallet.encrypt(pwd)console.log("钱包的加密json:")console.log(json)require("fs").writeFileSync("keystoreBatch.json", json);//在当前文件夹下生成一个 keystoreBatch.json文件}saveWalletJson();
  • 通过加密json读取钱包信息
async function ReadWalletJson() {
console.log("开始读取json文件");
const json=require("fs").readFileSync("keystoreBatch.json", "utf8");
const walletJson =await ethers.Wallet.fromEncryptedJson(json, "xxx");//生成json时设置的密码
console.log("Wallet from JSON:",walletJson);
console.log("Address:", walletJson.address);
console.log("Private Key:", walletJson.privateKey);
console.log("Mnemonic:", walletJson.mnemonic.phrase);
}
ReadWalletJson();

staticCall和callStatic:

名称所属模块作用返回值适用场景
staticCallethers.Contract 实例方法以 只读方式 调用合约函数,不修改状态函数返回值任何函数(读/写)
callStaticethers.Contract 实例方法(v6 新增)以 只读方式 调用合约函数,不修改状态函数返回值任何函数(读/写)
# 代码实例
# staticCall
const from="0xf39xxx"
const to="0x70xxx"
const result = await TokenContract.transfer.staticCall(to,10,{  // 可选 overridesfrom: from, // 指定调用者(模拟不同账户)});console.log('模拟结果:', result);
# callStatic
const result = await TokenContract.transfer.staticCall(to,10,{                 // 可选 overridesfrom: from, // 指定调用者(模拟不同账户)});console.log('模拟结果:', result);

callData

  • 接口abi:infce=new ethers.Interface(abi);//两者是一样的功能

  • callData:infce=TokenContract.interface;//两者是一样的功能

const provider = new ethers.JsonRpcProvider("http://127.0.0.1:8545");
const signer = await provider.getSigner();
const TokenAddress = "0xxxx";//合约地址
const TokenABI =[];//abi
const TokenContract = new ethers.Contract(TokenAddress, TokenABI, signer);
const param = TokenContract.interface.encodeFunctionData("balanceOf",["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"]);console.log("param:", param);const tx = {to: TokenAddress,data: param
}
// 发起交易,可读操作(view/pure)可以用 provider.call(tx)
const balanceWETH = await provider.call(tx)
console.log(`存款前WETH持仓: ${ethers.formatEther(balanceWETH)}\n`)

encodeFunctionData

const provider = new ethers.JsonRpcProvider("http://127.0.0.1:8545");
const signer = await provider.getSigner();
const TokenAddress = "0xxxxxxx";//合约地址
const TokenContract = new ethers.Contract(TokenAddress, TokenABI, signer);//构造合约
# 使用合约的transfer 向0x70997970C51812dc3A010C7d01b50e0d17dc79C8 转10n
const calldata = TokenContract.interface.encodeFunctionData('transfer', ['0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // 收款地址10n                                           // 转账数量 (BigInt)
]);
console.log(calldata)//生成callData
const wallet = new ethers.Wallet("钱包的私钥", provider);
const tx = await wallet.sendTransaction({to: "0x5Fxxxxxxx",//合约地址data: calldata,
});
await tx.wait();
console.log("交易成功生成的txHash:", tx.hash);
//通过交易hash 
//交易的详细信息
const hash = await provider.getTransaction(tx.hash);
//交易收据
const receipt = await provider.getTransactionReceipt(tx.hash);

识别ERC20、ERC721、ERC115标准合约

识别关键说明:所有现代标准(ERC721、ERC1155)都实现了 ERC165,通过 supportsInterface(bytes4 interfaceId) 函数声明支持的接口,ERC20 不支持 ERC165

  • ERC20

    说明:识别关键ERC20不是基于ERC165,但是ERC20包含totalSupply,识别关键通过totalSupply
    const provider = new ethers.JsonRpcProvider("http://127.0.0.1:8545");
    const signer = await provider.getSigner();//
    const TokenAddress = "0x5Fbxxxxx";//合约地址
    const TokenABI = []//abi
    const TokenContract = new ethers.Contract(TokenAddress, TokenABI, signer);//创建合约
    const totalSupplyValue=await TokenContract.totalSupply(); 
    console.log(totalSupplyValue)//说明是ERC20
    
  • ERC721

    说明:识别关键是ERC721基于ERC165,ERC165标准包含supportsInterface(bytes4 interfaceId)
     创建合约如上const isERC721 = await contract.supportsInterface("0x80ac58cd");console.log(isERC721); // true 或 false
    
  • ERC1155

    说明:识别关键是ERC721基于ERC165,ERC165标准包含supportsInterface(bytes4 interfaceId)
     创建合约如上const isERC721 = await contract.supportsInterface("0xd9b67a26");console.log(isERC721); // true 或 false
    
  • 总结

    调用函数/方法返回值识别结果备注
    supportsInterface(0x80ac58cd)trueERC721NFT 标准接口标识符
    supportsInterface(0xd9b67a26)trueERC1155多代币标准接口标识符
    totalSupply() 等函数调用成功成功ERC20同质化代币标准(无 ERC165)

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

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

相关文章

SpringBoot系列—入门

目录 1 第一个SpringBoot程序 1.1 创建SpringBoot项目 1.2 选择SpringBoot版本和必要依赖 1.3 项目目录结构 1.4 编写Hello World代码 1.5 运行程序 1.6 不需要IDEA也能创建SpringBoot程序 1.7 部署程序 1.8 pom.xml依赖问题 1.9 无Maven选项问题 1.10 SpringBoot版…

你的Prompt还有很大提升

与AI协作&#xff0c;Prompt&#xff08;提示词&#xff09;是沟通的桥梁。一个优秀的Prompt能让AI的输出事半功倍&#xff0c;而一个模糊的Prompt则可能导致南辕北辙的结果。如果你觉得AI的回答不够精准、缺乏深度&#xff0c;或者总带着一股“AI味”&#xff0c;那很可能是你…

3、Configuring Topics

如果您在应用程序上下文中定义了KafkaAdmin bean&#xff0c;它可以自动向代理添加主题。为此&#xff0c;您可以将每个主题的NewTopicBean添加到应用程序上下文中。2.3版本引入了一个新的类TopicBuilder&#xff0c;使创建此类bean更加方便。以下示例显示了如何执行此操作&…

FastAPI+React19开发ERP系统实战第04期

一、效果预览 1.1 首页 1.2 首页暗黑模式 1.3 登录页 1.4 登录页暗黑模式 二、搭建React开发环境 2.1 项目依赖 package.json {"name": "erp-web","version": "1.0.0","description": "ERP系统前端 - React 19&quo…

数据库|了解达梦数据库并做安装前的准备

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 你都用过哪些数据库&#xff1f; 使用过的数据库中觉得哪个数据库最好用&#xff1f; 你使用过达梦数据库吗&#xff1f; 最近在做的一个SCADA项目&#xff0c;要求信创版本&#xff0c;其中数据库也要使用信创目录…

Java驱动AI革命:Spring AI八篇进阶指南——从架构基础到企业级智能系统实战

系列文章目录 提示&#xff1a;下面列出了整个系列的完整目录&#xff0c;建议收藏本篇作为总览入口&#xff1a;本人将在7月份更新完毕 第一篇&#xff1a;Spring AI 概述与架构设计 第二篇&#xff1a;Spring AI 基本组件详解——ChatClient、Prompt、Memory 第三篇&#x…

hysAnalyser --- 支持菁彩视听双Vivid媒体信息解析

摘要 本文主要介绍 hysAnalyser 支持HDR Vivid格式的分析案例&#xff0c;满足用户分析HDR vivid 和 Audio Vivid格式的需要。 现将 hysAnalyser 新版本(v1.1.000)发布给网友使用&#xff0c;希望能帮助到更多音视频开发的爱好者。使用过程中&#xff0c;若遇到问题请您通过 G…

C++中NULL等于啥

文章目录 **一、`NULL` 的标准定义****二、常见实现方式**1. **定义为整数 `0`**2. **定义为 `0L` 或 `(void*)0`**(较少见)**三、与C语言的关键区别****四、`NULL` 在C++中的问题**1. **重载函数匹配歧义**2. **模板参数推导错误****五、C++11+ 的替代方案:`nullptr`****六…

pyhton基础【20】面向对象进阶一

目录 一.进阶 类方法和静态方法 属性(Properties) 继承和多态 抽象基类(Abstract Base Classes - ABCs) 魔术方法(Magic Methods) 组合和聚合 使用场景 二.私有属性 实现对数据的隐藏 设置私有属性 添加额外对属性操作的方法 三.私有方法 实现对方法的隐藏 直接…

渗透信息收集- Web应用漏洞与指纹信息收集以及情报收集

目录 1. 整体流程与目标概述 2. 常用工具及其用途 2.1 扫描与枚举工具 2.2 情报与数据聚合工具 2.3 流量拦截与手工验证工具 3. 详细技术手法与步骤 3.1 准备阶段 3.2 主动扫描与指纹识别 3.3 数据交叉验证与漏洞确认 3.4 进一步渗透与隐蔽操作 4. 实际工作经验与注…

ASP.NET代码审计 MVC架构 SQL注入漏洞n

接口路由 /Maintenance/GetMaintenanceList MaintenanceController.cs代码 Maintenance 控制器里面的 GetMaintenanceList 方法 接收参数 id 传进 MaintenanceManager.GetMaintenanceList 方法调用 MaintenanceManager.cs代码 这里 id 和 faultId 不一样是不影响的 C# 按顺序匹…

Python入门Day4

Python中数据的常用操作 数据拷贝 根据以下代码可以看出l1和l2实际上都是对于数据的引用&#xff0c;当l1被改变了&#xff0c;l2也会发生同样的改变&#xff0c;l2 l1只是将l2指向了l1所指向的地址。 >>> l1 [1,2,[3,4],[5,6]] >>> l2 l1 >>>…

计算机网络中的常用表项梳理

核心表项对比 表项 全称 工作层级 主要功能 涉及设备 典型生命周期 MAC表 媒体访问控制表 数据链路层&#xff08;二层&#xff09; Mac地址和端口关系 交换机、网桥 动态学习 FDB表 转发数据库 &#xff08;Forwarding DataBase&#xff09; 数据链路层&#xf…

百度轮岗:任命新CFO,崔珊珊退居业务二线

文 | 大力财经2025 年 7 月 1 日&#xff0c;百度组织再次变革&#xff0c;崔珊珊退居二线引发的行业关注。百度创始人李彦宏发布的内部信&#xff0c;宣布的新一轮组织调整里&#xff0c;崔珊珊退居二线这一变动&#xff0c;格外引人瞩目。崔珊珊&#xff0c;这位在百度人力资…

TAMPER-RTC(STM32F103) 引脚说明

我来查看ST官方手册中关于TAMPER-RTC引脚的具体说明。 Ran tool Ran tool Ran tool Read file: doc/STM32F103VGT6/STM32F103VGT6_specification.txt Read file: doc/STM32F103VGT6/STM32F103VGT6_specification.txt Ran tool Read file: doc/STM32F103VGT6/STM32F103VGT6_spec…

BUUCTF在线评测-练习场-WebCTF习题[极客大挑战 2019]HardSQL1-flag获取、解析

解题思路 打开靶场、熟悉的感觉 上次是过滤了很多字符&#xff0c;用了双写绕过进行注入即可&#xff0c;这次进阶了难度 先老规矩判断下闭合 11 123 报错提示 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version…

MyBatis动态SQL进阶:复杂查询与性能优化实战

引言 在复杂业务场景中&#xff0c;SQL查询往往需要动态拼接条件、复用代码片段&#xff0c;并支持批量操作。MyBatis的动态SQL功能提供了强大的解决方案&#xff0c;本文将深入解析<choose>条件分支、<sql>片段复用、批量操作优化等核心技巧&#xff0c;助你写出高…

@Transactional 注解失效的场景及原因分析

先分析一下 1&#xff0c;内部调用&#xff0c;原对象调用&#xff0c;不是代理对象调用 2&#xff0c;private方法&#xff0c;源码中&#xff0c;只能是public方法 3&#xff0c;异常被捕获了&#xff0c;事物拦截器&#xff0c;无法感知 4&#xff0c;子线程调用&#x…

使用unity创建项目,进行动画制作

1. 创建unity项目 error: error CS0006: Metadata file Library/PackageCache/com.unity.collab-proxy2.8.2/Lib/Editor/PlasticSCM/log4netPlastic.dll could not be found error CS0006: Metadata file Library/PackageCache/com.unity.collab-proxy2.8.2/Lib/Editor/Plasti…

Centos系统及国产麒麟系统设置自己写的go服务的开机启动项完整教程

1、创建服务文件 在 /etc/systemd/system/ 下新建服务配置文件&#xff08;需sudo权限&#xff09;&#xff0c;例如&#xff1a; sudo nano /etc/systemd/system/mygo.service 如下图&#xff0c;创建的mygo.service 2、创建内容如下&#xff1a; DescriptionThe go HTTP a…