Signature

從 ethereumjs-utils ecrecover 獲取地址

  • October 3, 2020

我正在嘗試使用 web3.eth.sign() 對字元串進行簽名,然後從簽名中獲取我使用的公鑰。為此,我使用 ethereumjs-utils 中的 ecrecover(),它返回一個緩衝區。當我在緩衝區上使用 bufferToHex() 時,它給出的十六進製字元串太長而不能成為地址 - 130 個字元,包括 ‘0x’

web3.personal.unlockAccount(myAccount,pass)
msg = web3.sha3(aString)
sig = web3.eth.sign(myAccount,msg)
r = sig.slice(0, 66)
s = '0x' + sig.slice(66, 130)
v = '0x' + sig.slice(130, 132)
v = web3.toDecimal(v)
msg = ethJsUtil.toBuffer(msg)
addr = ethJsUtil.ecrecover(msg,v,r,s)
addr = ethJsUtil.bufferToHex(addr)

我從工作流的答案中獲取了大部分程式碼,用於使用私鑰簽名字元串,然後使用公鑰進行簽名驗證,但必須將“msg”轉換為緩衝區,否則 ecrecover 會引發類型錯誤。

我需要做什麼才能將緩衝區從 ecrecover 轉換為地址?

ecrecover返回公鑰,您需要將其轉換為地址pubToAddress

pub     = ethJsUtil.ecrecover(msg, v, r, s);
addrBuf = ethJsUtil.pubToAddress(pub);
addr    = ethJsUtil.bufferToHex(addrBuf);

此外,您可以使用fromRpcSig獲取v, r, s

sig = web3.eth.sign(myAccount,msg)
res = ethJsUtil.fromRpcSig(sig)
pub = ethJsUtil.ecrecover(msg, res.v, res.r, res.s);

請注意,web3.eth.sign在簽名之前為消息添加前綴(請參閱JSON-RPC 規範)。

以下是手動添加的方法:

const util = require('ethereumjs-util')

const msg = new Buffer('hello');
const sig = web3.eth.sign(web3.eth.accounts[0], '0x' + msg.toString('hex'));
const res = util.fromRpcSig(sig);

const prefix = new Buffer("\x19Ethereum Signed Message:\n");
const prefixedMsg = util.sha3(
 Buffer.concat([prefix, new Buffer(String(msg.length)), msg])
);

const pubKey  = util.ecrecover(prefixedMsg, res.v, res.r, res.s);
const addrBuf = util.pubToAddress(pubKey);
const addr    = util.bufferToHex(addrBuf);

console.log(web3.eth.accounts[0],  addr);

另一方面,testrpc(至少版本 3.0.5)不添加這樣的前綴。

範例 node.js + testrpc 會話:

const util = require('ethereumjs-util')

const msg = web3.sha3('hello!');
const sig = web3.eth.sign(web3.eth.accounts[0], msg);
const {v, r, s} = util.fromRpcSig(sig);

const pubKey  = util.ecrecover(util.toBuffer(msg), v, r, s);
const addrBuf = util.pubToAddress(pubKey);
const addr    = util.bufferToHex(addrBuf);

console.log(web3.eth.accounts[0], addr);

引用自:https://ethereum.stackexchange.com/questions/12571