乙太坊簽名驗證不匹配
我想要實現的是簽署一條消息,然後驗證簽名是否由相同的地址驗證。
合約呼叫 ecrecover 方法來驗證地址
contract MyAuth { function verify( bytes32 hash, uint8 v, bytes32 r, bytes32 s) constant returns(address returnAddress) { returnAddress = ecrecover(hash, v, r, s); } }
Java 腳本程式碼
var cMyAuthAddress="0x09343c5EBB988315E117E1Cd6EE501AF02412cFB"; // Contract address var cMyAuthABI="<ABI data>"; // Contract ABI var cDeployed=web3.eth.contract(JSON.parse(cMyAuthABI)).at(cMyAuthAddress); var msg = web3.sha3('This my test data'); console.log('Message Hash: '+ msg); // Generated message hash console.log("Account Used to Sign: "+ web3.eth.accounts[0]); var state=web3.personal.unlockAccount(web3.eth.accounts[0], '<account password>', 1000); // Unlocking the account to perform the operation console.log('Account State: '+ state); var signature = web3.eth.sign(web3.eth.accounts[0], msg); // Signing the messge console.log('Signature: '+ signature); var r = signature.slice(0, 66) var s = '0x' + signature.slice(66, 130) var v = '0x' + signature.slice(130, 132) v = web3.toDecimal(v); console.log("V: "+ v); console.log("R: "+ r); console.log("S: "+ s); if(v<27 || v>28){ v+=27; console.log("Updated V: "+ v); } var finalAddress=cDeployed.verify.call(msg,v,r,s) console.log("Final Address: "+ finalAddress);
輸出
資訊散:0x1c6f4ab842fb95857783a0177eafb0133b3a626c89877a8bf4e2d07987aa1422
賬戶用於簽名:0x890bd380e472df5b8bab22075c6a5d4f0b84415c
帳戶狀態:真正的
簽名:0xb8b01f46f147bd5e8f84343719ca7492164f80af5f60370c433e2e096ae52fec76d2bbe0e454b2a07e4100e8463d98286ec6e849cbcf6e24f66f7d579fc8654f1c
五:28
R:0xb8b01f46f147bd5e8f84343719ca7492164f80af5f60370c433e2e096ae52fec
S:0x76d2bbe0e454b2a07e4100e8463d98286ec6e849cbcf6e24f66f7d579fc8654f
十進制五:28
最終地址:0x0609b9fae476d8b844716e3a0a6a3b5b7a5a2cdf
您可以清楚地看到列出的最終地址與用於簽署消息的地址不匹配。
注意:我正在我的私有區塊鏈上嘗試這個。
問題:需要更正哪個步驟才能達到預期的結果(即最終地址應與在這種情況下用於簽名的帳戶地址匹配,即 0x890bd380e472df5b8bab22075c6a5d4f0b84415c)?
嘗試將 ethereumjs-util 與 baove 生成的簽名值一起使用,但結果相同。
var ethUtils = require('ethereumjs-util'); let tSig = ethUtils.fromRpcSig(signature); let pubKey = ethUtils.ecrecover( ethUtils.sha3("This my test data"), tSig.v, tSig.r, tSig.s); let foundAddr = '0x' + ethUtils.pubToAddress(pubKey).toString('hex'); console.log("Final Address 2: "+ finalAddress);
輸出為最終地址2:0x0609b9fae476d8b844716e3a0a6a3b5b7a5a2cdf ”(即相同的地址)
您需要在消息前加上字元串“\x19Ethereum Signed Message:\n”和消息的長度
const prefix = new Buffer("\x19Ethereum Signed Message:\n"); const prefixedMsg = util.sha3( Buffer.concat([prefix, new Buffer(String(msg.length)), msg]) );
然後在 ecrecover 中使用前綴字元串。