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



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

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

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

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

最新更新