Signature
從 ethereumjs-utils ecrecover 獲取地址
我正在嘗試使用 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);