跳至主要內容

如何透過日誌追蹤 Solana 交易紀錄

更新於
2025年11月26日

閱讀時間 8 分鐘

概覽

您是否曾需要擷取與某個錢包相關的所有交易?想查看與某台糖果機相關的所有鑄造交易?或者想查看某個 NFT 的交易紀錄?Solana 的getSignaturesForAddress方法是一個多功能工具,能讓您輕鬆取得交易紀錄。 

想看影片教學嗎?跟著諾亞一起學習,只需 15 分鐘,就能掌握如何使用 Solana web3.js 取得 Solana 交易日誌。
訂閱我們的 YouTube 頻道,觀看更多影片!

您將負責的工作內容

在這份指南中,您將深入探索 Solana 交易的精彩世界!您將建立一個簡單的腳本,用以查詢某個地址(錢包、程式 ID、代幣鑄造等),並找出所有與該地址相關的交易紀錄。 

您需要準備的物品

我們開始吧!

設定您的執行環境

請在終端機中執行以下指令,建立一個新的專案目錄及名為log.js 的檔案:

mkdir get_sol_tx
cd get_sol_tx
echo > log.js

安裝 Solana web3 依賴項:

yarn init -y
yarn add @solana/web3.js@1

npm init -y
npm install --save @solana/web3.js@1

在您選擇的程式碼編輯器中開啟log.js 檔案,並在第 1 行引入@solana/web3.js,並將其儲存為常數 **solanaWeb3:
**

const solanaWeb3 = require('@solana/web3.js');

請指定您要搜尋的地址:

const searchAddress = '此處請填寫您的地址'; //範例 'vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg'

注意:此處可為 Solana 上的任何有效地址(例如:錢包地址、鑄造地址、程式地址)。若您尚未擁有此類地址,可將「vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg」作為範例。

好啦,我們準備好要開動了!

建立與您的 Quicknode RPC 的連線

若要在 Solana 上進行開發,您需要一個 API 端點來連線至該網路。您可以使用公開節點,或自行部署並管理基礎架構;不過,若您希望將回應時間縮短 8 倍,不妨將繁重的工作交給我們處理。


了解為何超過 50% 的 Solana 專案選擇 Quicknode,並點此免費註冊。

我們將在 Solana Devnet 上啟動我們的節點,但您也可以根據自身需求啟動相應的節點。請複製 HTTP Provider 的連結:

新節點

返回log.js檔案,建立一個常數「endpoint」,並將您的 Quicknode URL 賦值給它。在下一行中,將此常數作為Connection函式的參數傳入,並將結果儲存到另一個名為solanaConnection 的常數中:

const 端點 = 'https://example.solana-devnet.quiknode.pro/000000/';
const solanaConnection = new solanaWeb3.Connection(端點);

太好了!您已經準備好要建立搜尋功能了。

建立交易查詢

getSignaturesForAddress方法將在此承擔大部分繁重的工作。其運作方式如下: 

它將接受兩個參數: 

  • 要搜尋的地址(必填):您要查詢的公鑰
  • 選項 (可選):一個包含 3 個可選項目的物件: 
    • 之前:從特定交易簽名之前的時間點開始向後搜尋
    • 之後:從特定交易簽名開始,朝時間前方向搜尋
    • limit:要回傳的交易筆數上限(請注意,最大值和預設值皆為 1,000)

它將返回一個 Promise,該 Promise 代表一個包含ConfirmedSignatureInfo 陣列的物件,而 ConfirmedSignatureInfo 是一種包含關鍵交易資訊的類型物件: 

  • 簽名(交易 ID), 
  • slot 和 blockTime(用以查看交易何時被處理), 
  • err(若有錯誤),以及 
  • 備註(如有與該交易相關的備註)

定義一個新的非同步函式 `getTransactions`,該函式接受兩個參數:`address` 和`numTx`。 

在我們的函式內部,呼叫solanaConnection的新實例上的getSignaturesForAddress方法,並將輸出儲存至變數transactionList 中:

const getTransactions = async(address, numTx) => {
const pubKey = new solanaWeb3.PublicKey(address);
let transactionList = await solanaConnection.getSignaturesForAddress(pubKey, {limit:numTx});
}

這應該會回傳一個包含所有符合搜尋條件的交易紀錄的陣列。讓我們以易於閱讀的方式記錄結果。 

getTransactions 函式內部,建立一個forEach迴圈,用來記錄每筆交易相關的資訊: 

const getTransactions = async(address, numTx) => {
const pubKey = new solanaWeb3.PublicKey(address);
let transactionList = await solanaConnection.getSignaturesForAddress(pubKey, {limit:numTx});
transactionList.forEach((transaction, i) => {
const date = new Date(transaction.blockTime*1000);
console.log(`Transaction No: ${i+1}`);
console.log(`Signature: ${transaction.signature}`);
console.log(`Time: ${date}`);
console.log(`Status: ${transaction.confirmationStatus}`);
console.log(("-").repeat(20));
})
}

執行您的程式碼!

如果一切設定正確,您應該就能呼叫您的函式並看到一些結果!請將以下內容新增至log.js 檔案的末尾: 

getTransactions(searchAddress,3);

現在請在終端機中輸入: 

node log.js

您應該會看到類似以下的內容: 

交易搜尋

哇!還挺簡單的,對吧?不妨試著測試幾個不同的錢包、一個 NFT 鑄造地址,以及一個 Candy Machine ID。你可以發現,這種方法應該會產生類似的結果,這使得它在許多不同的應用場景中都非常實用。 

恭喜!您已成功完成交易……您可以在這裡停下來,但如果您想了解還能用這個交易簽名做些什麼,請繼續閱讀!👇

解析交易

現在我們已經掌握了一些關於交易歷史的有用基本資訊,但每筆交易究竟做了什麼呢?我們可以使用 Solana 的getParsedTransaction方法,藉此取得大量額外的詳細資訊。 

getParsedTransaction方法會接受一個已確認或已最終確認的交易簽名,並返回一個ParsedTransactionWithMeta物件: 

export type ParsedTransactionWithMeta = {
/** The slot during which the transaction was processed */
slot: number;
/** The details of the transaction */
transaction: ParsedTransaction;
/** Metadata produced from the transaction */
meta: ParsedTransactionMeta | null;
/** The unix timestamp of when the transaction was processed */
blockTime?: number | null;
/** The version of the transaction message */
version?: TransactionVersion;
};

這裡蘊含了大量資訊,雖然我們不會在這個入門指南中詳細探討,但我們仍想舉個例子,說明您該如何與這些物件進行互動。 

在您的getTransactions函式中,讓我們宣告兩個新變數:signatureListtransactionDetails。我們將透過對transactionList 進行映射來產生一個簽名清單,並透過將這些簽名傳入getParsedTransactions 來產生每筆交易的詳細資訊:

const getTransactions = async(address, numTx) => {
const pubKey = new solanaWeb3.PublicKey(address);
let transactionList = await solanaConnection.getSignaturesForAddress(pubKey, {limit:numTx});

//Add this code
let signatureList = transactionList.map(transaction=>transaction.signature);
let transactionDetails = await solanaConnection.getParsedTransactions(signatureList, {maxSupportedTransactionVersion:0});
//--END of new code

transactionList.forEach((transaction, i) => {
const date = new Date(transaction.blockTime*1000);
console.log(`Transaction No: ${i+1}`);
console.log(`Signature: ${transaction.signature}`);
console.log(`Time: ${date}`);
console.log(`Status: ${transaction.confirmationStatus}`);
console.log(("-").repeat(20));
})
}

當我們的承諾回傳結果時,`transactionDetails` 會返回一個由 `ParsedTransactionWithMeta` 物件組成的陣列。讓我們試著從中找出一些有用的資訊。 

假設我們想找出在某筆交易中,我們曾與之互動的所有程式或智慧合約。在原始的forEach迴圈內,於date變數宣告之後,讓我們建立一個新變數transactionInstructions: 

        const transactionInstructions = 交易詳情[i].交易.訊息.指令;

這將利用我們的索引i,來查找與迴圈中正在查詢的同一筆交易相關的詳細交易資訊。由於每筆交易可能包含多條指令或多個程式迭代,因此我們需要另一個迴圈來取得該交易中的每個程式互動。在迴圈內部,於記錄confirmationStatus之後,請加入以下內容:

        transactionInstructions.forEach((instruction, n)=>{
console.log(`---Instructions ${n+1}: ${instruction.programId.toString()}`);
})

我們在此的處理方式是:針對每筆交易,檢視每條交易指令,並記錄程式名稱(若有)及程式 ID。 

最終的函式應如下所示: 

const getTransactions = async(address, numTx) => {
const pubKey = new solanaWeb3.PublicKey(address);
let transactionList = await solanaConnection.getSignaturesForAddress(pubKey, {limit:numTx});

let signatureList = transactionList.map(transaction=>transaction.signature);
let transactionDetails = await solanaConnection.getParsedTransactions(signatureList, {maxSupportedTransactionVersion:0});

transactionList.forEach((transaction, i) => {
const date = new Date(transaction.blockTime*1000);
const transactionInstructions = transactionDetails[i].transaction.message.instructions;
console.log(`Transaction No: ${i+1}`);
console.log(`Signature: ${transaction.signature}`);
console.log(`Time: ${date}`);
console.log(`Status: ${transaction.confirmationStatus}`);
transactionInstructions.forEach((instruction, n)=>{
console.log(`---Instructions ${n+1}: ${instruction.programId.toString()}`);
})
console.log(("-").repeat(20));
})
}

現在,請再次執行您的腳本。在終端機中輸入: 

node log.js

您應該會看到類似以下的內容:

交易搜尋(第二部分)

做得真棒!我們的交易結果現在已包含我們曾互動過的各項計畫的詳細資訊! 

如果您願意,可以在此處搜尋您的地址,將結果與 Solana 區塊鏈瀏覽器進行比對(請務必透過頁面右上角的選項切換至相同網路進行搜尋)。

總結

太棒了!現在你已經深入了解了 Solana 交易這個令人興奮的世界! 

我們將在未來的指南中進一步探討這些內容;但如果您迫不及待想繼續探索,不妨嘗試對 `transactionDetails` 陣列進行實驗,執行一些類似的查詢,但這次改為檢視: 

  • transactionDetails[i].meta
  • transactionDetails[i].transaction.message.accountKeys

若要將這些概念付諸實踐,請點此查看我們其他關於 Solana 的教學指南。

訂閱我們的電子報,獲取更多關於 Solana 的文章和指南。如有任何意見回饋,歡迎透過Twitter聯絡我們。您隨時都可以在我們的Discord社群伺服器上與我們聊天,那裡聚集了您這輩子見過最酷的開發者們 :)

我們 ❤️ 您的回饋!

如果您有任何意見回饋或對新主題的建議,請告訴我們。我們非常樂意聽取您的意見。

分享這份指南