Возврат неправильного адреса из 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. Чистая реализация JS будет использоваться для возможной значимой ошибки. Однако в комментариях говорилось, что это должно быть безвредно.

Не могли бы вы опубликовать точные версии пакетов, которые вы используете ( npm list). testrpcЯ думаю, что в некоторых зависимостях была ошибка .
@maxtaldykin pastebin.com/v2ydwkgy вот что у меня получилось
@maxtaldykin Я использую macOS sierra версии 10.12.4, не знаю, где найти версию testrpc
@maxtaldykin я получил ошибку imgur.com/a/JTyU4

Ответы (1)

Geth добавляет к сообщению префикс перед его подписью web3.eth.sign(см . спецификацию JSON-PRC ). Без этого можно обманом заставить пользователя подписать транзакцию (подробнее здесь ).

Таким образом, правильный код для подписи сообщения web3.eth.signи восстановления адреса с помощью ethereumjs-util.ecrecoverили (Solidity 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.

Кажется, метеор будет разрешать только версии узлов 4.x.
Это сработало! Спасибо большое я уже давно с этим борюсь
извините, это маленькая вещь... адрес ecrecover написан строчными буквами, но в исходном адресе есть несколько заглавных букв. Это имеет значение?
неважно, на него ответили здесь ethereum.stackexchange.com/questions/2045/…
Как, черт возьми, ты нашел это?! Я искал вечность.