公共 RPC
https://rpc.arc-scan.io 是面向 Arc 主网的免费 JSON-RPC 端点,它位于若干独立提供方之前,因此单个提供方的故障对你不可见。
https://rpc.arc-scan.io这个端点#
一个主机名、一条链、不需要任何凭证。它回答常规的读取方法,按策略拒绝一小串其他方法,并在你向它询问 web3_clientVersion 时把自己标识为 arcscan-rpc-gateway/1——你可以据此判断自己连到的是我们,而不是钱包里配置的某个别的端点。
| 属性 | 取值 |
|---|---|
| URL | https://rpc.arc-scan.io |
| 链 | 仅 Arc 主网——链 ID 5042,十六进制 0x13b2 |
| 传输方式 | 仅 HTTPS POST。GET 返回 405,并带 allow: POST, OPTIONS。 |
| 认证 | 无。没有密钥、没有账户、没有注册、没有请求头。 |
| 浏览器调用 | 允许——每个回答都带有 access-control-allow-origin: *。 |
| 费用 | 免费,并按调用方限速。 |
仅限主网
这个端点只服务链5042,别无其他——向它询问 net_version,它会回答 5042。Arcscan 没有面向 Arc Testnet 的公共 JSON-RPC 端点。如果你在测试网上开发,浏览器请用testnet.arc-scan.io在新标签页中打开,RPC 请用你自己的节点或提供方。你的第一次调用#
没有什么需要注册,因此第一次调用就是全部的入门过程。先问问你在和哪条链说话:
curl -s -X POST https://rpc.arc-scan.io \ -H 'content-type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId"}' { "jsonrpc": "2.0", "id": 1, "result": "0x13b2" }
然后是链头。Arc 大约每半秒产生一个区块,因此这个数字在你阅读它的时候就在变。
curl -s -X POST https://rpc.arc-scan.io \ -H 'content-type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber"}' { "jsonrpc": "2.0", "id": 1, "result": "0xe2a22d" }
批量请求#
一个由多次调用组成的 JSON 数组,会以一个结果数组作答,按 id 顺序排列。每个请求最多 50 个条目、131,072 字节;超过任一上限,整个请求会在其中任何一部分执行之前以 413 被拒绝。
curl -s -X POST https://rpc.arc-scan.io \ -H 'content-type: application/json' \ -d '[{"jsonrpc":"2.0","id":1,"method":"eth_chainId"}, {"jsonrpc":"2.0","id":2,"method":"eth_blockNumber"}]' [ { "jsonrpc": "2.0", "id": 1, "result": "0x13b2" }, { "jsonrpc": "2.0", "id": 2, "result": "0xe2a22e" } ]
批量请求不是一次快照
上面那两个高度相差一。每个条目都是各自独立处理的,而链在它们之间继续前进,因此批量请求绝不会给你某一时刻的一致视图。当你需要关于同一个区块的若干事实时,请把它们固定到某个区块号或哈希上,而不是固定到latest。它回答什么#
常规的 eth_ 读取方法都可用:区块、交易和收据查询、eth_getBalance、eth_call、eth_getLogs、eth_gasPrice、eth_estimateGas。有四个方法由端点自身回答,完全不发出外部请求——eth_chainId、net_version、web3_clientVersion 和 eth_accounts,最后一个返回空数组,因为我们不持有任何账户。
与其公布一份「哪些方法可用」的清单,不如这样问:凡是下面没有被拒绝的,都会被转发。没有任何来源提供的方法会返回 -32601,其 data.reason 为 method_not_served——这与按策略拒绝是不同的事实,它也会如实说明。
它拒绝什么#
拒绝是刻意的,而且每一次都说明是谁决定的以及为什么。原因是机器可读的:error.data.reason 为 refused_by_policy,error.data.policy 是下面这些 slug 之一——客户端应当读取它,以判断稍后再问是否可能有用。对于这里的每一个 slug,答案都是不可能。
| policy | 原因 | 实测示例 |
|---|---|---|
no_custody | 这个端点不持有任何密钥,也不会转发签名请求。 | eth_sendTransaction, eth_sign, eth_signTypedData_v4 |
namespace | 整个命名空间在这里都不提供服务。 | debug_traceTransaction, ots_getApiLevel |
cost | 回答非常大,而这个端点是计量的。 | trace_block |
no_transport | 仅 HTTP。这里没有订阅传输可以承载它。 | eth_subscribe, eth_unsubscribe |
single_leg | 这个端点背后只有一个来源提供它,因此公布它等于承诺一项可能毫无预警消失的能力。 | eth_getProof |
opacity | 回答会描述一个这个端点并不运营的节点,因此没有诚实的取值可以给出。 | net_peerCount, net_listening |
curl -s -X POST https://rpc.arc-scan.io \ -H 'content-type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"eth_sendTransaction","params":[{}]}' { "jsonrpc": "2.0", "id": 1, "error": { "code": -32601, "message": "arc-scan.io does not serve eth_sendTransaction on this endpoint. This is our own policy decision, not a limitation of the Arc network. This endpoint holds no keys and will not forward a signing request. Sign locally and use eth_sendRawTransaction.", "data": { "reason": "refused_by_policy", "method": "eth_sendTransaction", "policy": "no_custody", "documentation": "https://arc-scan.io/developers" } } }
拒绝也是 HTTP 200
上面每一次拒绝都返回200 OK,错误放在 JSON-RPC 的 error 对象里,这正是 JSON-RPC 规范所要求的。因此只盯着 HTTP 状态码的监控会把这一切都判为健康。请读取 error.code 和 error.data.reason,而不是状态行。发送一笔交易#
我们不持有任何密钥,因此每一个需要托管密钥的方法都会被拒绝——请在本地签名。已经签好名的交易可以广播:eth_sendRawTransaction 会被转发,而且它被刻意只发给恰好一个提供方并且从不重试,因为一个会重试广播的代理可能把你的交易提交两次。
读那条错误,不要盲目重发
already known 和 nonce too low 会原样从节点返回,而不会被抹平,两者通常都意味着你的交易已经在途中了。格式错误的载荷会返回 -32602,并带上节点自己的解码消息。故障转移#
这一个主机名背后是若干个独立的 Arc 主网提供方。在某一个上失败的调用会在另一个上重试;开始报错或对我们限速的提供方会被冷却并跳过;而这一切在你的响应里都看不见:你得到一个答案,或者一个诚实的错误,绝不会得到关于是哪个来源为你服务的暗示。我们不公布它们是谁。
有两个后果值得知道
只有一个提供方提供的方法会被拒绝而不是被服务(就是上面那一行single_leg)——一项只要有一个来源被冷却就会立刻消失的能力,不是我们会去承诺的能力。而如果所有来源都完全无法作答,你会得到 -32603,其 data.reason 为 unreachable,消息会说明不应对结果作任何假设,而不是给出一个读起来像「链上什么也没发生」的空结果。限制与错误#
请求按调用方限速。我们不在这里公布阈值——我们唯一能引用的数字是配置里的那个,而你实际遇到的是已部署的边缘——因此请把 429 当作信号,遵守它的 retry-after 并退避,而不要照着某个数字去调参。大小上限是确切的,并且写在拒绝消息本身里。
HTTP/1.1 429 Too Many Requests retry-after: 1 content-type: application/json { "jsonrpc": "2.0", "id": null, "error": { "code": -32005, "message": "arc-scan.io is rate limiting requests from this client. Retry shortly.", "data": { "reason": "edge_rate_limited", "retry_after_seconds": 1, "scope": "client" } } }
| HTTP · JSON-RPC 代码 | 发生了什么 |
|---|---|
405 · -32600 | 你用了 GET。JSON-RPC 请求必须使用 POST。 |
413 · -32600 | 请求超过了 131072 字节或 50 个批量条目;data.reason 为 request_too_large,两个上限都在消息里。 |
429 · -32005 | 来自同一调用方的请求过多。data.reason 为 edge_rate_limited;请遵守 retry-after。 |
200 · -32601 | 要么是我们拒绝的方法(data.reason 为 refused_by_policy,并带一个 policy slug),要么是没有任何来源提供的方法(method_not_served)。 |
200 · -32602 | 你的参数被拒绝了。这一条是节点自己的消息,原样透传。 |
200 · -32603 | 完全没有取得任何回答——data.reason 为 unreachable。消息会明确说明这一点,并且不应对结果作任何假设。 |