必须用 types.neweip155signer,因 homesteadsigner 不含 chain id,v 值固定为 27/28,而 eip-155 要求 v = 35 + chainid×2;节点会拒收旧签名并报 invalid sender 或 rlp 非规范整数错误。

必须用 types.NewEIP155Signer,不能用 types.HomesteadSigner{} —— 后者在现代网络(主网、测试网)下会签名失败或被节点拒绝。
为什么 types.HomesteadSigner{} 会出错
Homestead 签名器不带 chain ID,生成的 v 值固定为 27 或 28,而 EIP-155 要求根据 chain ID 动态计算 v(例如主网是 v = 35 + chainID*2)。节点收到旧签名会直接返回 invalid sender 或 invalid v, r, s values 错误。
- 常见错误现象:
rlp: non-canonical integer (leading zero bytes) for *big.Int(常因 chain ID 传nil或 0 导致) - 主网 chain ID 是
1,Rinkeby 已停用,Sepolia 是11155111,Goerli 是5(已弃用),务必核对目标网络实际值 - 如果你硬传
types.HomesteadSigner{},types.SignTx内部不会校验 chain ID,但签名后交易无法广播
types.SignTx 的三个参数怎么填
签名函数签的是原始交易结构体,不是哈希或字符串。关键在于传对 signer 和私钥类型:
- 第一个参数:
*types.Transaction,用types.NewTransaction构造,注意nonce必须是该地址当前 pending + queued 交易数(可查eth_getTransactionCount) - 第二个参数:
types.Signer,只接受types.NewEIP155Signer(big.NewInt(chainID)),chainID必须是*big.Int类型,不能是 int 或 uint64 - 第三个参数:
*ecdsa.PrivateKey,从 hex 字符串解析时要用hexutil.Decode→crypto.ToECDSA两步,少一步会 panic
示例片段:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
tx := types.NewTransaction(nonce, toAddr, value, gasLimit, gasPrice, data) signer := types.NewEIP155Signer(big.NewInt(1)) // 主网 signedTx, err := types.SignTx(tx, signer, privateKey)
私钥来源:明文 vs keystore 解密
明文私钥字符串(64 字符 hex)适合开发调试;keystore+password 方式更安全,但需额外依赖 github.com/ethereum/go-ethereum/accounts/keystore。
- 明文路径:
"0x..."或纯 hex(去掉0x),hexutil.Decode自动处理前缀 - keystore 路径:读取 JSON 文件内容为
[]byte,用keystore.DecryptKey(keystoreBytes, password)得到*keystore.Key,再取.PrivateKey - 别漏掉 error 检查:keystore 解密失败时返回
nil私钥,后续SignTx会 panic
签名后怎么发出去
签名完得到 *types.Transaction,必须 RLP 编码成字节再 hex 化,才能调用 eth_sendRawTransaction:
- 编码用
rlp.EncodeToBytes(signedTx),不是signedTx.Data()或signedTx.Hash().Hex() - 结果是 raw tx hex string,形如
"0xf86d80843b9aca0082520894...",直接 POST 给 RPC 节点 - 如果用
ethers.js验证该签名,注意 Golang 签名的v值比 ethers 默认高(因 chain ID 加成),验签时需传入正确 chain ID
最易忽略的一点:签名本身不检查 nonce 是否重复、gas 是否足够、from 是否有余额——这些全由节点在广播时校验。离线签名只是把「我同意这笔交易」这个声明打包好,其余全靠你提前算准。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










