我正在尝试使用 geth golang 库验证从客户端传入的签名。我正在从我的一个加密猫帐户(我可以在请求中看到它)获取样本数据(签名/地址)。如果我将打击凭据粘贴到https://etherscan.io/verifySig,它会得到验证,所以我知道参数是正确的。
我的代码:
import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
)
sig := 0x80f5bac5b6300ed64835d5e2f167a368c892ccc2d0e252bc84befbcb093f5a2d36294b95d86683cec778c8c796049933c04c71576c56c1d6e9a9fa10342beca31c
data := "Cryptokitties"
decoded = hexutil.MustDecode(sig) // j8aUTtPid0ZnNa/s4Ef5gisYYh1bCeLSmFrtJtDjNRRqxShUr+1A3BVgoAPwiZ+lKN0POB1JOdVhVHI9tcHmABs=
hash := crypto.Keccak256([]byte(data)) // "ljQQTm25oqIbD+LMl70aRUcTzXCeeDGfkRj9YJYsgKY="
pubKey, err := crypto.Ecrecover(hash, sig) // error: "invalid signature recovery id"
我确定我错过了一些简单的东西,但不确定在哪里看。
**更新
在查看了一些答案后我尝试了什么:
像这样更改消息:
fmt.Sprintf("\u0019Ethereum Signed Message:\n%d%s", len(data), data)
//"\u0019Ethereum Signed Message:\n13Cryptokitties"
在散列之前对消息进行十六进制编码:
data=hexutil.Encode(data)
将上述两者结合起来,因此首先添加“以太坊签名消息”,然后对其进行十六进制编码。
任何观点将不胜感激,我敢肯定这是一个菜鸟问题。
**更新
查看源代码,我发现它的期望恢复 id 大于 4:
sig[64] >= 4
就我而言,结果是27:
sig[64] --> 27