WEB3全棧開發——面試專業技能點P1Node.js / Web3.js / Ethers.js

一、Node.js 事件循環

Node.js 的事件循環(Event Loop)是其異步編程的核心機制,它使得 Node.js 可以在單線程中實現非阻塞 I/O 操作


🔁 簡要原理

Node.js 是基于 libuv 實現的,它使用事件循環來處理非阻塞操作。事件循環的主要作用是:

不斷檢查任務隊列(如回調、I/O、定時器),并按階段執行回調。


📊 事件循環的幾個階段

  1. timers:執行 setTimeoutsetInterval 的回調。

  2. pending callbacks:執行 I/O 操作失敗的回調(如錯誤處理)。

  3. idle, prepare:內部使用。

  4. poll:等待新的 I/O 事件,如文件讀寫。

  5. check:執行 setImmediate() 的回調。

  6. close callbacks:如 socket.on('close', ...)


🧪 示例代碼:事件循環的順序

setTimeout(() => {console.log('setTimeout');
}, 0);setImmediate(() => {console.log('setImmediate');
});Promise.resolve().then(() => {console.log('Promise');
});process.nextTick(() => {console.log('nextTick');
});

🧾 輸出順序可能是:

nextTick
Promise
setTimeout
setImmediate

? 原因:

  • process.nextTick()Promise.then() 是微任務(microtask),優先執行

  • setTimeoutsetImmediate 是宏任務(macrotask),排在后面。


📘 應用場景

  • 高并發服務器(如 HTTP 服務器)

  • 異步數據庫訪問

  • 異步文件 I/O 操作

  • 消息隊列處理


🎯 總結

特性描述
單線程Node.js 本身是單線程的
非阻塞 I/O借助事件循環與回調實現并發處理
微任務優先nextTick > Promise > setTimeout

一、瀏覽器事件循環和 Node.js 的區別

瀏覽器和 Node.js 都使用事件循環(Event Loop)來處理異步任務,但由于運行環境不同,它們的事件循環機制在架構設計、宏任務與微任務處理、任務來源和模塊支持等方面存在明顯差異。


🌐 一、瀏覽器事件循環機制

瀏覽器的事件循環遵循 HTML5 標準,基本結構如下:

1. 執行順序

  1. 同步任務(調用棧)

  2. 微任務隊列(Microtasks):如 Promise.thenMutationObserver

  3. 宏任務隊列(Macrotasks):如 setTimeoutsetIntervalrequestAnimationFrame

2. 典型任務來源

任務類型示例
宏任務setTimeoutsetIntervalmessageUI 渲染XHR onload
微任務Promise.thenqueueMicrotaskMutationObserver

3. 特點

  • 每執行一個宏任務,立即清空所有微任務。

  • 瀏覽器事件循環中含有 UI 渲染階段,微任務清空后才允許渲染。


?? 二、Node.js 的事件循環機制

Node.js 基于 libuv 庫實現自己的事件循環,主要包含 6 個階段,不完全等同于瀏覽器模型。

1. Node.js 事件循環階段

  1. timers:處理 setTimeoutsetInterval

  2. pending callbacks:處理某些 I/O 的回調

  3. idle, prepare:僅內部使用

  4. poll:檢索 I/O 事件

  5. check:處理 setImmediate

  6. close callbacks:處理 close 事件,如 socket.on('close')

每個階段之間都會執行微任務隊列。

2. 微任務來源

  • process.nextTick()(優先級最高,不屬于微任務隊列,是獨立隊列

  • Promise.then()(真正的微任務)

3. 特點

  • process.nextTickPromise.then 更早執行。

  • 沒有 UI 渲染階段(非瀏覽器)。

  • setImmediatesetTimeout(..., 0) 行為不同。


🔍 三、主要區別對比

項目瀏覽器Node.js
環境有 UI 渲染無 UI 渲染
宏任務示例setTimeout, setIntervalsetTimeout, setImmediate
微任務隊列Promise, MutationObserverPromise, process.nextTick(優先)
微任務執行時機每個宏任務后執行所有微任務每個階段后執行所有微任務(先執行 nextTick
特殊隊列nextTickprocess.nextTick 隊列優先于微任務
底層實現瀏覽器廠商自研libuv 實現多平臺 I/O


? 總結記憶口訣

瀏覽器關注 UI,先宏后微;Node 有 Tick,分階段處理。

二、Node.js異步編程

下面是關于 Node.js 中異步編程的兩種主要方式 —— Promiseasync/await 的示例與解釋:


一、Promise 示例與解釋

function fetchData() {return new Promise((resolve, reject) => {setTimeout(() => {const success = true;if (success) {resolve("數據加載成功");} else {reject("數據加載失敗");}}, 1000);});
}fetchData().then(data => {console.log(data); // 輸出:數據加載成功}).catch(error => {console.error(error);});
? 說明:
  • Promise 表示一個異步操作的最終完成(或失敗)及其結果值。

  • .then() 處理成功,.catch() 處理錯誤。

  • 適合鏈式調用多個異步任務。


二、async/await 示例與解釋

function fetchData() {return new Promise((resolve) => {setTimeout(() => {resolve("數據加載成功");}, 1000);});
}async function getData() {try {const result = await fetchData();console.log(result); // 輸出:數據加載成功} catch (error) {console.error(error);}
}getData();
? 說明:
  • async 表示函數內部可能存在異步操作。

  • await 表示等待 Promise 處理完成,簡化回調地獄。

  • 語法更接近同步邏輯,可讀性好,推薦使用。


如需講解 回調函數 → Promise → async/await 的演進過程或應用在實際項目場景里,我也可以繼續補充。

三、libuv 工作機制

libuv 是 Node.js 底層的核心庫之一,負責 跨平臺的異步 I/O 操作。理解 libuv 的工作機制,有助于深入掌握 Node.js 的高性能和事件驅動模型。


? libuv 是什么?

libuv 是一個用 C 編寫的跨平臺異步 I/O 庫,為 Node.js 提供以下能力:

  • 事件循環(Event Loop)

  • 異步文件系統操作

  • 網絡通信(TCP、UDP)

  • 子進程管理

  • 定時器(Timers)

  • DNS 查詢

  • 線程池


🔄 libuv 的工作機制(核心組成)

1. Event Loop 事件循環

libuv 實現了事件循環的機制,管理所有異步任務的執行時機。

2. 任務隊列分階段處理

libuv 的事件循環大致如下(簡化版本):

while (循環運行中) {處理 timers 階段(如 setTimeout、setInterval)處理 I/O callbacks(異步操作的回調)處理 idle, prepare 回調處理 poll 階段(處理新的 I/O 事件)處理 check 階段(setImmediate)處理 close callbacks(如 socket關閉)執行 microtask(如 Promise.then) → V8 控制
}
3. 線程池(Thread Pool)

對于 CPU 密集型或無法異步的操作(如 fs.readFile),libuv 使用線程池異步執行:

  • 默認線程數:4

  • 可以通過 UV_THREADPOOL_SIZE 環境變量配置


📌 舉例說明(libuv 在線程池中運行 I/O):

const fs = require('fs');fs.readFile('example.txt', 'utf8', (err, data) => {console.log('文件內容:', data);
});

此處 readFile 實際由 libuv 在線程池中執行,不阻塞主線程,執行完回調被加入事件循環隊列。


📊 總結圖示(流程簡化)

JS 調用異步API(如 fs.readFile)↓
libuv 將其交由線程池處理↓
任務完成后,結果回調加入 Event Loop 的隊列↓
Event Loop 執行回調函數

如果你需要一張完整的圖示來可視化這個執行流程,我可以畫圖說明(更詳細展示與 V8、線程池、事件循環的協作)。是否需要?

四、Cluster 實現多進程

1. 概念

Node.js 是單線程運行的,但它的底層 libuv 使用線程池處理異步 I/O。單線程模型對 I/O 密集型應用非常高效,但在 CPU 密集型任務或者需要利用多核 CPU 的場景下,單線程的限制就明顯了。

Cluster 模塊允許你創建多個 Node.js 進程(worker),這些進程共享同一個服務器端口,從而實現多核 CPU 的并行利用。每個 worker 進程是 Node.js 的一個單獨實例,擁有自己的事件循環。

這樣,Cluster 能讓你充分利用多核 CPU,提升 Node.js 應用的性能和吞吐量。


2. 代碼示例

下面是一個使用 Cluster 的簡單示例,創建多個 worker,監聽同一個端口:

const cluster = require('cluster');
const http = require('http');
const os = require('os');if (cluster.isMaster) {// 獲取CPU核心數const cpuCount = os.cpus().length;console.log(`主進程 ${process.pid} 正在運行`);console.log(`啟動 ${cpuCount} 個 worker`);// Fork 子進程for (let i = 0; i < cpuCount; i++) {cluster.fork();}// 監聽 worker 退出事件cluster.on('exit', (worker, code, signal) => {console.log(`worker ${worker.process.pid} 已退出,啟動新的 worker`);cluster.fork();});
} else {// Worker 進程運行 HTTP 服務器http.createServer((req, res) => {res.writeHead(200);res.end(`由進程 ${process.pid} 處理請求\n`);}).listen(8000);console.log(`worker ${process.pid} 啟動`);
}

3. 講解

  • cluster.isMaster 判斷當前進程是不是主進程。

  • 主進程會根據 CPU 核數 fork 出對應數量的 worker 進程。

  • 每個 worker 進程都執行同樣的代碼,但 cluster.isMaster 為 false,啟動一個 HTTP 服務器監聽同一端口。

  • Node.js Cluster 模塊內部會將進入的請求分發給不同的 worker,負載均衡處理。

  • 當某個 worker 進程退出時,主進程捕獲 exit 事件,自動重啟一個新的 worker,保證服務穩定。

  • 每個 worker 進程擁有自己的進程 ID (process.pid),方便區分請求是由哪個進程處理。


4. 總結

  • Cluster 允許 Node.js 程序多進程運行,充分利用多核 CPU。

  • 主進程負責管理 worker 進程的生命周期。

  • Worker 進程獨立運行同樣的服務器代碼,監聽同一個端口。

  • 請求會被均衡分發到不同的 worker,提高并發處理能力。

  • 適合 CPU 密集型或高并發的 Node.js 服務。


如果需要,我還可以幫你寫更完整的示例,或者介紹更高級的用法,比如 IPC 通信,歡迎告訴我!

五、V8 引擎原理

1. 概念

V8 引擎是 Google 開發的開源 JavaScript 引擎,主要用于 Chrome 瀏覽器和 Node.js 環境。它負責將 JavaScript 代碼編譯、優化并執行,極大提升了 JavaScript 的運行效率。

V8 的核心特點包括:

  • 即時編譯(JIT):將 JavaScript 代碼即時編譯成機器碼,而非先解釋執行,提高性能。

  • 隱藏類(Hidden Classes)和內聯緩存(Inline Caches):優化對象屬性訪問,減少動態查找的開銷。

  • 垃圾回收(Garbage Collection):自動管理內存,回收不再使用的對象。

  • 多階段編譯:先快速生成初步代碼,再逐漸優化熱代碼。


2. V8 執行流程簡述

  1. 解析階段:V8 把 JavaScript 源代碼解析成抽象語法樹(AST)。

  2. 編譯階段:使用 Ignition 解釋器將 AST 轉換成字節碼(intermediate representation)。

  3. 執行階段:解釋字節碼運行程序,同時收集熱點代碼信息。

  4. 優化階段:HotSpot 優化編譯器將熱點字節碼編譯為高效的機器碼。

  5. 垃圾回收:定期回收無用對象釋放內存。


3. 代碼示例

V8 是底層引擎,運行時隱藏在 Node.js 或 Chrome 里。下面是一個用 Node.js 運行 JavaScript 的簡單示例,展示 V8 執行 JavaScript:

// demo.js
function fibonacci(n) {if (n <= 1) return n;return fibonacci(n - 1) + fibonacci(n - 2);
}console.log(fibonacci(10));

執行:

node demo.js

背后 V8 會:

  • 將這個函數編譯成字節碼。

  • 解釋執行,識別熱點函數(遞歸調用頻繁)。

  • 對該函數進行優化編譯,生成高效機器碼。

  • 最終輸出結果。


4. 講解

  • V8不是簡單的解釋器,它通過多階段編譯和優化,極大提升 JS 代碼性能。

  • 傳統的 JS 解釋器逐行執行代碼,而 V8 首先把代碼編譯成字節碼,運行更快。

  • 在運行過程中,V8 會分析哪些代碼“熱”(被頻繁執行),并通過優化編譯器將其轉換成原生機器碼,提高執行速度。

  • 隱藏類和內聯緩存是 V8 優化對象訪問的關鍵技術,類似于為 JS 對象動態生成“類”,快速定位屬性。

  • V8 使用分代垃圾回收,比如新生代和老生代,來高效管理內存,減少停頓時間。


如果你想,我還能幫你梳理 V8 的內存分配、垃圾回收機制,或者介紹 Node.js 如何通過 V8 實現高性能,隨時告訴我!

六、V8 引擎內存分配與垃圾回收機制

1. 概念

V8 引擎內存分配

V8 引擎在執行 JavaScript 代碼時,需要在內存中為對象、函數、變量等分配空間。它將內存劃分為不同的區域,主要包括:

  • 新生代(Young Generation):存放新創建的對象,分配速度快,采用 Scavenge 算法進行垃圾回收。

  • 老生代(Old Generation):存放經過多次垃圾回收仍存活的長生命周期對象,采用標記-清除(Mark-Sweep)和標記-整理(Mark-Compact)算法回收。

  • 代碼區(Code Space):存放編譯后的機器碼。

  • 大對象空間(Large Object Space):存放特別大的對象,避免影響新生代和老生代的內存管理。

垃圾回收機制

V8 使用自動垃圾回收,自動管理內存,釋放不再被引用的對象。其核心算法包括:

  • Scavenge(新生代回收):采用復制算法,將存活對象從一塊內存區復制到另一塊,快速清理內存。

  • 標記-清除(Mark-Sweep):標記所有存活對象,清除未標記對象。

  • 標記-整理(Mark-Compact):類似標記-清除,但會整理存活對象,避免內存碎片。

垃圾回收器根據對象的生命周期自動將其從新生代晉升到老生代,提高回收效率。


2. 代碼示例

V8 的內存分配和垃圾回收是引擎內部行為,普通 JavaScript 代碼無法直接控制,但可以通過編寫大量對象生成與銷毀來觀察其效果。

示例:大量創建對象模擬內存使用

function createObjects() {let arr = [];for (let i = 0; i < 1000000; i++) {arr.push({ index: i, time: Date.now() });}return arr;
}let objects = createObjects();// 模擬釋放內存
setTimeout(() => {objects = null;  // 解除引用,等待垃圾回收console.log('Objects dereferenced, eligible for GC');
}, 5000);

運行這段代碼時,V8 會為 arr 分配大量內存。當 objects = null 后,數組及其包含的對象失去引用,V8 垃圾回收器會在合適時間回收這部分內存。


3. 講解

  • 新生代和老生代的設計是基于**大部分對象“朝生暮死”**的經驗:新創建的對象大多數生命周期短暫,快速回收;存活較久的對象才進入老生代。

  • Scavenge 復制算法效率高,適合快速回收新生代內存,避免內存碎片。

  • 老生代垃圾回收用 標記-清除標記-整理算法,后者減少碎片,保證大塊內存連續,方便長壽命對象管理。

  • 代碼區內存存放編譯后的機器碼,方便函數和代碼快速執行。

  • 大對象空間獨立分配,避免影響普通對象的內存回收策略。

  • JavaScript 代碼中不能直接手動觸發垃圾回收,但通過釋放對象引用(如賦值 null),讓垃圾回收器能回收無用內存。

  • V8 的垃圾回收是并發和增量式,盡量減少程序停頓,提高響應性能。


如果你想深入了解 V8 垃圾回收的算法細節、如何通過 --trace_gc 等命令行參數查看垃圾回收日志,我也可以幫你寫具體說明!

七、V8 引擎定位性能瓶頸

1. 概念

V8 引擎在執行 JavaScript 代碼時,通過多種機制定位和優化性能瓶頸,以提升代碼執行效率。主要包括:

  • 內置性能分析工具:V8 支持采樣 CPU 和內存使用情況,幫助開發者找出代碼熱點(hot spots)。

  • 優化編譯器(TurboFan):通過收集運行時信息,動態編譯熱點代碼成機器碼,提高性能。

  • 內聯緩存(Inline Cache):加速屬性訪問,減少查找時間。

  • 性能剖析(Profiler):V8 可以生成性能分析數據,用于發現執行瓶頸。

通過這些手段,V8 能自動發現“慢代碼”,并對其進行重點優化。


2. 代碼示例

JavaScript 代碼本身不直接控制 V8 的性能分析,但可以利用 Node.js 提供的性能工具,比如 --prof 選項開啟 V8 性能分析。

示例:使用 Node.js 運行腳本并生成性能日志

node --prof demo.js

假設 demo.js 內容:

function slowFunction() {let sum = 0;for (let i = 0; i < 1e7; i++) {sum += i;}return sum;
}console.log(slowFunction());

運行后,會生成 isolate-0x...-v8.log 文件,使用 node --prof-process 解析:

node --prof-process isolate-0x...-v8.log > processed.txt

processed.txt 會包含函數執行時間、調用次數等性能數據,幫助定位性能瓶頸。


3. 講解

  • V8 的性能優化基于采樣分析,它不記錄所有細節,而是定時采樣調用棧,減少性能開銷。

  • 通過 --prof,V8 記錄運行時的函數調用和時間分布,開發者可以找出耗時多的函數。

  • V8 識別“熱點代碼”,使用 TurboFan 優化編譯器將其轉為高效機器碼。

  • 內聯緩存減少了屬性訪問的動態查找,是提升代碼訪問性能的關鍵。

  • 在 Node.js 或 Chrome 開發者工具中,也能結合 V8 采集的性能數據,直觀查看代碼瓶頸。

  • 通過定位性能瓶頸,開發者可以優化算法、減少不必要的循環、避免低效操作,從而提升整體性能。


如果你需要,我可以幫你寫更詳細的性能分析步驟,或者示范如何結合 Chrome DevTools 使用 V8 Profiler。

八、Web3.js使用手冊在哪里看

1. 概念

Web3.js 的官方使用手冊(文檔)是學習和掌握該庫的最佳途徑。它詳細介紹了 Web3.js 的安裝、API 結構、常用功能、示例代碼和進階用法,幫助開發者快速上手與以太坊區塊鏈交互。


2. 官方文檔地址

Web3.js 官方文檔網址:

  • web3.js - Ethereum JavaScript API — web3.js 1.0.0 documentation

這里你可以找到:

  • 安裝和快速開始教程

  • 主要模塊和類的 API 說明(如 web3.ethweb3.utils

  • 示例代碼和使用指南

  • 常見問題和社區鏈接


3. 如何查閱使用手冊

  1. 首頁快速入門
    先瀏覽 “Getting Started” 或 “Quick Start” 部分,了解如何安裝 Web3.js 以及基本連接。

  2. 模塊導航
    文檔頁面左側有目錄,按模塊分類,比如:

    • web3.eth:以太坊核心 API,如賬戶、交易、合約等。

    • web3.utils:工具函數,如單位轉換、哈希計算。

    • web3.shh:點對點消息。

    • web3.net:網絡相關接口。

  3. 查找具體 API
    搜索你想用的功能,比如 “getBalance”、“sendTransaction”,查看參數、返回值和示例。

  4. 示例代碼
    結合文檔里的示例代碼,實際寫代碼測試,幫助理解。

  5. 版本對應
    注意文檔版本對應你使用的 Web3.js 版本,避免接口不兼容。


4. 額外資源

  • GitHub 主頁:https://github.com/ChainSafe/web3.js

  • 官方示例:https://github.com/ChainSafe/web3.js/tree/1.x/examples

  • 社區論壇和問答(如 Stack Overflow)

八、Web3.js與以太坊等區塊鏈交互

1. 概念

Web3.js 是一個 JavaScript 庫,用于與以太坊區塊鏈進行交互。它封裝了以太坊的 JSON-RPC 接口,使開發者能夠輕松調用智能合約、發送交易、查詢賬戶余額等操作。

通過 Web3.js,前端或后端應用可以:

  • 連接以太坊節點(如 Infura、Alchemy 或本地節點)

  • 讀取鏈上數據(賬戶信息、合約狀態)

  • 發送交易(轉賬、調用合約方法)

  • 監聽鏈上事件


2. 代碼示例

以下是一個使用 Web3.js 連接以太坊節點、查詢賬戶余額的示例:

const Web3 = require('web3');// 連接到以太坊節點(這里用Infura的主網節點)
const web3 = new Web3('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID');async function getBalance(address) {try {const balanceWei = await web3.eth.getBalance(address);const balanceEth = web3.utils.fromWei(balanceWei, 'ether');console.log(`賬戶 ${address} 余額: ${balanceEth} ETH`);} catch (err) {console.error('查詢余額出錯:', err);}
}const address = '0x742d35Cc6634C0532925a3b844Bc454e4438f44e'; // 示例地址
getBalance(address);

3. 智能合約交互示例

假設你有一個已部署的智能合約地址和ABI,調用合約的只讀方法:

const contractABI = [ /* 合約ABI數組 */ ];
const contractAddress = '0xYourContractAddressHere';const contract = new web3.eth.Contract(contractABI, contractAddress);async function callContractMethod() {try {const result = await contract.methods.yourMethodName().call();console.log('調用結果:', result);} catch (err) {console.error('調用合約方法失敗:', err);}
}callContractMethod();

4. 講解

  • 連接節點:Web3.js 需要連接一個以太坊節點,可以是遠程公共節點(Infura、Alchemy)或者本地節點。

  • 賬戶余額查詢:通過 web3.eth.getBalance 查詢某地址的以太幣余額,返回單位為 Wei(以太坊最小單位),通常用 web3.utils.fromWei 轉換成人類易讀的 Ether。

  • 智能合約交互:通過合約的 ABI 和地址實例化 web3.eth.Contract,調用 methods 中定義的函數。

    • .call() 用于只讀調用,不消耗 Gas,不產生交易。

    • .send() 用于狀態更改調用,需要簽名并消耗 Gas。

  • 交易發送:通過 web3.eth.sendTransactioncontract.methods.methodName().send() 發送交易,通常需要私鑰或錢包簽名。

  • 事件監聽:Web3.js 支持監聽智能合約事件,方便前端實時響應鏈上變化。


如果你想,我還可以幫你寫完整的發送交易示例、錢包集成示例,或者講解 Web3.js 的更多高級用法。

九、Ethers.js 在哪里看使用手冊,是干嘛的

1. 概念

Ethers.js 的使用手冊(官方文檔)是學習和掌握這個庫的核心資源,提供詳細的 API 說明、安裝指南、示例代碼和進階用法。它幫助開發者理解如何用 Ethers.js 與以太坊區塊鏈交互,比如連接節點、查詢余額、調用合約、發送交易等。


2. 官方文檔地址

Ethers.js 官方文檔網址是:

  • https://docs.ethers.io/

這是 Ethers.js 官方維護的文檔,內容覆蓋:

  • 快速開始

  • 核心模塊(Provider、Wallet、Contract 等)

  • API 詳細說明

  • 常用工具函數

  • 進階主題(事件監聽、合約工廠、ENS 等)


3. 如何使用手冊

  1. 首頁快速開始
    了解安裝和基礎用法,快速寫出第一個查詢余額或調用合約的代碼。

  2. 模塊分類導航
    根據功能查找對應模塊的使用方法,例如查 Provider 如何連接節點,查 Wallet 如何管理私鑰。

  3. API 參考
    查看每個類和方法的參數、返回值和示例,便于正確調用。

  4. 示例代碼
    文檔中大量示例,方便模仿和調試。

  5. 版本匹配
    確保文檔版本和你項目中安裝的 Ethers.js 版本一致。


4. 額外資源

  • GitHub 倉庫:https://github.com/ethers-io/ethers.js

  • 社區問答(Stack Overflow)

  • 教程視頻和博客

九、Ethers.js 與以太坊等區塊鏈交互

1. 概念

Ethers.js 是一個輕量級的 JavaScript 庫,用于與以太坊區塊鏈交互。它功能類似于 Web3.js,但設計更加模塊化和簡潔,且更注重安全性和易用性。

Ethers.js 支持:

  • 連接以太坊節點(本地或遠程,如 Infura)

  • 查詢賬戶余額和鏈上數據

  • 構造、簽名和發送交易

  • 與智能合約進行交互

  • 事件監聽和解析

  • 錢包管理(私鑰、助記詞)


2. 代碼示例

安裝 Ethers.js

npm install ethers

查詢賬戶余額示例

const { ethers } = require('ethers');// 連接到以太坊主網節點
const provider = new ethers.providers.InfuraProvider('mainnet', 'YOUR_INFURA_PROJECT_ID');async function getBalance(address) {const balance = await provider.getBalance(address);console.log(`賬戶余額: ${ethers.utils.formatEther(balance)} ETH`);
}const address = '0x742d35Cc6634C0532925a3b844Bc454e4438f44e';
getBalance(address);

調用智能合約只讀方法示例

const contractABI = [ /* 合約 ABI 數組 */ ];
const contractAddress = '0xYourContractAddressHere';const contract = new ethers.Contract(contractAddress, contractABI, provider);async function callContractMethod() {try {const result = await contract.yourMethodName();console.log('調用結果:', result);} catch (err) {console.error('調用合約方法失敗:', err);}
}callContractMethod();

3. 講解

  • Provider(提供者):Ethers.js 使用 Provider 對象連接以太坊節點,用于讀取區塊鏈數據(余額、交易、合約狀態)。支持多種類型節點,如 JSON-RPC、Infura、Alchemy 等。

  • Wallet(錢包):管理私鑰和簽名交易,支持從助記詞、私鑰或硬件錢包創建。

  • Contract(合約):實例化合約后,可以調用智能合約中的函數,call 方法用于只讀調用,send(需要 Wallet 簽名)用于發送交易。

  • 工具函數:Ethers.js 包含很多實用工具,如單位轉換(Wei 和 Ether)、哈希計算、編碼解碼等。

  • Ethers.js API 設計更現代、易用,類型定義完善,適合 TypeScript 開發。

  • 它更注重安全性,默認不會暴露用戶私鑰,必須顯式創建 Wallet 進行簽名。


如果需要,我也可以幫你寫發送交易、事件監聽等更復雜的示例,或者給你對比 Web3.js 和 Ethers.js 的優缺點。

十、Web3.js和Ethers.js區別,各自的作用

Web3.js和Ethers.js一般來說只用其中一個庫就夠了,因為 Web3.js 和 Ethers.js 都能完成和以太坊區塊鏈的主要交互功能,比如:

  • 查詢余額

  • 發送交易

  • 調用智能合約

  • 監聽事件

它們功能大部分重疊,沒必要同時用兩個,避免增加項目復雜度和包體積。


選哪個合適?

  • 想用更輕量、現代、TypeScript 支持好、錢包管理方便,建議選 Ethers.js

  • 需要兼容老項目或已有依賴,或者用的生態比較多是 Web3.js,就用 Web3.js


如果你只做一個項目,學會用一個庫就足夠高效,沒必要混著用。

1. Web3.js 和 Ethers.js 的區別及作用概述

特性/方面Web3.jsEthers.js
定位和設計以太坊官方較早的 JS 庫,功能全面但較龐大輕量級、模塊化設計,更加現代和易用
體積大小較大,功能豐富但包體積較重更小,適合前端項目,對資源有限環境友好
API 風格API 設計相對復雜,有些冗余API 更簡潔,鏈式調用方便,類型定義更好(TS 友好)
錢包支持通常與外部錢包配合使用,錢包管理較弱內置 Wallet 支持,私鑰、助記詞管理方便
社區支持與生態更成熟,很多教程和項目使用發展迅速,社區活躍,越來越多項目青睞
功能覆蓋功能全面,涵蓋所有鏈交互需求功能齊全但更注重核心,擴展性好
文檔和易用性文檔較豐富,但入門門檻稍高文檔結構清晰,示例豐富,更容易上手
事件監聽支持事件監聽,使用起來稍復雜事件監聽使用簡潔,支持過濾器
性能和穩定性穩定性好,廣泛使用,但有些接口較舊性能優化好,設計現代,支持最新以太坊特性


2. 各自作用

Web3.js

  • 主要用于和以太坊區塊鏈進行交互,功能涵蓋賬戶管理、交易、智能合約調用、事件監聽等。

  • 適合需要全面功能,已有成熟項目或依賴 Web3.js 生態的開發者。

  • 常用于 DApp 前端與以太坊節點通信。

Ethers.js

  • 設計更輕量且模塊化,強調安全和易用,支持錢包管理(私鑰、助記詞)。

  • 適合希望代碼體積小、使用現代 JS/TS 特性、方便錢包集成的項目。

  • 也適合后端腳本和服務,提供簡潔且強大的鏈交互能力。


3. 總結建議

  • 如果你是新項目,注重代碼質量和易用性,推薦用 Ethers.js

  • 如果需要兼容大量現有教程或項目,或者使用的庫/框架依賴 Web3.js,則用 Web3.js


需要的話,我可以幫你寫一份兩者的對比示例代碼,或者幫你快速上手其中任意一個。

十一、賬戶管理(Account Management)

功能點:

  • 創建賬號

  • 從私鑰導入

  • 查詢余額

Web3.js 示例:

const Web3 = require('web3');
const web3 = new Web3('https://mainnet.infura.io/v3/你的API_KEY');// 創建新賬戶
const newAccount = web3.eth.accounts.create();
console.log(newAccount);// 從私鑰導入
const account = web3.eth.accounts.privateKeyToAccount('0x你的私鑰');
console.log(account.address);// 查詢余額
web3.eth.getBalance(account.address).then(balance => {console.log('ETH余額:', web3.utils.fromWei(balance, 'ether'));
});

Ethers.js 示例:

import { ethers } from 'ethers';const provider = new ethers.InfuraProvider('mainnet', '你的API_KEY');// 創建錢包
const wallet = ethers.Wallet.createRandom();
console.log(wallet.address);// 導入私鑰
const walletFromPK = new ethers.Wallet('0x你的私鑰', provider);// 查詢余額
provider.getBalance(walletFromPK.address).then(balance => {console.log('ETH余額:', ethers.utils.formatEther(balance));
});

十二、交易構造與簽名(Transaction Creation & Signing)

功能點:

  • 構造交易(to、value、gas等)

  • 簽名交易

  • 廣播交易

Web3.js 示例:

const tx = {to: '0x接收方地址',value: web3.utils.toWei('0.01', 'ether'),gas: 21000,
};web3.eth.accounts.signTransaction(tx, '0x你的私鑰').then(signed => web3.eth.sendSignedTransaction(signed.rawTransaction)).then(receipt => console.log('交易成功:', receipt.transactionHash));

Ethers.js 示例:

const tx = {to: '0x接收方地址',value: ethers.utils.parseEther('0.01'),
};walletFromPK.sendTransaction(tx).then(txResponse => {console.log('發送中:', txResponse.hash);return txResponse.wait();
}).then(receipt => {console.log('交易成功:', receipt.transactionHash);
});

十三、調用智能合約(Call Smart Contract)

功能點:

  • 加載合約 ABI 和地址

  • 調用讀取函數(call)

  • 調用修改函數(send/寫交易)

Web3.js 示例:

const abi = [ /* 合約ABI */ ];
const contractAddress = '0x合約地址';
const contract = new web3.eth.Contract(abi, contractAddress);// 讀取數據(不會上鏈)
contract.methods.name().call().then(console.log);// 寫數據(需要簽名+發交易)
contract.methods.setValue(123).send({ from: account.address, gas: 100000 });

Ethers.js 示例:

const abi = [ /* 合約ABI */ ];
const contractAddress = '0x合約地址';
const contract = new ethers.Contract(contractAddress, abi, walletFromPK);// 讀取
contract.name().then(console.log);// 寫入(需要簽名)
contract.setValue(123).then(tx => tx.wait()).then(console.log);

賬戶管理、交易構造與簽名、調用智能合約——知識總結表

功能Web3.jsEthers.js
創建/導入賬戶web3.eth.accountsethers.Wallet
查詢余額web3.eth.getBalanceprovider.getBalance
構造交易手動構造 + sign/sendwallet.sendTransaction()
調用合約函數contract.methods.fncontract.fn()
簽名交易/消息signTransactionwallet.signMessage()

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83405.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83405.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83405.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

大數據學習棧記——Neo4j的安裝與使用

本文介紹圖數據庫Neofj的安裝與使用&#xff0c;操作系統&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安裝 Neofj可以進行官網安裝&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我這里安裝是添加軟件源的方法 最新版…

web架構4------(nginx常用變量,nginx中英文自動匹配,lnmp網站架構,正向代理,反向代理,負載均衡)

一.前言 本期來介紹nginx最后幾個知識點&#xff0c;看著要說的內容很多&#xff0c;其實一點也不多&#xff0c;都是所見即所得的東西。 二.nginx常用變量 2.1 常用變量 $args 請求中的參數&#xff0c;也叫查詢參數&#xff0c;如www.123.com/1.php?a1&b2的$args就是…

openeuler系統(CentOs)圖形化桌面黑屏/丟失(開啟VNC服務沖突)

1. VNC服務開啟如下&#xff1a; https://zhuanlan.zhihu.com/p/5049263261 在centos8系統上使用tigervnc-server搭建VNC_centos8 tigervnc-server-CSDN博客 2. 上述操作完成后&#xff0c;連接VNC仍會出現黑屏&#xff0c;則需要編輯/root/.vnc/xstartup&#xff1a; [運維…

MySQL:Prepared Statement 預處理語句

預處理語句&#xff08;Prepared Statements&#xff09;是 MySQL 中一種用于執行 SQL 查詢的高效、安全的方法。通過使用預處理語句&#xff0c;可以顯著提升查詢性能&#xff0c;并防止 SQL 注入攻擊。本文將詳細介紹 MySQL 預處理語句的概念、使用方法及其優勢。 一、預處理…

EPPLUS——CAD c#讀寫EXCEL的第三方庫

EPPLUS(可支持NET35) 在 CAD 的 C# 二次開發中&#xff0c;使用 EPPLUS 庫處理 Excel 文件具有以下顯著優點&#xff0c;尤其在兼容性、便捷性和性能等方面契合 CAD 項目的需求&#xff1a; 1. 跨.NET 版本兼容性強&#xff0c;適配 CAD 多環境部署 多框架支持&#xff1a;EP…

Linux知識回顧總結----進程狀態

本章將會介紹進程的一些概念&#xff1a;馮諾伊曼體系結構、進程是什么&#xff0c;怎么用、怎么表現得、進程空間地址、物理地址、虛擬地址、為什么存在進程空間地址、如何感性得去理解進程空間地址、環境變量是如何使用的。 目錄 1. 馮諾伊曼體系結構 1.1 是什么 1.2 結論 …

微信小程序之bind和catch

這兩個呢&#xff0c;都是綁定事件用的&#xff0c;具體使用有些小區別。 官方文檔&#xff1a; 事件冒泡處理不同 bind&#xff1a;綁定的事件會向上冒泡&#xff0c;即觸發當前組件的事件后&#xff0c;還會繼續觸發父組件的相同事件。例如&#xff0c;有一個子視圖綁定了b…

Android Test3 獲取的ANDROID_ID值不同

Android Test3 獲取的ANDROID_ID值不同 這篇文章來說明上一篇文章中說到的一個現象&#xff1a;在同一個項目中&#xff0c;創建不同的 app module&#xff0c;運行同一段測試代碼&#xff0c;獲取到的 ANDROID_ID 的值不同。 我也是第一次認真研究這個現象&#xff0c;這個還…

JSON 和 LabVIEW Data Types 互相轉換

使用JSONtext C:\Program Files (x86)\National Instruments\LabVIEW 2021\examples\JDP Science\JSONtext JSONtext LabVIEW Data Types.vi

docker和docker-compose的版本對應關系怎么看?

docker和docker-compose的版本對應關系怎么看&#xff1f;最近在安裝這兩個工具&#xff0c;像知道他們的版本對應關系&#xff0c;查了不少資料才找到。 雖然 Docker 和 Docker Compose 的版本并不嚴格綁定&#xff0c;但是在某些情況下&#xff0c;新版本的 Docker Compose …

郵科ODM攝像頭:多維度護航高鐵安全系統方案解析

?高鐵作為現代交通的重要支柱&#xff0c;其安全穩定運行依賴于高效的監控體系。攝像頭系統作為高鐵安全管理的“視覺感知中樞”&#xff0c;憑借多場景覆蓋、智能分析以及環境適應性設計&#xff0c;在行車安全、設備維護、乘客服務等方面發揮著不可或缺的作用。本文將從技術…

盒模型小全

CSS盒子模型詳解 1. 定義 CSS盒子模型是用于描述HTML元素在頁面中布局和表現的核心概念之一。在CSS中&#xff0c;所有HTML元素都被視為一個矩形的盒子&#xff0c;這些盒子封裝了周圍的HTML元素&#xff0c;并允許在其他元素和周圍元素邊框之間的空間放置內容。 2. 組成部分…

自定義鼠標效果 - 瀏覽器擴展使用教程

自定義鼠標效果 - 瀏覽器擴展使用教程 這里寫目錄標題 自定義鼠標效果 - 瀏覽器擴展使用教程功能特點安裝方法Chrome/Edge瀏覽器 使用指南1. 更改鼠標光標樣式2. 啟用鼠標軌跡效果3. 自定義軌跡效果點狀/彩虹/漸隱軌跡&#xff1a;表情軌跡&#xff1a; 管理自定義光標支持的文…

基于SpringBoot實現的課程答疑系統設計與實現【源碼+文檔】

基于SpringBootVue實現的課程答疑系統采用前后端分離架構方式&#xff0c;系統設計了管理員、學生、老師三種角色&#xff0c;系統實現了用戶登錄與注冊、個人中心、學生管理、老師管理、科目類型管理、學生問題管理、老師回答管理、老師信息管理、關注列表管理、交流區、輪播圖…

御微半導體面試總結

前一陣子在公司干的難受&#xff0c;所以再合肥這邊面試了幾家公司&#xff0c;挑一個御微半導體來說一下吧&#xff0c;公司主要是做半導體晶元測量的&#xff0c;具體啥我也不太明白。 公司產品線多&#xff0c;每條產品線配有獨立的軟件、結構、光學控制等人員開發語言和框…

Android Compose 自定義圓形取色盤

val Dp.toPx: Floatget() {var scale 3f // MyApplication.context.resources.displayMetrics.apply { // scale density // }return value * scale}val colors List(360) { i ->Color.hsv(360f - i, 1f, 1f) // 360到1的所有HSV顏色 }Preview …

vscode 配置 latex

下載插件 安裝插件前自行安裝 texlive, 按照 https://tug.org/texlive/ 要求安裝 找到 settings 打開 json 文件 在 json 文件中添加如下配置 "latex-workshop.latex.tools": [{"name": "latexmk","command": "latexmk",&qu…

安寶特方案丨船舶智造的“AR+AI+作業標準化管理解決方案”(質檢)

船舶質檢管理現狀&#xff1a;質檢環節部分依賴人工檢測&#xff0c;質檢員依據質量標準對產品進行抽檢或全檢。人工質檢受質檢員主觀因素影響較大&#xff0c;不同質檢員對標準的把握可能存在差異。 一、痛點與需求 1 Arbigtec 人工經驗依賴嚴重&#xff1a; 質檢員的檢測準確…

jenkins gerrit-trigger插件配置

插件gerrit-trigger下載好之后要在Manage Jenkins -->Gerrit Trigger-->New Server 中新增Gerrit Servers 配置好保存后點擊“狀態”查看是否正常

ubuntu24.04下 zookeeper3.8.4 集群的配置

1、環境 1.1 三臺機器網絡互通&#xff0c;并做hosts解析 準備三臺及以上ubuntu24.04主機&#xff08;奇數&#xff09; rootzk-node01:~# hostname zk-node01rootzk-node01:~# cat /etc/hosts 127.0.0.1 localhost 127.0.1.1 u24-server10.0.49.215 zk-node01 10.0.4…