从键入的签名中恢复公共地址

时间:2018-07-19 14:51:20

标签: javascript firebase ethereum metamask

我正在实施一个应用程序,有必要在该应用程序上确认您的以太坊钱包。为此,我目前正在编写一个基本的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

所以我发现问题出在库中...我是否将错误的参数发送给函数?还有其他方法可以从签名者那里恢复公共地址吗?

1 个答案:

答案 0 :(得分:0)

您需要使用对象数据,可以在此处检查代码:

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来恢复公钥。