Logo
新用户订阅 RPC,首月享 6.5 折优惠查看优惠
OnFinality Learn
基础设施与运维阅读约 11 分钟

什么是非托管钱包?密钥控制、签名与验证

实用解释非托管钱包:密钥控制如何运作,签名与托管账户有何不同,以及如何针对实时 RPC 端点验证自托管行为。

TL;DR

非托管钱包是指授权支出的私钥由用户生成并持有,而非由平台持有的钱包。钱包软件是一个签名客户端:它从密钥派生地址、构建交易,并在本地签名后通过 RPC 端点广播。本文解释密钥控制模型,将其与托管账户对比,并提供可运行的流程来验证签名发生在客户端,且 RPC 端点只能看到已签名的交易。文章还涵盖助记词恢复的限制、常见故障模式,以及如何选择不会削弱自托管的基础设施。

非托管钱包的定义与范围

非托管钱包,也称为自托管钱包,是一种软件或硬件,其中控制地址的私钥由用户创建并存储在用户控制之下。钱包并不持有代币;它持有的是在区块链上授权状态变更的能力。任何能为某个地址生成有效签名的人,就控制着该地址上的资产。

本文涵盖这种控制的技术机制:密钥生成、地址派生、交易签名、通过 RPC 端点广播,以及从助记词恢复。本文不推荐特定钱包品牌。目标是给你一个可以测试的心智模型,以及一个可以在任何 EVM 兼容链和 RPC 提供商上运行的流程。

  • 非托管意味着用户持有密钥,而非用户持有代币。
  • 钱包是客户端;区块链是真相来源。
  • RPC 端点中继已签名的交易,但绝不应需要你的私钥。

验证流程的假设与前提条件

以下示例假设使用 EVM 兼容网络、Node.js 18 或更高版本,以及测试网上有资金的测试账户。你需要目标链的 RPC_URL;可从提供商仪表板或 OnFinality API 服务获取。切勿在教程脚本中使用主网私钥。

你还需要对交易结构有基本了解。如果对 nonce、gas 和 chain ID 不熟悉,请先阅读区块链 nonce 的解释和 RPC 端点指南,然后再继续。

  • 签名示例需要 Node.js 18+ 和 npm。
  • 原始 JSON-RPC 检查需要 curl。
  • 一个测试网账户,余额较少,其私钥存储在环境变量中,而非源代码中。

密钥控制与托管账户访问有何不同

在托管模式下,平台持有密钥,而你持有登录凭证。当你请求提现时,平台用自己的密钥签名。如果平台失败,你的访问可能被暂停、限速或丢失。在非托管模式下,你持有密钥,平台(如果有)仅提供连接。

实际差异体现在签名时。非托管钱包在本地构建交易负载,用私钥签名,然后仅将已签名的字节发送到 RPC 端点。端点可以看到交易并可能记录它,但没有密钥就无法更改签名或转移资金。

  • 托管:平台签名;你进行身份验证。
  • 非托管:你签名;网络验证。
  • 非托管流程中的 RPC 提供商是传输层,而非托管方。

从助记词到广播的签名流水线

非托管钱包遵循确定性流水线。助记词被拉伸成主密钥,从中派生出账户密钥和地址。钱包构建交易,包含正确的 nonce、chain ID、gas 参数、接收方和金额。它在本地对该负载进行哈希和签名,然后调用 RPC 端点上的 eth_sendRawTransaction。

端点验证交易格式,将其转发到网络,并返回交易哈希。确认是单独的步骤:钱包轮询 eth_getTransactionReceipt,直到某个区块包含该交易。端点在任何时候都不会收到私钥。

const { ethers } = require("ethers");

async function signAndBroadcast() {
  const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
  const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);

  const tx = {
    to: process.env.RECIPIENT,
    value: ethers.parseEther("0.001"),
    chainId: Number(process.env.CHAIN_ID)
  };

  const signed = await wallet.signTransaction(tx);
  console.log("Signed locally. First 20 bytes:", signed.slice(0, 42));

  const response = await provider.broadcastTransaction(signed);
  console.log("Broadcast hash:", response.hash);

  const receipt = await response.wait();
  console.log("Included in block:", receipt.blockNumber);
}

signAndBroadcast().catch(console.error);

可运行的检查:RPC 端点绝不会收到你的密钥

你可以用两个 curl 调用确认职责分离。第一个向端点查询你地址的当前 nonce;第二个提交预签名的原始交易。两个调用都不包含私钥。如果提供商要求提供私钥来发送交易,那就是托管模式,应视为危险信号。

先运行 nonce 查询,然后用上面的脚本离线签名,再提交原始交易。将占位符替换为你自己的值。

curl -s -X POST "$RPC_URL" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_getTransactionCount","params":["0xYOUR_ADDRESS","pending"]}'

curl -s -X POST "$RPC_URL" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"eth_sendRawTransaction","params":["0xSIGNED_RAW_TRANSACTION"]}'

预期验证结果及其解读

正确的非托管流程会产生三个可观察的结果。nonce 查询返回你地址的十六进制计数。签名脚本打印出已签名的负载,而不为获取密钥材料联系网络。广播调用返回交易哈希,稍后的收据查询返回区块号和状态。

将每个结果记录在表格中,以便比较提供商或在失败后重试。不要填写你未观察到的值;该表格是测量模板,而非对任何提供商的声明。

  • Nonce 结果:来自 eth_getTransactionCount 的十六进制字符串。
  • 已签名负载:来自 signTransaction 的本地输出,无网络依赖。
  • 广播结果:来自 eth_sendRawTransaction 的交易哈希。
  • 收据结果:来自 eth_getTransactionReceipt 的区块号和状态。

用于比较 RPC 行为的结果表流程

当你测试多个 RPC 端点时,保持已签名交易不变,仅更改 RPC_URL。这将传输行为与签名行为隔离开来。表格中只填写观察到的值。

端点标签返回的 Nonce返回的广播哈希收据区块收据状态备注
提供商 A
提供商 B
提供商 C

如果广播成功但收据从未出现,交易可能处于待处理、被丢弃或被网络拒绝。在假设端点故障之前,先在区块浏览器上检查哈希。对于生产工作负载,比较专用节点选项并查看 RPC 定价,以免速率限制被误认为钱包故障。

排查常见的非托管钱包故障

大多数非托管钱包问题分为四类:密钥处理、交易构建、端点连接和网络状态。在更改任何内容之前,先将它们区分开。

如果签名失败,密钥或派生路径有误。如果广播因 nonce 错误失败,同一地址的另一笔交易正在待处理。如果端点超时,钱包无法访问网络,但你的密钥不受影响。如果收据缺失,交易可能因 gas 不足或从内存池中被丢弃。

  • Nonce 过低:等待待处理交易或替换它。
  • 资金不足:分别检查余额和 gas 价格。
  • Chain ID 不匹配:确认钱包网络与 RPC_URL 匹配。
  • 助记词被拒绝:重试前验证单词顺序和语言。

恢复限制与责任权衡

助记词是密钥材料的备份,而非账户恢复服务。如果助记词丢失且设备故障,资金将无法恢复。如果助记词泄露,任何人都可以签名。这是自托管的核心权衡:你消除了平台风险,接受了操作风险。

非托管钱包也依赖基础设施。钱包可以离线签名,但需要 RPC 端点来读取余额和广播。因此,选择可靠的端点是自托管运维的一部分,而非独立的问题。当你从测试转向生产时,请审查网络覆盖和专用节点选项。

安全自托管运维的后续步骤

先在测试网上开始,运行签名和广播流程,并记录结果表。然后尽可能使用硬件签名器转移到小额主网金额。将私钥排除在 shell 历史记录和源代码控制之外,并在每次练习后轮换测试密钥。

关于端点选择,请使用 RPC Assistant 关于 Web3 项目最佳 RPC 提供商的指南和多链 RPC 端点指南。如果你需要可预测的吞吐量,在提交生产钱包流程之前,比较专用节点产品和定价。

  • 先在测试网上测试签名和广播。
  • 离线存储助记词,切勿将其输入网站。
  • 将端点健康监控与钱包软件分开。

永远不用担心基础设施

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

开始