1

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

所以我发现问题出在库上……我是否向函数发送了错误的参数?有没有其他方法可以从签名者那里恢复公共地址?

4

1 回答 1

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

于 2018-07-20T02:47:51.783 回答