Golang调用ElectrumX JSON-RPC报Invalid scripthash错误排查
问题原因
你的代码存在两个核心问题,会触发ElectrumX节点返回invalid error map[code:1 message:Invalid scripthash]错误:
- 参数传递方式不符合Go标准库
net/rpc/jsonrpc的使用规范:该库的Call方法会将第二个传入参数作为RPC请求params字段的元素做二次JSON序列化,你直接传入拼接完成的JSON字符串,最终发往节点的请求参数会是一个字符串值,而非协议要求的包含scripthash字段的结构化对象,节点解析参数时无法识别到合法的scripthash,直接返回参数错误。 - 你需要校验scripthash的生成逻辑:ElectrumX协议明确要求scripthash为「脚本公钥(scriptPubKey)做SHA256哈希后的小端序十六进制字符串」,如果生成时误用大端序输出哈希值,哪怕参数传递格式正确,也会返回无效scripthash错误。
- 额外逻辑错误:
Call方法的第三个参数是接收RPC返回结果的指针,你传入空字符串既无法正常获取节点返回的余额数据,也可能触发序列化异常。
修正后的可运行代码
package main import ( "log" "net/rpc/jsonrpc" ) func main() { rpcClient, err := jsonrpc.Dial("tcp", "de.poiuty.com:50001") if err != nil { log.Fatal(err) } defer rpcClient.Close() // 注意:此处scripthash必须替换为符合小端序要求的合法值 scripthash := "8b01df4e368ea28f8dc0423bcf7a4923e3a12d307c875e47a0cfbf90b5c39161" // 直接传入结构化参数,不要手动拼接JSON字符串 reqParams := map[string]string{ "scripthash": scripthash, } var resp map[string]uint64 // 第三个参数传入接收返回值的指针 err = rpcClient.Call("blockchain.scripthash.get_balance", reqParams, &resp) if err != nil { log.Fatalf("RPC调用失败: %v", err) } log.Printf("账户余额(单位:聪): 已确认=%d,未确认=%d", resp["confirmed"], resp["unconfirmed"]) }
scripthash生成校验规则
如果修正参数传递逻辑后仍然报错,按以下步骤检查scripthash生成流程:
- 先获取目标地址对应的完整scriptPubKey原始字节,不要缺失或多余前缀字节
- 对scriptPubKey原始字节做SHA256运算,得到32字节长度的哈希结果
- 将32字节哈希结果整体反转字节序(满足小端序要求),再转为小写十六进制字符串,即为符合ElectrumX要求的合法scripthash
内容的提问来源于stack exchange,提问作者Timofey Belanenko
相关产品推荐
相关产品推荐

