Addresses
從 ecrecover 獲取錯誤的地址
當我使用以下程式碼簽署一個字元串時,我會返回一個與我簽署的地址不同的地址。不同的字元串返回的地址不同。
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);
我從之前在此從 ethereumjs-utils erecover 獲取地址的問題的答案中獲取了程式碼。
我在這裡問了一個問題:Secp256k1 bindings are not compiled。純 JS 實現將用於可能相關的錯誤。評論表明它應該是無害的。
Geth 在 siginig 之前將前綴添加到消息中
web3.eth.sign
(請參閱JSON-PRC 規範)。如果沒有這個,就有可能欺騙使用者簽署交易(更多在這裡)。因此,使用or (Solidity’s )簽署消息
web3.eth.sign
和恢復地址的正確程式碼應顯式添加前綴。ethereumjs-util.ecrecover``ecrecover
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);
存在誤導性的不一致之處,
ethereumjs-testrpc
因為它在登錄之前沒有為消息添加前綴web3.eth.sign
。