如果你想了解如何組織資料,則可以使用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}';
但是我們到底從哪裡得到資料呢?這是接下來要做的。我們需要建立一個變數來說明:
url(網址)
method(方法:即POST/GET/etc)。
headers(請求頭)
body(請求體)
auth:可能的授權資訊(如:在其中包含專案密碼的資訊)。
讓我們逐一分析一下這些含義:
1. url: 用來訪問API的URL;你可以在我們的文件中找到所有網路及其相應URL的列表。
· 注意:文件中URL上顯示“YOUR-PROJECT-ID”的位置,使用dotenv檔案中的ProjectID
· 我們將使用Rinkeby節點,因此我們將使用Rinkeby HTTP URL
2. method: 特定的每個JSON-RPC呼叫的docs使用的HTTP方法(**與dataString中的method的標識不同)
· 可能的選項:POST/GET/PUT/PATCH/DELETE
· getBlockByNumber是一個POST請求
3. headers : 呼叫需要的請求頭
· 我們已經在**var headers**中標識了這些內容!
4. body: 請求傳送的任何資訊
· 在這種情況下,我們已經透過建立**var dataString**來自己完成這項工作!
5. auth: 完成該請求可能需要的授權(不是必須的)
·這就需要Project Secret - 請注意,user 欄位保留為空白,而你的Project Secret(隱藏在dotenv檔案中)填充到pass欄位。
· 在此示例中,我們不需要Project Secret,但出於語法考慮,我們將其作為註釋包括在內:
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為我們提供了最新區塊號的十六進位制:
每個區塊還具有一個唯一的雜湊,該雜湊儲存在hash欄位中,通常對於後續請求更有用,但是現在我們只關注數字。當我們使用console.log(obj.result.number)時,會得到相同的高亮顯示的十六進位制值(最好再次檢查一下期望從程式碼中得到的值):
所以,我們可以在程式碼中將hex定義為obj.result.number,以便訪問該hex值:
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訪問以太坊節點了!如果你要查詢更多歷史資料或只需要一次資料,此方法非常有用,但是如果你需要滾動的資料,該怎麼辦?你就需要使用WebSocket連線!
WebSocket
WebSocket是雙向和有狀態的,這意味著客戶端和伺服器之間的連線將保持有效狀態,直到被任何一方(客戶端或伺服器)終止。連線關閉後,將終止連線。當你想要將資料連續推送/傳輸到已經開啟的連線時,這是選用WebSocket的最佳時間,例如在加密貨幣交易平臺,遊戲應用程式或聊天應用程式中,你想要在其中不斷(即時的)更新資料。
示例
在此示例中,我們將編寫一個Node.js程式,該程式再次使用Rinkeby節點,並使用WebSocket連線透過該WebSocket連線上的newHeads訂閱型別來獲取最新的區塊頭資訊。對於這個例子,我們希望看到來自WebSocket連線的最新塊頭資料在日誌的尾部輸出。讓我們開始吧!
首先,我們要進行 npm install 以及引入必需的依賴 -dotenv和ws(用於WebSocket)。dotenv將使我們能夠隱藏Project ID和Secret, ws用於連線到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檔案將Project 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可以發出的所有可能的請求,以及一些更復雜的概念,例如速率限制: