Восстановить публичный адрес из напечатанной подписи

Я реализую приложение, в котором необходимо подтвердить свой кошелек Ethereum. Для этого я в настоящее время пишу базовую веб-страницу на HTML и Javascript.

Это мой код JavaScript.

const msgParams = [
    {
      type: 'uint',
      name: 'Please verify your generated key',
      value: ''
    }
]
var signeddata = ''

function sanitizeData (data) {
    const sanitizedData = {}
    for (const key in TYPED_MESSAGE_SCHEMA.properties) {
      data[key] && (sanitizedData[key] = data[key])
    }
    return sanitizedData
  }

window.onload = function() {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'https://plapla.pla/initializeVerification', true);

  // If specified, responseType must be empty string or "text"
  xhr.responseType = 'json';

  xhr.onreadystatechange = function () {
    if (xhr.readyState === xhr.DONE) {
        if (xhr.status === 200) {
            msgParams[0].value = xhr.response.key;
            console.log(msgParams);
        }
    }
  };
  console.log('!');
  xhr.send(null);
}


function verify() {
  let web3 = window.web3;

  console.log(web3);

    // Checking if Web3 has been injected by the browser (Mist/MetaMask)
    if (typeof web3 !== 'undefined') {

      // Use the browser's ethereum provider
      web3 = new Web3(web3.currentProvider);
      console.log(web3);

    } else {
      console.log('No web3? You should consider trying MetaMask!')
    }

    //Login tracken
    web3.currentProvider.publicConfigStore.on('update', callback => {
      console.log(callback);
      //Login tracken
    });

    console.log(web3.eth.accounts);

    web3.eth.getCoinbase(function(error, result){
      if(!error) {
        console.log("params: "+msgParams[0]);
        var fromAddress = result;
        web3.currentProvider.sendAsync({
          method: 'eth_signTypedData',
          params: [msgParams, fromAddress],
          from: fromAddress,
        }, function (err, result) {
          if (err) return console.error(err);
          if (result.error) {
            return console.error(result.error.message)
          }

          var sign = {};
          sign.data =[{
              type:msgParams[0].type,
              name:msgParams[0].name,
              value:msgParams[0].value
            }];
          sign.sig = result.result
          var json = JSON.stringify(sign);
          console.log("Do JSON"+json);

          var xhr = new XMLHttpRequest();
          console.log("Fa: "+fromAddress);
          xhr.open('POST', 'https://plapla.pla/addWallet', true);
          xhr.setRequestHeader('Content-type','application/json; charset=utf-8');
          // If specified, responseType must be empty string or "text"
          xhr.responseType = 'text';

          xhr.onreadystatechange = function () {
            if (xhr.readyState === xhr.DONE) {
                if (xhr.status === 200) {
                    console.log(xhr.response);
                }
            }
          };
          xhr.send(json);

        });

      }
    });
};

Я получаю случайное число из своего бэкэнда при загрузке и хочу, чтобы пользователь подписал этот код с помощью Metamask. Затем я снова отправляю его в свою серверную часть firebase, которая получает данные, а также подпись.

Firebase обрабатывает это следующим образом:

exports.addWallet = functions.https.onRequest((req, res) => {
  cors(req, res, () => {
    const signed = req.body;
    console.log(signed);
    const recovered = sigUtil.recoverTypedSignature(signed);
    return recovered;
  })
});

Как видите, я использую библиотеку eth-sig-util: https://github.com/MetaMask/eth-sig-util

Но я всегда получаю эту ошибку от firebase:

TypeError: Cannot read property 'EIP712Domain' of undefined
    at Object.findTypeDependencies (/user_code/node_modules/eth-sig-util/index.js:97:47)
    at Object.encodeType (/user_code/node_modules/eth-sig-util/index.js:76:21)
    at Object.hashType (/user_code/node_modules/eth-sig-util/index.js:127:30)
    at Object.encodeData (/user_code/node_modules/eth-sig-util/index.js:42:33)
    at Object.hashStruct (/user_code/node_modules/eth-sig-util/index.js:116:30)
    at Object.sign (/user_code/node_modules/eth-sig-util/index.js:153:21)
    at Object.recoverTypedSignature (/user_code/node_modules/eth-sig-util/index.js:235:36)
    at cors (/user_code/index.js:29:31)
    at cors (/user_code/node_modules/cors/lib/index.js:188:7)
    at /user_code/node_modules/cors/lib/index.js:224:17

Так я понял, что проблема с библиотекой... Я посылаю в функцию неправильные параметры? Есть ли другой способ восстановить публичный адрес подписавшего?


person Florian Pircher    schedule 19.07.2018    source источник


Ответы (1)


Вам нужно использовать данные объекта, можете проверить код здесь:

https://github.com/MetaMask/eth-sig-util/blob/master/index.js#L234

{
  data: '', // the data you signed
  sig: '' // the r, s, v concated string
}

Или вы можете использовать ethereumjs-util для восстановления открытого ключа, если вы знаете подписанные данные.

person Peter Lai    schedule 20.07.2018