Чего я хочу добиться, так это подписать сообщение, а затем проверить подпись, проверена ли она по тому же адресу или нет.
Контракт на вызов метода 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);
Выход
Message Hash: 0x1c6f4ab842fb95857783a0177eafb0133b3a626c89877a8bf4e2d07987aa1422
Account Used to Sign: 0x890bd380e472df5b8bab22075c6a5d4f0b84415c
Account State: true
Signature: 0xb8b01f46f147bd5e8f84343719ca7492164f80af5f60370c433e2e096ae52fec76d2bbe0e454b2a07e4100e8463d98286ec6e849cbcf6e24f66f7d579fc8654f1c
V: 28
R: 0xb8b01f46f147bd5e8f84343719ca7492164f80af5f60370c433e2e096ae52fec
S: 0x76d2bbe0e454b2a07e4100e8463d98286ec6e849cbcf6e24f66f7d579fc8654f
Decimal V: 28
Final Address: 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.
код взят из ответа здесь https://ethereum.stackexchange.com/a/12684/
Суммит