Logo
新用户订阅 RPC,首月享 6.5 折优惠查看优惠
OnFinality Learn
网络与协议指南阅读约 12 分钟

Solana 链 ID:为什么它是创世哈希,而不是 101

Solana 没有数字链 ID。了解 getGenesisHash 如何识别集群、为什么 101 是错误的,以及如何从任意 RPC 端点推导 CAIP-2 链 ID。

TL;DR

Solana 没有 EVM 风格的数字链 ID。集群由其创世哈希标识,getGenesisHash 返回一个 44 字符的 Base58 字符串,而 CAIP-2 链引用就是该哈希截断后的前 32 个字符,例如 mainnet-beta 对应 solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp。在 Solana 端点上,eth_chainId 和 getChainId 会返回 -32601 Method not found,因此广为流传的链 ID 101(实际上是 EtherInc)并不是 Solana 的标识符。验证 Solana 环境意味着从每个端点收集创世哈希,将每个哈希缩减为 32 字符引用,并在集合中出现多个值时判定检查失败。

简短回答:Solana 没有数字链 ID

如果你在寻找 Solana 链 ID,诚实的答案是:Solana 并没有以太坊开发者所期望的那种链 ID。Solana 交易中没有 chainId 字段,Solana 端点上没有 eth_chainId 方法,协议也不会把任何整数混入签名。区分不同 Solana 集群的标识符是创世哈希:即区块零的 Base58 编码哈希,由 getGenesisHash 返回。

该哈希长度为 44 个字符。多链钱包和 dApp 使用的链无关标准 CAIP-2 并不会原样使用它,而是取前 32 个字符作为链引用,并加上命名空间前缀,例如 mainnet-beta 对应 solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp。Solana CAIP-2 命名空间规范将其定义为 truncate(genesisHash, 32),并通过调用 getGenesisHash 来解析;CAIP-2 规范则定义了通用的 namespace:reference 字符串格式,结果就填入其中。

因此,你在配置中实际会看到两个值:集群名称(mainnet-beta、devnet、testnet)和 CAIP-2 链 ID(solana: 加上创世哈希的前 32 个字符)。如果某个教程或注册表告诉你 Solana 的链 ID 是一个数字,那这个数字是从 EVM 惯例中借用的。

为什么 Solana 不需要数字链 ID

以太坊需要链 ID 来实现重放保护。在 EIP-155 之前,签名字段是 (nonce, gasprice, startgas, to, value, data)——没有任何字段标识链,因此为某个 EVM 网络签名的交易可以在另一个网络上重放。EIP-155 将 CHAIN_ID 纳入签名哈希,并以 CHAIN_ID * 2 + 35 或 CHAIN_ID * 2 + 36 的形式编码进 v,使链 ID 成为签名本身的一部分。

Solana 的交易格式以不同方式解决同一问题。Solana 交易是由编译后的指令和签名组成的消息,按 Solana 自身的线格式对该消息进行签名。它不是带有 v 值的 RLP 结构,也没有用于数字链标识符的字段。集群隔离来自提交环节:交易被发送到参与某个集群的端点,只有当其近期区块哈希存在于该集群的账本中时,交易才有效。

其后果是实践性的,而非哲学性的。你得到的是一个连接级标识符:你的端点实际所服务集群的创世哈希。这比配置常量更有力,因为它是从节点测量出来的,而不是在配置文件中声明的。

三个集群及其创世哈希

Solana 目前公布三个公共集群,每个都有自己的创世哈希、自己的 API 端点以及不同的用途。下表是在 2026-10-19 对每个公共端点调用 getGenesisHash,并将结果截断为 32 个字符以推导 CAIP-2 引用后得到的。

注意命名。生产集群称为 mainnet-beta,而不是 mainnet,该名称出现在主机名 api.mainnet-beta.solana.com 中。在你自己的配置中,应将单独的 mainnet 视为有歧义,因为钱包或库可能将其映射为与集群报告不同的字符串。

  • mainnet-beta — 5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d → solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp。生产环境,真实 SOL,真实价值。
  • devnet — EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG → solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1。应用测试,由水龙头提供资金,可能被重置。
  • testnet — 4uhcVJyU9pJkvQyS88uRDiswHXSCkY3zQawwpjk2NsNY → solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z。验证者和核心版本压力测试,可能被重置。
  • 上述三个 32 字符引用与 Solana CAIP-2 命名空间规范中的测试用例一致——这是一个有用的交叉检查:如果你的工具为这些集群生成了其他结果,那么截断或编码步骤就是错误的。

数字 101 的来源,以及为什么它是错误的

搜索 Solana 链 ID,你会发现有人声称它是 101,有时是 900,偶尔是 501。这三个都是属于无关网络的 EVM 链 ID。2026-10-19,公开的以太坊链 ID 注册表列出了 2,818 条链:101 是 EtherInc,900 是 Garizon Testnet Stage0,501 是 Columbus Test Network。没有一个名为 Solana,因为 Solana 不是 EVM 链,也从不注册 eip155 链 ID。

这种混淆有可预测的起源。一些钱包和 SDK 对 EVM 网络接受数字 chainId,对非 EVM 网络接受 CAIP-2 字符串,因此少数工具为 Solana 集群分配了占位数字,以填充单个数字字段。这些占位符是实现细节:不是共识标识符,在不同供应商之间不稳定,两个工具完全可能对哪个数字映射到哪个集群存在合理分歧。

这就是为什么你绝不应通过比较数字来验证 Solana 目标。正确的检查是 32 字符的 CAIP-2 引用,或完整的 44 字符创世哈希,且必须从你即将使用的端点获取。

将任意端点解析为其链 ID

下面的脚本接受任意 Solana RPC URL,向端点询问其创世哈希,推导 CAIP-2 链 ID,并针对可选的预期集群返回判定结果。它还触发两个阴性对照 eth_chainId 和 getChainId,以表明 Solana 的 JSON-RPC 接口两者都未实现。

// solana-chain-id.mjs — Node.js 18+
// Usage: node solana-chain-id.mjs <RPC_URL> [mainnet-beta|devnet|testnet]
const [rpcUrl, expected] = process.argv.slice(2);
if (!rpcUrl) { console.error("usage: node solana-chain-id.mjs <RPC_URL> [cluster]"); process.exit(2); }

// Authoritative references: ChainAgnostic/namespaces solana caip2 => truncate(genesisHash, 32)
const KNOWN = {
  "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp": "mainnet-beta",
  "EtWTRABZaYq6iMfeYKouRu166VU2xqa1": "devnet",
  "4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z": "testnet",
};

async function rpc(method, params = []) {
  const started = Date.now();
  const res = await fetch(rpcUrl, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
    signal: AbortSignal.timeout(15000),
  });
  return { http: res.status, ms: Date.now() - started, body: await res.json() };
}

const genesis = await rpc("getGenesisHash");
if (genesis.body.error) {
  console.error(JSON.stringify({ rpcUrl, error: genesis.body.error }, null, 2));
  process.exit(1);
}
const fullHash = genesis.body.result;      // 44 Base58 characters
const chainRef = fullHash.slice(0, 32);    // CAIP-2 reference = first 32 characters
const cluster = KNOWN[chainRef] ?? "unknown";

// Negative controls: neither method exists in Solana's JSON-RPC surface.
const ethChainId = await rpc("eth_chainId");
const getChainId = await rpc("getChainId");

console.log(JSON.stringify({
  rpcUrl,
  httpStatus: genesis.http,
  latencyMs: genesis.ms,
  genesisHash: fullHash,
  genesisHashLength: fullHash.length,
  caip2ChainId: `solana:${chainRef}`,
  cluster,
  expectedCluster: expected ?? null,
  verdict: !expected ? "observed" : expected === cluster ? "match" : "MISMATCH",
  eth_chainId_error: ethChainId.body.error ?? null,
  getChainId_error: getChainId.body.error ?? null,
}, null, 2));

三个公共集群的实测输出

以下是 2026-10-19 针对公共 solana.com 端点捕获的实际运行结果。每个值都在运行期间从节点返回;延迟是单次采样,因此应视为参考值,而非基准测试。

$ node solana-chain-id.mjs https://api.mainnet-beta.solana.com mainnet-beta
{
  "rpcUrl": "https://api.mainnet-beta.solana.com",
  "httpStatus": 200,
  "latencyMs": 83,
  "genesisHash": "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d",
  "genesisHashLength": 44,
  "caip2ChainId": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
  "cluster": "mainnet-beta",
  "verdict": "match",
  "eth_chainId_error": { "code": -32601, "message": "Method not found" },
  "getChainId_error": { "code": -32601, "message": "Method not found" }
}

$ node solana-chain-id.mjs https://api.devnet.solana.com mainnet-beta
{
  "rpcUrl": "https://api.devnet.solana.com",
  "caip2ChainId": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
  "cluster": "devnet",
  "expectedCluster": "mainnet-beta",
  "verdict": "MISMATCH"
}

解读结果:匹配、不匹配与未知集群

第二次运行才是关键。一个 devnet 端点被要求证明自己是 mainnet-beta 时,会返回有效的创世哈希、有效的 CAIP-2 字符串、HTTP 200,且完全没有错误;除了比较之外,所有检查都通过。只有 MISMATCH 判定能发现问题,这就是为什么仅停留在 getHealth 的健康检查不够:devnet 节点完全健康,只是账本不对。

unknown 集群判定是另一种信号:端点响应了 getGenesisHash,但返回的引用不是三个公共集群之一。这可能是合法的,因为本地 solana-test-validator 实例、私有集群和分叉都有自己的创世哈希。应将 unknown 视为不可信输入,并审慎决定是否接受。

两个 -32601 Method not found 响应是实证答案。eth_chainId 是 EVM 方法,getChainId 不属于 Solana 的 JSON-RPC 接口,因此 Solana 节点无法通过它们产生数字链 ID。如果某个工具仍然报告了数字,那它是在读取本地常量或通过 CAIP-2 映射进行转换。

在信任整个环境之前进行验证

在生产环境中,你很少只验证一个端点;你会验证一个端点池或移动端构建中嵌入的端点。收集所有端点上不同的 CAIP-2 引用集合,并断言该集合恰好只有一个成员。其他任何情况都是配置缺陷,最终会把已签名交易发送到错误的集群。

在客户端,将钱包或 RPC 端点返回的完整 32 字符引用与你期望的引用进行比较。绝不要比较短前缀:solana:5ey 和 solana:5ez 是不同的字符串,前缀匹配正是仅限主网的操作最终出现在测试集群上的原因。

  • 从列表中的每个端点收集 getGenesisHash,而不仅仅是第一个响应的端点。
  • 将每个结果缩减为 32 字符引用,并按引用分组,而不是按主机名或配置中的标签分组。
  • 如果集合大小大于一,则部署失败,并列出每个不一致的端点。
  • 在服务目录中将引用与端点一起记录,因为 DNS 名称和负载均衡器可能在没有通知的情况下被重新指向。
  • 按计划重新运行检查。devnet 和 testnet 可能被重置,重置会改变账本而不改变主机名。

非 EVM 链的钱包与 dApp 集成规则

CAIP-2 之所以存在,是因为单个数字字段无法描述每个生态系统。其语法是 namespace:reference,每个命名空间定义如何解析引用:对于 eip155,它是来自 eth_chainId 的十进制链 ID;对于 solana,它是来自 getGenesisHash 的截断创世哈希。仅存储数字的多链钱包无法正确表示 Solana。

在实践中,将 CAIP-2 字符串作为网络的主键,并将任何遗留数字字段仅作为显示标签推导。网络切换变成对引用的字符串比较;日志应包含它;缓存应以它为键,这样主网和 devnet 的响应就不会冲突。

再养成一个习惯:存储完整的 44 字符创世哈希用于对账和分析,存储 32 字符引用用于线格式标识。引用是截断结果,因此它是用于标识的约定,而不是密码学承诺;保留完整哈希意味着未来的截断方案不会悄悄将两条链合并为一个键。

端点无法响应时该怎么办

如果 getGenesisHash 失败,不要回退到配置的数字或硬编码的集群标签。相反,应区分失败模式,因为它们对你的应用意味着不同的事情。

如果你需要经过验证的端点而不是公共端点,Solana RPC 端点指南涵盖了选择与配置,Solana 网络页面则在更高层面描述了该网络。本文刻意不推荐提供商:使用哪个端点是服务决策,而如何证明它服务哪条链是协议问题。

  • 连接被拒绝或超时 — 端点宕机或网络路径被阻断。尝试池中的下一个端点,但在使用前仍要验证其创世哈希。
  • HTTP 429 或 403 — 你被限流或封禁。这是访问问题,不是身份问题;在请求成功之前,该端点的集群对你来说仍然未知。有关重试行为,请参阅 Solana RPC 速率限制与 429 错误。
  • -32601 Method not found — 该端点根本不是 Solana JSON-RPC 节点,或者是一个只转发部分方法的代理。不要假设其集群。
  • 返回有效结果但引用意外 — 端点有响应,但属于与你预期不同的集群。将其视为 MISMATCH 并停止。

局限性与假设

Solana CAIP-2 命名空间规范被标记为草案,最后更新于 2023 年 3 月,因此截断规则是事实上的约定,而非最终标准。目前各实现对此一致,本文的三个引用也与规范自身的测试用例匹配,但应重新检查规范,而不是将其视为冻结不变。

上述延迟是来自单台机器的单次采样。它们表明该调用开销很低,而不是端点很快;公共端点有限流且会无通知变化,这就是生产环境需要验证加私有端点的原因。

集群重置也是真实存在的。devnet 和 testnet 被记录为可能发生账本重置,重置可能改变创世哈希。将任何硬编码的非生产哈希视为带过期时间的缓存,从端点刷新,绝不要当作永久常量。

相关阅读与后续步骤

如果你的工作跨越 EVM 和非 EVM 链,配套文章是 EVM 节点身份:chainId、net_version 与 clientVersion,它涵盖了同一问题的数字方面。对于手动配置的钱包网络,Base RPC MetaMask 设置:链 ID 字段展示了 EVM 字段集。

确认链之后,接下来的问题是何时可以信任结果。Solana 承诺级别:processed、confirmed、finalized解释了确认状态,Solana 版本化交易与 getBlock 解析涵盖了如何解码返回内容。在基于链 ID 检查构建对账逻辑之前,这两篇都值得一读。

关于经过验证的访问的容量规划,请参阅 RPC 定价和 API 服务概览,并浏览 OnFinality Learn 中心获取更广泛的协议与运维指南。

永远不用担心基础设施

OnFinality 消除了 DevOps 的繁重工作,让您能够更聪明、更快地构建。

开始