Infura Ethereum API 入門

如果您想要使用 Infura API 存取 Ethereum 網路,您要如何進行操作?首先,您必須確認自己有 Infura 帳戶;請參閱此教學課程以開始!接下來,您必須決定自己要使用的介面;Infura 支援 HTTPS 和 WebSocket 介面的 JSON-RPC。在此教學課程中,我們將說明您使用各個介面的原因,也將使用 Node.js 範例說明如何透過這兩種方式存取 Ethereum API

HTTPS

HTTP/HTTPS 是單向的 (用戶端傳送要求,然後伺服器傳送回應),而且沒有與之關聯的狀態,也就是說,每個要求都會獲得一個回應,然後連線即終止。如果您獲得只需收集一次的資料,或如果您要存取舊資料,您就應使用 HTTPS 介面。您可以使用簡單的 RESTful 應用程式定期查看使用的 HTTPS。

範例:

在此範例中,我們將使用 Rinkeby 端點撰寫 Node.js 程式,並傳送 RPC 要求至 Infura 以使用 eth_getBlockByNumber 取得最新區塊資料。然後我們會將區塊編號從十六進位轉換為整數,並將整數區塊編號列印至終端。準備好了嗎?開始吧!

撰寫此程式碼的第一部份是安裝「節點」(如果您尚未安裝,您可以使用 npm下載)、 DotEnv 以及您的相依性。如果您對於 dotenv 不熟悉,這是不會上傳至 GitHub 的個別檔案,可確保您的專案識別碼和專案密鑰 (您的環境變數) 在您的程式保中保持機密!如果您需要更多資訊,請參閱此媒體文章

現在我們已完成安裝,我們可以繼續建立 app.js 檔案,並在頂端要求 dotenv 和 request。這可讓我們存取要求資料,以及包含在您 dotenv 檔案中的變數。

const dotenv = require('dotenv').config();
var request = require('request');

副本

接下來,我們要查看文件,了解 eth_getBlockByNumber 所需的標題。我們的標題必須包含 Content-Type:application/json,所以我們要將其加入至我們的 app.js 檔案:

const dotenv = require('dotenv').config();
var request = require('request');

var headers = {
	'Content-Type': 'application/json'
};

副本

接下來,我們將找出要透過伺服器傳送的資料。這種情況我們要指定:

1.JSON-RPC (最新版本)

2.我們稱此方式為

3.我們要加入的任何區塊參數 (這裡我們要最新區塊的資料,所以我們要加入的參數是 `[“latest”,true]`)

4.ID

您可以將此 dataString 視為我們在送出至伺服器前要填寫的 HTML 表格部分。

如果您要查看如何進行此配置,您可以使用 CURL 指令查看文件中提供的範例 (不全然是我們要找的參數,但意思差不多):

現在查看語法,並確認我們的程式碼正確無誤,然後將我們的 var dataString 新增至 app.js:

const dotenv = require('dotenv').config();
var request = require('request');

var headers = {
	'Content-Type': 'application/json'
};

var dataString = '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",true], "id":1}';

副本

現在我們有些進展了!但我們究竟是從何處取得資料?這就是接下來的程序。我們必須建立可拼出以下內容的變數:

1.URL

2.方式 (意即 POST/GET 等)

3.標題

4.本文

5.任何必要的授權 (您可以在這裡加入專案密鑰的資訊)。

現在讓我們個別說明這些所需項目:

  1. URL:您用以存取 API 的 URL;您可以使用我們文件中相對應的 URL 尋找所有網路的列表。
    • 注意:文件中的 URL 如果顯示「YOUR-PROJECT-ID」,就表示您要在這裡輸入您來自 dotenv 檔案的專案 ID
    • 我們將使用 Rinkeby 端點,因此我們將使用 Rinkeby HTTP URL
  2. 方式:使用的 HTTP 方式 (與 dataString 中的「方式」不同) - 在文件中識別,依各個所做的 JSON-RPC 呼叫而異
    • 可能的選項:POST/GET/PUT/PATCH/DELETE
    • getBlockByNumber 為 POST 要求
  3. 標題:呼叫要求的標題
    • 我們已在 var headers 中識別!
  4. 本文:我們要透過要求傳送的資訊
    • 在這個範例中,我們也已經建立 var dataString,完成了這個部分的操作!
  5. 驗證:完成要求時可能需要的任何授權 (並非必須)
    • 我們的專案密鑰就是在這裡 - 請注意,user 欄位會保留空白,且您的專案密鑰 (隱藏在您的 dotenv 檔案中) 會填入 pass 欄位中
    • 在這個範例中,我們並不需要專案密鑰,但是為了語法,我們仍在註解中加入:
const dotenv = require('dotenv').config();
var request = require('request');

var headers = {
	'Content-Type': 'application/json'
};

var dataString = '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",true], "id":1}';

var options = {
	url: `https://rinkeby.infura.io/v3/${process.env.PROJECT_ID}`,
	method: 'POST',
	headers: headers,
	body: dataString,
	// auth: {
	//   'user': '',
	//   'pass': `${process.env.PROJECT_SECRET}`
	// }
};

副本

注意:範本常值的語法非常重要,如果您需要協助,請參閱本此篇文章

好了,現在我們終於完成所有設定!現在我們只需要撰寫傳送要求、取得回應,以及從回應中擷取 JSON 並轉譯成可閱讀內容的函式:

const dotenv = require('dotenv').config();
var request = require('request');

var headers = {
	'Content-Type': 'application/json'
};

var dataString = '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",true], "id":1}';

var options = {
	url: `https://rinkeby.infura.io/v3/${process.env.PROJECT_ID}`,
	method: 'POST',
	headers: headers,
	body: dataString,
};

function callback(error, response, body) {
	if (!error && response.statusCode == 200) {
		json = response.body;
		var obj = JSON.parse(json);
		console.log(obj)
	}
}

request(options, callback);

副本

這可為我們提供完整的原始 JSON 回應,但一開始要查看的內容可能會很多:

但是我們知道要尋找最新的區塊編號 (一開始是十六進位,之後會轉成整數以列印):

對於這種特定情況,您可以使用最新交易並取得其區塊編號以取得最新區塊,但如果區塊中沒有交易,這種方式就無法使用!使用下列,不論區塊是否有交易,您都可以取得區塊資訊:

查看之前列印的 JSON 資料,我們可以發現 obj.result.number 提供我們最新區塊的十六進位:

每個區塊也有不重複的雜湊並儲存在雜湊欄中,通常這對後續要求更為實用,但我們目前先只著眼於數字部分。當我們 console.log(obj.result.number) 時,我們會獲得相同得醒目顯示十六進位值 (建議您一定要再次確認是否從程式碼獲得預期的結果):

為了要存取十六進位值,我們可以在程式碼中定義 hex 為 obj.result.number:

const dotenv = require('dotenv').config();
var request = require('request');

var headers = {
	'Content-Type': 'application/json'
};

var dataString = '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",true], "id":1}';

var options = {
	url: `https://rinkeby.infura.io/v3/${process.env.PROJECT_ID}`,
	method: 'POST',
	headers: headers,
	body: dataString,
};

function callback(error, response, body) {
	if (!error && response.statusCode == 200) {
		json = response.body;
		var obj = JSON.parse(json);
		hex = obj.result.number;
	}
}

request(options, callback);

副本

現在是這個挑戰的最後一個部分:將此十六進位轉換成整數,然後列印出該整數!我們想要呼叫 parseInt(hex, 16),將我們的十六進位字串轉換成整數,然後我們會主控台記錄最終結果。hex 是我們在上一步中找到的十六進位代碼,而 16 代表 hex 為十六進位,且基數為 16 (如果沒有指定,任何以「0x」為首的字串都會假設為十六進位,因此基數為 16,否則基數將為 10):

const dotenv = require('dotenv').config();
var request = require('request');

var headers = {
	'Content-Type': 'application/json'
};

var dataString = '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",true], "id":1}';

var options = {
	url: `https://rinkeby.infura.io/v3/${process.env.PROJECT_ID}`,
	method: 'POST',
	headers: headers,
	body: dataString,
};

function callback(error, response, body) {
	if (!error && response.statusCode == 200) {
		json = response.body;
		var obj = JSON.parse(json);
		hex = obj.result.number;
		final = parseInt(hex, 16)
		console.log(final)
	}
}

request(options, callback);

副本

執行程式碼時,我們會獲得:

成功!現在您了解如何使用 Infura API 透過 HTTPS 存取 Ethereum 端點!如果您想要尋找較舊資料,或只需要取得資料一次,這個方式很方便,但如果您需要持續取得資料該怎麼辦?那麼您就需要使用 WebSocket 連線!

WebSocket

WebSockets 是雙向可以設定狀態的,也就是說,用戶端和伺服器之間會保持連線,直到連線由任一方 (用戶端或伺服器) 終止為止。連線關閉後即終止。使用 WebSocket 的最佳時機,是當您要持續推送/傳輸資料至以開啟的連線時,例如在加密貨幣交易平台、遊戲應用程式或聊天應用程式中,您希望資料可以持續及時更新的時候

範例:

在此範例中,我們將再次使用 Rinkeby 端點撰寫 Node.js 程式,並會使用 WebSocket 連線,透過 WebSocket 連線利用 newHeads 訂閱類型使用 WebSocket 連線取得最新區塊標題資訊。在這個部分,我們想要查看 WebSocket 連線的最新區塊標題資料追蹤記錄。讓我們開始吧!

首先,我們要前往 npm 安裝,並要求必要的常數 - dotenv 及 ws (適用於 WebSocket)。這樣我們就可以隱藏專案 ID 和密鑰,並連接至 WebSocket。

const dotenv = require('dotenv').config();
const WebSocket = require('ws');

副本

接下來,我們要建立 WebSocket 的新執行個體以開啟 WebSocket 連線:

const dotenv = require('dotenv').config();
const WebSocket = require('ws');

const ws = new WebSocket(`wss://ropsten.infura.io/ws/v3/${process.env.PROJECT_ID}`);

副本

同樣的,我們要使用 dotenv 檔案來加密我們的專案 ID,因此我們這裡有範本常值。

如果您讀完了 HTTPS 部分,那麼這個部分您應該不會感到陌生!取得 WebSocket 後,我們就要開啟程式,然後在程式開啟時傳送我們的資料 (同樣的,這就像我們送出表格至伺服器,讓伺服器知道我們想要什麼)。此時,我們的方式是 eth_subscribe (由於我們訂閱以取得最新標題),且我們的參數是 newHeads,而這就是我們要取得結果的訂閱類型:

const dotenv = require('dotenv').config();
const WebSocket = require('ws');

const ws = new WebSocket(`wss://ropsten.infura.io/ws/v3/${process.env.PROJECT_ID}`);

ws.on('open', function open() {
	ws.send('{"jsonrpc":"2.0","method":"eth_subscribe","params":["newHeads"], "id":1}');
});

副本

現在我們要能夠查看在回應中收到的資料,因此我們將指定一個變數至剖析的 JSON 資料,並且將 console.log 以取得我們想要的標題資料:

const dotenv = require('dotenv').config();
const WebSocket = require('ws');

const ws = new WebSocket(`wss://ropsten.infura.io/ws/v3/${process.env.PROJECT_ID}`);
	ws.on('open', function open() {
	ws.send('{"jsonrpc":"2.0","method":"eth_subscribe","params":["newHeads"], "id":1}');
});

ws.on('message', function incoming(data) {
	var obj = JSON.parse(data);
	console.log(obj);
	ws.close()
});

副本

請注意,最後我們會關閉我們的 WebSocket,當我們嘗試取得最新區塊標題資料時,這是個很重要的步驟!由於我們已關閉我們的 WebSocket 連線,我們的回應就是我們所要的 (最新區塊的標題及其資料):


如果沒有關閉 WebSocket 連線會怎麼樣?我們會說明!我們取得此列印的速度其實很快,然資料就會不斷地進行更新。以下是保留開啟 WebSocket 連線的範例:


就這樣!現在您了解如何開啟 WebSocket 連線、使用參數呼叫方式並取得最新區塊的輸出資料 (如果想要的話,也可以取得最新區塊的持續更新列表)。

現在快去實際操作,探索 Infura API 吧!

想要探索更多嗎?

在我們的文件中查看所有您可以透過 HTTPS 及 WebSocket 所做的要求,以及幾種如速率限制等更為複雜的概念!

訂閱我們的電子報以取得更多 Web3 教學課程和產品最新消息。一如以往,如果您有任何疑問或功能方面的要求,您可以加入我們的社群直接與我們聯絡