我不太清楚Gnosis是如何完成签名和签名验证的。翻阅堆叠溢出、Gnosis文档和不和,使我比任何事情都更加困惑。我正试图通过Walletconnect使我的登录支持Gnosis安全。
我做了以下工作:
// Front-end Signing method:
let signature
try {
signature = await provider.request({ method: 'personal_sign', params: [message, wallet], jsonrpc: '2.0' })
} catch (e) {
// User refused to sign.
console.error(e)
signature = null
}登录时,用户复制QRcode并将其粘贴到Gnosis网站上的WalletConnect应用程序中。
现在,我们注意到,Gnosis要求用户对我们的消息进行签名,并且在签署消息时,personal_sign将返回0x。
无论如何,这是正常的。
现在我们要验证签名,这就是问题的开始。
// Function in backend checking if the signature is valid:
const { message, signature, wallet } = req.body
// Signature is `0x` therefore we likely are trying to login using a multiSig.
if (signature == '0x' ) {
let msgHash = ethers.utils.hashMessage(message)
const magicValue = '0x1626ba7e'
const contract = gnosisSafeContract(wallet, provider) // function that returns a ethers.Contract instance
const _signature = ?????????
const value = await contract.isValidSignature(msgHash,_signature)
return value == magicValue
}此时,我意识到我的问题几乎是这个堆叠溢出柱的翻版,但“解决方案”并不是真正的解决方案。
三个问题:
isValidSignature?contract.signMessage来生成事务而不是personal_sign,但是如果我们还没有签名者,signMessage就会恢复。由于用户尚未登录,前端如何知道如何调用元问询或x提供程序?signMessage,signMessage函数也不会返回签名。我在rinkeby上部署了一个保险箱,我一直用它来解决这个问题。https://rinkeby.etherscan.io/address/0x8390Ac0155FFC8a373F0Fd725cc15CD0841ED91B#code
我绝对需要帮助。
发布于 2022-06-17 21:28:39
好的,亲爱的,谢谢你。我们决定采用事件侦听选项。
(使用nodejs快速后端)
export default async function (req: any, res: any) {
let { message, signature, wallet } = req.body
if (signature === '0x') {
// generate gnosis contract instance (using new ethers.Contract(...) )
const wsSafeProxyContract = gnosisProxyContract(wallet)
if (!wsSafeProxyContract) {
res.json({ success: false })
return
}
const msgHash = ethers.utils.hashMessage(message)
const getMessageHash = await wsSafeProxyContract.getMessageHash(msgHash)
const waitForSignedEvent = new Promise<boolean>((myResolve, myReject) => {
const onMultiSigSigned = () => {
myResolve(true)
}
setTimeout(() => { wsSafeProxyContract.removeListener(wsSafeProxyContract.filters.SignMsg(getMessageHash), onMultiSigSigned)
myReject(false)
}, 5 * 60 * 60 * 1000)
// login() only after the _signMessage() txn is mined and SignMsg(msgHash) event emitted
wsSafeProxyContract.once(wsSafeProxyContract.filters.SignMsg(getMessageHash), onMultiSigSigned)
})
waitForSignedEvent
.then(async (value) => {
if (value) {
const { token, name, isNewUser } = await getUserInfo(res, wallet, options)
res.json({ success: true, token, name, isNewUser })
}
})
.catch((err) => {
console.error(err)
res.json({ success: false })
})
} else {
// signature either undefined or the usual
}发布于 2022-06-16 19:23:31
博士
只需使用0x作为签名。如果Gnosis安全返回EIP-1271魔术值(0x1626ba7e),则签名有效。
if (signature == '0x') {
let msgHash = ethers.utils.hashMessage(message);
const magicValue = '0x1626ba7e';
const contract = gnosisSafeContract(wallet, provider);
const _signature = '0x';
const response = await contract.isValidSignature(msgHash, _signature);
// check if response equals EIP-1271 magic value
if(response == magicValue) {
...
}
}在签名消息时,Gnosis只返回0x作为签名。正如这里解释的那样,原因是Gnosis是一个智能的合同钱包,不能生成ECDSA签名。
在内部,Gnosis安全商店包含所有签名消息的地图中的消息哈希。
当调用isValidSignature(msgHash,_signature)时,Gnosis安全检查映射是否包含msgHash。如果为真,则返回神奇的值。
关于您的第二个问题,Gnosis安全喷出签署后的下列事件:
event SignMsg(bytes32 indexed msgHash);您可以收听该事件,以了解消息何时已签名。
https://ethereum.stackexchange.com/questions/124444
复制相似问题