我对最新版本的
js-ethereum-cryptography中的
recoverPublicKey()
方法有问题。我可以获得 { r, s, recovery }
的值,但无法恢复公钥,因为我在浏览器中收到 undefined
错误。感谢您的帮助!
app.post("/send", (req, res) => {
const { sender, recipient, amount, signature } = req.body;
const { r, s, recovery } = signature;
const publicKey = secp.secp256k1.recoverPublicKey({ r, s, recovery }, sender);
console.log(publicKey.toString());
//...
});
来自js-ethereum-cryptography官方存储库的升级部分:
从1.0升级到2.0:
模块发生了巨大的变化: 之前,它使用的是noble-secp256k1 1.7; 现在它使用更安全的noble-curves。请参考 到曲线自述文件的升级部分。 要记住的主要变化:a)secp256k1
现在返回sign
实例 b)Signature
被移动到recoverPublicKey
实例Signature
- node.js 14 及更早版本的支持已被删除。升级到 Node.js 16 或更高版本。
以及来自高贵曲线的升级部分:
从 Nobel-secp256k1 1.7 升级:
改为recoverPublicKey(msg, sig, rec)
sig.recoverPublicKey(msg)
因此,您应该首先从
signature
数据重新创建 JSON
对象,然后使用它来恢复公钥。请注意,根据您序列化 (BigInt
) r
和 s
的方式,您可能需要先将它们转换回 BigInt
。
此外,即使在旧版本的库中,恢复也是从
signature
和 transaction
数据的哈希完成的,而不是从发送者(如您的代码中所示)完成的。
const { secp256k1 } = require("ethereum-cryptography/secp256k1");
const { keccak256 } = require("ethereum-cryptography/keccak");
const { utf8ToBytes } = require("ethereum-cryptography/utils");
//...
app.post("/send", (req, res) => {
const { transaction, signature } = req.body;
const { sender, recipient, amount } = transaction;
const { r, s, recovery } = signature;
//const sig = new secp256k1.Signature(BigInt(r), BigInt(s), recovery);
const sig = new secp256k1.Signature(r, s, recovery);
const data = JSON.stringify(transaction);
const hash = keccak256(utf8ToBytes(data));
//const publicKey = sig.recoverPublicKey(hash).toRawBytes();
const publicKey = sig.recoverPublicKey(hash).toHex();
console.log('public key:', publicKey);
//...
});
最后,根据您需要对公钥执行的操作,您可以使用
toRawBytes()
或 toHex()
方法,甚至可以通过指定 isCompressed = false
参数来获取未压缩的版本。