使用Infura的API访问以太坊网络数据
因此,你想使用Infura的API访问以太坊网络-你将如何做?首先,你需要确保你拥有Infura帐户(查看此教程 申请账号!)接下来,需要确定要使用哪个接口 - Infura在HTTPS和WebSocket接口上都支持JSON-RPC。在本教程中,我们介绍使用每个接口的原因,以及将通过Node.js示例介绍两种访问以太坊API的方法。
HTTP/HTTPS 是“单向”的 - 客户端发送请求,然后服务器发送响应 - 其“无状态”关联,这意味着每个请求都获得一个响应,然后终止连接。如果你获得仅需要收集一次的数据或正在访问旧数据,则需要使用HTTPS接口。你会看到HTTPS在简单的RESTful应用程序里经常使用。
在此示例中,我们将编写一个使用Rinkeby节点的Node.js程序,并使用eth_getBlockByNumber
将RPC请求发送到Infura以获取最新的区块数据。从那里,我们将把块号从十六进制转换为整数,并将整数块号打印到终端。准备好了?我们开始吧!
编写此代码的第一步是安装Node(如果尚未安装,则可以使用npm或download)、DotEnv、以及相关的依赖。如果你不熟悉dotenv
,这是一个不会上传到GitHub的单独文件,可确保你的Project ID和Project Secret(配置在环境变量中)在代码中仍然是保密!要了解更多请查看此篇文章。
现在,我们已经完成了安装,继续创建 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'
};
接下来,我们将确定要发送到服务器的数据。在这种情况下,要指定我们想要的:
JSON-RPC(最新版本)
正在调用的方法
要包含的任何块参数(在本案例下,我们需要最新的块数据,因此我们包含一个参数为[“latest”,true]
)
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}';
但是我们到底从哪里得到数据呢?这是接下来要做的。我们需要创建一个变量来说明:
url(网址)
method(方法:即POST/GET/etc)。
headers(请求头)
body(请求体)
auth:可能的授权信息(如:在其中包含项目密码的信息)。
让我们逐一分析一下这些含义:
method
的标识不同)
getBlockByNumber
是一个POST请求var headers
中标识了这些内容!var dataString
来自己完成这项工作!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的最佳时间,例如在加密货币交易平台,游戏应用程序或聊天应用程序中,你想要在其中不断(即时的)更新数据。
在此示例中,我们将编写一个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可以发出的所有可能的请求,以及一些更复杂的概念,例如速率限制:
本翻译由 Cell Network 赞助支持。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!