基于 ethers.js 的區塊鏈事件處理與錢包管理


幣圈工具箱 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…