使用 WebSocket
这是一篇关于使用 WebSocket 和 Alchemy 向以太坊区块链发起请求的入门指南。
(opens in a new tab)WebSocket 与 HTTP 的对比
与 HTTP 不同,使用 WebSocket 时,你不需要在想要获取特定信息时不断发起请求。WebSocket 会为你维持一个网络连接(如果配置正确的话)并监听变化。
与任何网络连接一样,你不应假设 WebSocket 会永远保持打开状态而不中断,但手动正确处理掉线和重连可能会非常具有挑战性。WebSocket 的另一个缺点是,你无法在响应中获得 HTTP 状态码,只能获得错误消息。
Alchemy Web3 (opens in a new tab) 自动添加了对 WebSocket 故障和重试的处理,无需任何配置。
试一试
测试 WebSocket 最简单的方法是安装一个用于发起 WebSocket 请求的命令行工具,例如 wscat (opens in a new tab)。使用 wscat,你可以按如下方式发送请求:
注意:如果你有 Alchemy 账户,你可以将 demo 替换为你自己的 API 密钥。在此处注册免费的 Alchemy 账户! (opens in a new tab)
wscat -c wss://eth-mainnet.ws.alchemyapi.io/ws/demo
> {"jsonrpc": "2.0", "id": 0, "method": "eth_gasPrice"}
< {"jsonrpc": "2.0", "result": "0xb2d05e00", "id": 0}
如何使用 WebSocket
首先,使用你的应用程序的 WebSocket URL 打开一个 WebSocket。你可以通过在 你的仪表板 (opens in a new tab) 中打开应用程序页面并点击“View Key”(查看密钥)来找到你的应用程序的 WebSocket URL。请注意,你的应用程序的 WebSocket URL 与其 HTTP 请求的 URL 不同,但两者都可以通过点击“View Key”找到。
Alchemy API 参考 (opens in a new tab) 中列出的任何 API 都可以通过 WebSocket 使用。为此,请使用与作为 HTTP POST 请求主体发送的相同有效载荷,但改为通过 WebSocket 发送该有效载荷。
使用 Web3
在使用像 Web3 这样的客户端库时,过渡到 WebSocket 非常简单。只需在实例化 Web3 客户端时传递 WebSocket URL 而不是 HTTP URL 即可。例如:
const web3 = new Web3("wss://eth-mainnet.ws.alchemyapi.io/ws/your-api-key")
web3.eth.getBlockNumber().then(console.log) // -> 7946893
订阅 API
通过 WebSocket 连接时,你可以使用两个额外的方法:eth_subscribe 和 eth_unsubscribe。这些方法将允许你监听特定事件并立即收到通知。
eth_subscribe
为指定事件创建新的订阅。了解有关 eth_subscribe 的更多信息 (opens in a new tab)。
参数
- 订阅类型
- 可选参数
第一个参数指定要监听的事件类型。第二个参数包含取决于第一个参数的附加选项。下面描述了不同的订阅类型、它们的选项以及它们的事件有效载荷。
返回值
订阅 ID:此 ID 将附加到任何接收到的事件中,也可用于使用 eth_unsubscribe 取消订阅。
订阅事件
在订阅处于活动状态时,你将收到事件,这些事件是具有以下字段的对象:
jsonrpc:始终为 "2.0"method:始终为 "eth_subscription"params:具有以下字段的对象:subscription:由创建此订阅的eth_subscribe调用返回的订阅 ID。result:一个对象,其内容因订阅类型而异。
订阅类型
alchemy_newFullPendingTransactions
返回添加到待处理状态的所有交易的交易信息。此订阅类型订阅待处理交易,类似于标准的 Web3 调用 web3.eth.subscribe("pendingTransactions"),但不同之处在于它发出_完整的交易信息_而不仅仅是交易哈希。
示例:
> {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["alchemy_newFullPendingTransactions"]}
< {"id":1,"result":"0x9a52eeddc2b289f985c0e23a7d8427c8","jsonrpc":"2.0"}
< {
"jsonrpc":"2.0",
"method":"eth_subscription",
"params":{
"result":{
"blockHash":null,
"blockNumber":null,
"from":"0xa36452fc31f6f482ad823cd1cf5515177d57667f",
"gas":"0x1adb0",
"gasPrice":"0x7735c4d40",
"hash":"0x50bff0736c713458c92dd1848d12f3354149be1363123dae35e94e0f2a9d56bf",
"input":"0xa9059cbb0000000000000000000000000d0707963952f2fba59dd06f2b425ace40b492fe0000000000000000000000000000000000000000000015b1111266cfca100000",
"nonce":"0x0",
"to":"0xea38eaa3c86c8f9b751533ba2e562deb9acded40",
"transactionIndex":null,
"value":"0x0",
"v":"0x26",
"r":"0x195c2c1ed126088e12d290aa93541677d3e3b1d10f137e11f86b1b9227f01e3b",
"s":"0x60fc4edbf1527832a2a36dbc1e63ed6193a6eee654472fbebbf88ef1750b5344"},
"subscription":"0x9a52eeddc2b289f985c0e23a7d8427c8"
}
}
newHeads
只要有新区块头添加到链中,就会发出一个事件,包括在链重组期间。
当发生链重组时,此订阅将发出一个包含新链所有新区块头的事件。特别是,这意味着你可能会看到发出多个具有相同高度的区块头,当发生这种情况时,应将较晚的区块头视为重组后的正确区块头。
示例:
> {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["newHeads"]}
< {"jsonrpc":"2.0","id":2,"result":"0x9ce59a13059e417087c02d3236a0b1cc"}
< {
"jsonrpc": "2.0",
"method": "eth_subscription",
"params": {
"result": {
"extraData": "0xd983010305844765746887676f312e342e328777696e646f7773",
"gasLimit": "0x47e7c4",
"gasUsed": "0x38658",
"logsBloom":
"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"nonce": "0x084149998194cc5f",
"number": "0x1348c9",
"parentHash": "0x7736fab79e05dc611604d22470dadad26f56fe494421b5b333de816ce1f25701",
"receiptRoot": "0x2fab35823ad00c7bb388595cb46652fe7886e00660a01e867824d3dceb1c8d36",
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"stateRoot": "0xb3346685172db67de536d8765c43c31009d0eb3bd9c501c9be3229203f15f378",
"timestamp": "0x56ffeff8",
"transactionsRoot": "0x0167ffa60e3ebc0b080cdb95f7c0087dd6c0e61413140e39d94d3468d7c9689f"
},
"subscription": "0x9ce59a13059e417087c02d3236a0b1cc"
}
}
logs
发出属于新添加区块且符合指定过滤标准的日志。
当发生链重组时,属于旧链上区块的日志将再次发出,其 removed 属性设置为 true。此外,还会发出属于新链上区块的日志,这意味着在重组的情况下,可能会多次看到同一笔交易的日志。
参数
- 具有以下字段的对象:
address(可选):表示地址的字符串或此类字符串的数组。- 仅发出从这些地址之一创建的日志。
topics:主题说明符数组。- 每个主题说明符要么是
null,要么是表示主题的字符串,要么是字符串数组。 - 数组中非
null的每个位置,都会将发出的日志限制为仅包含在该位置具有给定主题之一的日志。
- 每个主题说明符要么是
主题规范的一些示例:
[]:允许任何主题。[A]:A 在第一个位置(以及之后的任何内容)。[null, B]:任何内容在第一个位置,B 在第二个位置(以及之后的任何内容)。[A, B]:A 在第一个位置,B 在第二个位置(以及之后的任何内容)。[[A, B], [A, B]]:(A 或 B)在第一个位置,(A 或 B)在第二个位置(以及之后的任何内容)。
示例:
> {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["logs", {"address": "0x8320fe7702b96808f7bbc0d4a888ed1468216cfd", "topics": ["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"]}]}
< {"jsonrpc":"2.0","id":2,"result":"0x4a8a4c0517381924f9838102c5a4dcb7"}
< {
"jsonrpc": "2.0",
"method": "eth_subscription",
"params": {
"subscription": "0x4a8a4c0517381924f9838102c5a4dcb7",
"result": {
"address": "0x8320fe7702b96808f7bbc0d4a888ed1468216cfd",
"blockHash": "0x61cdb2a09ab99abf791d474f20c2ea89bf8de2923a2d42bb49944c8c993cbf04",
"blockNumber": "0x29e87",
"data": "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003",
"logIndex":"0x0",
"topics":["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"],
"transactionHash": "0xe044554a0a55067caafd07f8020ab9f2af60bdfe337e395ecd84b4877a3d1ab4",
"transactionIndex": "0x0"
}
}
}
eth_unsubscribe
取消现有订阅,以便不再发送任何事件。
参数
- 订阅 ID,即先前从
eth_subscribe调用返回的 ID。
返回值
如果成功取消订阅,则返回 true;如果不存在具有给定 ID 的订阅,则返回 false。
示例:
请求
curl https://eth-mainnet.alchemyapi.io/v2/your-api-key
-X POST
-H "Content-Type: application/json"
-d '{"id": 1, "method": "eth_unsubscribe", "params": ["0x9cef478923ff08bf67fde6c64013158d"]}'
结果
{
"jsonrpc": "2.0",
"id": 1,
"result": true
}
免费 注册 Alchemy (opens in a new tab),查看 我们的文档 (opens in a new tab),如需获取最新消息,请在 推特 (opens in a new tab) 上关注我们。
