Solidity

ERC20Permit (EIP2612) 中的“無效簽名”錯誤

  • May 27, 2022

我使用來自 openzeppelin 的ERC20Permit令牌擴展合約通過簽名進行批准。在測試(安全帽測試網)中,我使用乙太幣和簽名類型的數據,如下所述:Ethers Signers。所以問題是當我嘗試使用許可功能時,它給了我“無效簽名”錯誤。Permit 函式是從標準的 erc721 合約呼叫的,實際上是從 erc20 代幣所有者的賬戶批准到 erc721 合約地址。

程式碼的相關部分:

來自 ERC20Permit:

function permit(
   address owner,
   address spender,
   uint256 value,
   uint256 deadline,
   uint8 v,
   bytes32 r,
   bytes32 s
) public virtual override {
   require(block.timestamp <= deadline, "ERC20Permit: expired deadline");

   bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));

   bytes32 hash = _hashTypedDataV4(structHash);

   address signer = ECDSA.recover(hash, v, r, s);
   require(signer == owner, "ERC20Permit: invalid signature");

   _approve(owner, spender, value);
}

來自 test.js 文件:

const types = {
       Permit: [
           { name: 'owner', type: 'address' },
           { name: 'spender', type: 'address' },
           { name: 'value', type: 'uint256' },
           { name: 'nonce', type: 'uint256' },
           { name: 'deadline', type: 'uint256' } 
       ]
}

const domain = {
   name: "ERC20Permit-Token",
   version: '1',
   chainId: "31337",
   verifyingContract: verifyAddr
}

const value = {
   owner: _owner,
   spender: _spender, 
   value: _value, 
   nonce: _nonce, 
   deadline: _deadline
}

const signer = _signer
const signature = await signer._signTypedData(domain, types, value)

鏈上和來自 js 的所有參數都是相等的(我將它與 hardhat/console.sol 進行了比較)。但是恢復的簽名者和所有者的地址不同(與錯誤實際出現的地方不同)。

我認為在 ERCPermit 中使用乙太進行數據簽名和散列會以某種方式給出不同的結果,因此地址不相等。但我不確定。

這裡有什麼問題?任何幫助表示讚賞。

鏈 ID 是否正確?

檢查這個:1337 或其他 IDK

我對許可證做了一些研究,chainid 也很重要。

經過一些調試後,我決定使用 ethers-eip712 的 typeData 生成和通過元遮罩簽名,一切正常。

不要現在到底是什麼問題……看看這個解決方案:codesandbox。希望它會有所幫助

引用自:https://ethereum.stackexchange.com/questions/129024