跳至內容
0%

區塊鏈資料深度解析

發布於 2023年10月6日閱讀時間 3 分鐘

每個區塊鏈都保存著不可竄改的交易與事件紀錄。Web3 應用程式依賴區塊鏈資料來進行警示、儀表板呈現、決策判斷,或發想新功能。這對 Web3 至關重要,因為它驅動著從去中心化應用程式、基礎設施到 NFT 的一切。

本指南將涵蓋區塊鏈資料的所有面向,從 onchain 與 offchain 資料,到區塊鏈索引與 subgraph。讀完本指南後,你應該能更深入理解區塊鏈資料是如何產生、儲存與存取的。

什麼是 onchain 資料?

Onchain 資料就是儲存在區塊鏈網路上的所有資訊。它是網路上曾發生過的所有交易的不可竄改紀錄,且公開供所有人查看。Onchain 資料有許多不同類型,例如:

  • **交易資料:**涵蓋區塊鏈上每筆交易的相關資訊,例如寄送方與接收方、轉帳金額、以及交易手續費。
  • 區塊資料:涵蓋區塊鏈上每個區塊的相關資訊,例如前一個區塊的雜湊值、區塊內包含的交易、區塊的時間戳記,以及礦工手續費與獎勵。
  • **智能合約資料:**涵蓋所有已部署在區塊鏈上的智能合約相關資訊,例如合約程式碼本身、合約狀態,以及合約發出的事件。

與 offchain 資料不同,onchain 資料無法被更動,這對於全面掌握區塊鏈網路狀況相當重要。這些資料可用於追蹤區塊鏈上資產的移動、驗證交易是否成功完成,以及分析網路活動。

Onchain 資料的挑戰在於,要有效地存取它其實相當麻煩。儘管 onchain 資料隨時可取得,但它是以機器可讀的格式編碼;這種做法優先考量安全性,但犧牲了人類可讀性。人類可讀的格式可以是像 JSON 和 XML 這類型態,而這正是 ABI(application binary interface,應用二進位介面)派上用場的地方。

資料結構是如何定義的?

如前所述,onchain 資料的儲存方式與一般資料不同。它通常是以機器可讀的格式儲存,例如 bytecode。

ABI(application binary interface)幫助開發者將資料監控並解碼為人類可讀的格式。智能合約中的資料結構是透過 ABI 來定義的。ABI 作為一種函式選擇器,協助定義如何與智能合約互動,以及每個函式接受與回傳的資料型態。換句話說,它是一種標準化的方式,以人類與機器都容易理解的形式來表示資料結構。

區塊鏈資料儲存在哪裡?

區塊鏈資料通常儲存在分散式帳本中,意味著它並非儲存在單一位置,而是分散在節點網路上。節點是儲存區塊鏈資料並確保其安全的基本元件,因為每個節點都會保存一份資料副本。以下概略說明幾種不同類型的節點及其運作方式:

  • Full node(完整節點):顧名思義,full node 會儲存完整的區塊鏈歷史紀錄,以及網路的最新狀態(最新的 128 個區塊)。最新的狀態是所有客戶端驗證新進交易所需的資訊。理論上所有先前的狀態都可以從 full node 推導出來,但這會消耗大量的運算能力。當開發者需要存取區塊鏈最新的資料與狀態時,應該查詢 full node。以 Ethereum 為例,產生一個新區塊平均約需 13 秒,你只能取得過去 28 到 29 分鐘內的鏈上狀態。
  • Archive node(歸檔節點):除了完整的區塊鏈歷史之外,archive node 還會保存每個區塊的歷史狀態紀錄。這使得 archive node 相較於 full node,能更有效率地處理歷史資料的請求。當需要歷史資料時,開發者應查詢 archive node,因為它不需要像 full node 那樣重新產生狀態。對於建立分析工具,以及其他需要快速存取歷史資料的工具的開發者來說,archive node 是理想的選擇。
  • Light node(輕節點):這類節點只儲存區塊標頭(block header),也就是在網路上交易所需的最少資料。當開發者只需要從區塊標頭擷取基本區塊鏈資料時,可以選擇查詢 light node。

節點並非儲存資料的唯一方式。資料也可以儲存在 offchain 的資料庫、雲端儲存服務,甚至是自建伺服器上。將資料儲存在 offchain 可能不如 onchain 安全,但對於許多應用程式而言仍然相當實用,因為存取起來更便宜也更快。當資料儲存在 offchain 時,區塊鏈上通常只會儲存用來定位這些 offchain 資料所需的資訊。

智能合約與區塊鏈儲存

智能合約是儲存在區塊鏈的節點內,不過智能合約本身也有自己的資料儲存機制。智能合約中的資料儲存方式稱為合約儲存佈局(contract storage layout)。合約儲存佈局指的是規範合約儲存變數在長期記憶體中如何排列的規則。

以 Solidity(一種用於建構智能合約的高階程式語言)來說,有 3 種不同的記憶體類型可以指示 EVM 將變數儲存在何處:memory、calldata 與 storage。

Memory:用來儲存函式執行期間所需的暫時資料

Calldata:一種特殊的資料位置,內含函式引數

Storage:資料永久儲存在區塊鏈上的位置

資料儲存 vs. 檔案儲存

最簡單來說,資料儲存就是將資料保存下來,以便日後能被取用的過程。而檔案儲存則不同於資料儲存,它是將實際檔案儲存在與該檔案的中繼資料不同的位置。這種分離做法通常是為了提升效能、降低成本,或加強安全性。

將檔案儲存與資料儲存分開的常見方式,是使用像 IPFS 或 Arweave 這類去中心化檔案儲存系統。這些系統讓使用者能將檔案儲存在分散式的電腦網路上,並透過減少需要儲存在區塊鏈本身上的資料量,來達到成本效益。

概略來說,檔案的中繼資料儲存在 onchain,而檔案本身則儲存在 offchain。當應用程式需要存取該檔案時,可以從中繼資料中取得 IPFS 或 Arweave 的 URL。接著應用程式便能使用這個 URL 從 IPFS 或 Arweave 下載檔案。

什麼是 IPFS?

IPFS 使用一種以內容定址的系統,每個檔案都是根據 CID(content identifier,內容識別碼)來識別。CID 是獨一無二的雜湊值,無論檔案儲存在何處都始終指向同一個檔案。

這代表如果檔案有所變更或更新,雜湊值也會隨之改變。這種以內容定址的系統讓檔案能依據其 CID 而非所在位置來儲存與擷取。

IPFS 運作的大致流程如下:

  1. 為檔案建立一個 CID
  2. 接著將檔案上傳至 IPFS 網路
  3. IPFS 會在 DHT(distributed hash table,分散式雜湊表)中儲存哪個網路節點擁有與該 CID 對應之檔案的資訊
  4. 接著可以用該雜湊值查詢 DHT,找出儲存該檔案的節點
  5. CID 會儲存在該代幣的智能合約中

Arweave

Arweave 是另一種分散式儲存解決方案,同樣使用 CID 來儲存與存取內容,並在中繼資料中引用內容。主要差異在於,Arweave 在誘因與永久性上採取不同的做法,透過激勵節點永久保存資料。

資料發布 vs. 資料儲存 vs. 資料可用性

要更深入理解區塊鏈資料,我們還必須了解資料發布(data publishing)、資料儲存(data storage)與資料可用性(data availability)分別代表什麼意思。簡單來說:資料發布是指在區塊鏈上將資料公開讓其他人取得的過程,資料儲存是指將資料保存在區塊鏈上的過程,而資料可用性則是確保區塊鏈網路上所有參與者都能存取到資料的保證。

資料可用性之所以重要,是因為當驗證者(validator)將區塊加入 Ethereum 區塊鏈時,必須將該區塊的所有交易資料廣播給網路上其他的驗證者。驗證者的任務是執行所有交易資料,這意味著區塊鏈能處理的交易數量,取決於其驗證者能執行的交易量——簡而言之,這就是資料可用性問題。

其中一個核心的資料可用性問題,是在無法取得整個區塊的情況下(資料發布),如何得知某個區塊是否已經被發布。

資料發布面臨的主要挑戰在於,區塊產生者不會在含有未知內容的區塊之上繼續產生新區塊。這代表含有未發布資料的區塊可能會被完全忽略。一旦資料被發布,就進入了資料儲存的階段,然而,full node 究竟會保存該資料多久卻並不明確。這點值得關注,因為我們無法強制節點保留資料,因而對資料可用性帶來更多疑慮。

模組化區塊鏈與替代性資料可用性方案

模組化區塊鏈是指專門處理特定功能的區塊鏈。舉例來說,一條模組化區塊鏈可能專注於資料可用性,而將執行或共識等其他任務交由其他區塊鏈或系統處理。

模組化區塊鏈會建立替代性的資料可用性層,透過使用 offchain 資料儲存、資料壓縮、分片(sharding)等多種技術,讓發布 calldata 的成本比發布到 Ethereum 上更便宜。

使用替代性資料可用性層的模組化區塊鏈範例之一是 EigenDA。EigenDA 是一個建構在 Arweave 之上的去中心化資料可用性層。EigenDA 讓使用者能將 calldata 發布到 Arweave,接著向 Ethereum 證明該 calldata 已經被發布。這讓使用者能將 calldata 發布到 Ethereum,而不需要支付將 calldata 儲存在 onchain 所需的高額 gas 費用。

Onchain 資料的類型

了解 onchain 資料是什麼之後,接下來我們將深入探討不同類型的 onchain 資料,以及它們是如何產生、儲存與存取的。

什麼是交易資料?

交易資料包含與區塊鏈上某筆交易相關的所有資訊,例如:

  • 寄送方
  • 接收方
  • 轉帳金額
  • 交易手續費
  • 交易的時間戳記

這些資料是在使用者於區塊鏈上進行交易時產生的。接著會廣播給網路節點,以驗證該交易並將其加入帳本。

交易資料可以透過一種稱為 Merkle tree 的樹狀資料結構來儲存與驗證。Merkle tree 是一種二元樹,能快速驗證資料,樹中的每個節點都是其所包含資料的雜湊值。要驗證 Merkle tree 中資料的完整性,只需要該樹的根雜湊值(root hash)即可。將資料儲存在 Merkle tree 中,有助於盡可能縮小區塊鏈的大小。由於 Merkle tree 還有更多細節可以深入探討,你可以閱讀 Alchemy 文件中關於 Merkle tree 的更多說明。特別是在 Ethereum 上,資料是使用 Patricia Merkle Trie 來儲存——這是一種結合了 radix trie(Patricia trie)與 Merkle tree 的資料結構。

若要快速存取交易資料,你可以直接使用區塊鏈瀏覽器,例如 Ethereum 交易可以使用 Etherscan。區塊鏈瀏覽器讓使用者能查看與搜尋所有交易資料,可用於追蹤代幣的移動、識別詐騙交易、開發區塊鏈應用程式等等。若要查找某筆特定交易的資料,你需要該交易的雜湊值。如果你的應用程式需要經常性地存取區塊鏈資料,Alchemy 可以提供協助。

中繼資料(Metadata)

中繼資料是提供區塊鏈上交易與資產額外資訊的資料。這可能包含以下額外細節:

  • 資產的名稱或代號
  • 資產的總供給量
  • 資產的持有歷史紀錄
  • 資產的合約地址

與交易資料不同,中繼資料對於區塊鏈的運作並非必要,但對開發者建立像是區塊瀏覽器、錢包、儀表板等應用程式來說相當實用,這只是其中幾個例子。中繼資料可以由智能合約或區塊鏈自動產生並定義(例如交易中繼資料),也可以由使用者手動定義(例如資產中繼資料)。

若要存取中繼資料,開發者可以使用 getMetadata 查詢。若要使用這些查詢,開發者需要使用區塊鏈 API,例如 Alchemy API。透過使用 getMetadata 查詢,開發者可以建構各種應用程式,協助使用者理解並與區塊鏈網路互動。

事件資料(Events data)

事件資料指的是智能合約在執行交易時所發出的資料。這些資料可能包含以下資訊:

  • 所發生事件的類型
  • 發出該事件的智能合約地址
  • 該事件的詳細內容(例如轉移的代幣數量、資產的新擁有者等)

這些資訊有助於開發者監控智能合約的活動,並可以透過 log 來存取。Log 是區塊鏈上曾發生過的所有事件的紀錄,由智能合約產生。這些 log 可以在交易收據中找到,也可以透過向 eth_getLogs 發出請求來查看。

Calldata

Calldata 是在呼叫函式時傳遞給智能合約的資料。換句話說,它是一種暫時性的資料儲存形式,外部呼叫者的函式引數會先儲存在這裡,然後才傳入智能合約。Calldata 可以包含任何型態的資料,無論是整數、字串、陣列等等。這一點很重要,因為它讓智能合約能彼此溝通,也能與使用者溝通;舉例來說,在 NFT 智能合約中,calldata 可用於將 NFT 的所有權轉移給使用者。

區塊鏈上的所有操作都會收取 gas 費用,使用 calldata 也不例外。當 L2 交易發布到 Ethereum 時,calldata 會包含在該交易中。這是因為 Ethereum 網路需要 calldata 來驗證交易,並執行被呼叫的智能合約函式。Calldata 所消耗的 gas 取決於 calldata 的大小,以及 calldata 中所包含資料的類型。以 Ethereum 為例,每個區塊所能容納的最大 calldata 為 1,048,576 位元組。

Blob

Blob(binary large object,二進位大型物件)的設計目的,是讓網路確認附加在區塊上的 blob 承載著正確的資料,藉此讓交易驗證更有效率。Blob 是隨著 proto-danksharding 一起被引入的,這是一項旨在降低 calldata 成本並增加每個區塊 calldata 容量的提案。

據稱 proto-danksharding 透過引入一種稱為 blob-carrying transaction(攜帶 blob 的交易)的新交易類型,讓區塊鏈上的 calldata 更便宜。Blob-carrying transaction 與一般交易類似,但它們可以包含資料 blob。

Blob-carrying transaction 比一般交易更便宜,因為它們處理時所需的 gas 較少。這是因為資料 blob 是儲存在 offchain,不需要包含在交易之中。

資料 blob 與 blob-carrying transaction 的引入,將使得在 Ethereum 區塊鏈上以更低成本儲存與處理大量資料成為可能。

什麼是區塊鏈索引?

書籍中的索引會列出關鍵字與概念被提及的頁碼。同樣地,區塊鏈索引是一種將區塊鏈資料組織並儲存的過程,使其易於搜尋與查詢。在處理區塊鏈資料時理解這一點相當重要,因為它讓使用者能以更有效率且有效的方式存取並分析資料。

由於區塊鏈遵循以時間排序的結構,資料可能分散在眾多區塊之間並糾結在一起。索引旨在透過建立區塊鏈資料的索引來解決這個問題。

這個索引是一種資料庫,以最適合搜尋與查詢的方式儲存區塊鏈資料的子集。要為資料建立索引,有多種不同的索引方法,例如:索引交易相關資訊、索引地址、索引智能合約互動等等。經過索引的資料,開發者便可以透過 GraphQL、Alchemy 及其他 Web3 協定所提供的 API 來存取。

常見的索引使用情境

既然我們已經了解區塊鏈索引對開發者更有效率地搜尋與查詢資料有多大幫助,接下來讓我們看看幾個常見的索引使用情境。

索引交易歷史紀錄——這可用於追蹤像是 Uniswap 資金池的交易量與流動性,也可用於找出最大的交易者與大戶(whale)。

索引分析與報表——這可用於產生各種指標的報表,例如交易量、gas 費用與使用者活動。在追蹤與分析特定智能合約、加密貨幣、市場趨勢的表現時特別有幫助,或是用來理解使用者活動(例如活躍錢包數量、已處理交易數量等)。

索引中繼資料——這可用於追蹤 NFT 的所有權與轉移狀況。一個實際的例子可能是 NFT 分析工具,你可以針對某個特定 NFT 系列的交易索引進行查詢,以了解購買/所有權歷史及其他相關細節。

索引智能合約事件——這可用於追蹤代幣的移動(例如特定 ERC-20 代幣的 transfer 事件)、借貸活動,或是更深入了解 NFT 市場,這裡僅舉幾個具體例子。整體而言,索引智能合約事件有助於我們監控智能合約的活動,這能協助識別弱點,甚至發掘新應用程式與服務的機會。

Offchain 與 onchain 索引

索引可以儲存在 onchain 或 offchain,各自有其優點與取捨。舉例來說,Satsuma 是一個 onchain 索引協定,已被 Alchemy 收購。Satsuma 使用 GraphQL,一種用於 API 的查詢語言,其運作方式是透過 subgraph 掃描網路區塊與智能合約,將來自不同來源的資料整合到單一 API 呼叫中。Offchain 索引協定的運作方式,則是將索引儲存在節點的本地儲存空間中(例如 SubQuery),或是儲存在像 AWS 這類傳統雲端伺服器上,這可能比 onchain 索引更快。無論是使用 offchain 還是 onchain 索引協定,開發者都能輕鬆使用各種查詢語言:

  • GraphQL——開發者可以使用 GraphQL 查詢 subgraph,取得特定 ERC20 代幣的轉移歷史紀錄。
  • SQL——開發者可以使用 SQL 查詢 offchain 索引,取得已部署在特定區塊鏈上的所有智能合約清單。
  • Elasticsearch——開發者可以使用 Elasticsearch 查詢 offchain 索引,取得特定區塊鏈上最熱門的 NFT。

區塊鏈資料是如何被存取的?

了解 onchain 資料及其儲存方式之後,我們可以更深入探討開發者實際上要如何存取區塊鏈資料。

查詢節點

存取區塊鏈資料最直接的方式之一,就是查詢節點,不過這也可能是最消耗資源的方式。

要查詢節點,你必須使用 JSON-RPC,透過 full node 或 archive node(如先前所述,這些是保有完整區塊鏈副本的節點)來存取資料。若要使用 JSON-RPC 查詢節點,開發者必須向節點傳送一個 JSON 物件,其中包含你想呼叫的方法(method)、該方法的參數,以及 JSON-RPC 版本。

透過像 Alchemy 這類提供 JSON-RPC API 的解決方案,就能輕鬆完成這些工作,用來查詢節點。

若要向節點查詢帳戶餘額,你會傳送以下 JSON 物件給節點
若要向節點查詢帳戶餘額,你會傳送以下 JSON 物件給節點(來源)

在查詢節點以取得特定區塊鏈事件時,事件篩選器(event filter)也相當實用。要使用事件篩選器,你需要指定想要篩選的事件類型以及該事件的參數。一個使用事件篩選器的簡便方式,是透過 Alchemy 的 Node API。Alchemy 的 Node API 是一項完全託管的服務,包含執行節點所需的全部基礎設施,以及方便與節點互動及查詢的 API 與 SDK。

透過 webhook 串流資料

透過 webhook 串流資料是一種即時接收區塊鏈資料更新的方式。事件資料可以透過自訂 webhook 與 webhook 變數來串流。做法是選擇一項區塊鏈索引服務,例如 Alchemy,在你的伺服器上建立一個 webhook 端點,訂閱相關事件,並設定 webhook 變數。以 Alchemy 為例,它讓使用者能建立自訂 webhook,這些 webhook 可以由各種區塊鏈事件觸發,例如新交易、新的智能合約部署,以及智能合約狀態的變更。Alchemy 最近也升級了自訂 webhook 功能,協助開發者更精確地縮小資料串流範圍,並能輕鬆使用變數來更新 webhook 查詢。

查詢 Subgraph

Subgraph 是由社群建立的開源 API,用於從 Indexer、Curator 與 Delegator 取得區塊鏈資料。由於 subgraph 是使用 GraphQL 建構而成,開發者可以使用 GraphQL API 來查詢 subgraph。Subgraph 可以是託管的(hosted),也可以是自行架設的(self-hosted)。託管的 subgraph 可以透過向 GraphQL API URL 發送 GraphQL 查詢來查詢。自行架設的 subgraph 則可以透過將 subgraph 部署到 GraphQL 伺服器來查詢。這可以透過像 Satsuma 這樣的解決方案來完成,它讓開發者能部署自己的 subgraph。

查詢資料倉儲(Data warehouse)

資料倉儲是針對查詢歷史資料而優化的,通常是結構化格式。相對地,資料湖(data lake)則儲存大量通常是非結構化或半結構化的資料。Dune Analytics 是一項可用來查詢、擷取並視覺化資料湖資料的工具。Dune 透過提供如資料集探索器(dataset explorer)等工具來做到這點,讓你能探索不同鏈上的資料、資料集、原始區塊鏈資料等等。你也可以透過回填資料庫,並透過自訂 webhook 串流資料,來建立你自己的資料湖。

結語

總結來說,理解區塊鏈資料對於任何想要使用或建構 Web3 基礎設施或應用程式的開發者來說都相當實用。Onchain 資料儲存在區塊鏈上,可以拆分為不同類型,例如交易資料、中繼資料、事件資料、calldata 與 blob。這些資料接著儲存在節點中,並可以根據使用情境的不同,透過各種方式存取。

Background gradient

打造區塊鏈魔法

Alchemy 結合最強大的 Web3 開發者產品與工具,並提供資源、社群與卓越的支援。