Infura 以太坊 API 入门教程

使用Infura的API访问以太坊网络数据

因此,你想使用Infura的API访问以太坊网络-你将如何做?首先,你需要确保你拥有Infura帐户(查看此教程 申请账号!)接下来,需要确定要使用哪个接口 - Infura在HTTPSWebSocket接口上都支持JSON-RPC。在本教程中,我们介绍使用每个接口的原因,以及将通过Node.js示例介绍两种访问以太坊API的方法。

HTTPS(HTTPS)

HTTP/HTTPS 是“单向”的 - 客户端发送请求,然后服务器发送响应 - 其“无状态”关联,这意味着每个请求都获得一个响应,然后终止连接。如果你获得仅需要收集一次的数据正在访问旧数据,则需要使用HTTPS接口。你会看到HTTPS在简单的RESTful应用程序里经常使用。

看一个示例

在此示例中,我们将编写一个使用Rinkeby节点的Node.js程序,并使用eth_getBlockByNumber将RPC请求发送到Infura以获取最新的区块数据。从那里,我们将把块号从十六进制转换为整数,并将整数块号打印到终端。准备好了?我们开始吧!

编写此代码的第一步是安装Node(如果尚未安装,则可以使用npmdownload)、DotEnv、以及相关的依赖。如果你不熟悉dotenv,这是一个不会上传到GitHub的单独文件,可确保你的Project ID和Project Secret(配置在环境变量中)在代码中仍然是保密!要了解更多请查看此篇文章

现在,我们已经完成了安装,继续创建 app.js 文件,并在开头引入dotenvrequest。用与访问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. method(方法:即POST/GET/etc)。

  3. headers(请求头)

  4. body(请求体)

  5. 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 以及引入必需的依赖 -dotenvws(用于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 赞助支持。

  • 发表于 4天前
  • 阅读 ( 96 )
  • 学分 ( 211 )
  • 分类:以太坊

相关问题

0 条评论

请先 登录 后评论
翻译小组
翻译小组

首席翻译官

21 篇文章, 1902 学分