EIP712 не возвращает адрес пользователя через Smart Contract (Solidity)

Пытаюсь подписать EIP-712 через фронт и декодировать через смарт контракт, передаю хэш подписи (V, R, S) и message в смарт контракт, но контракт возвращает совсем другой адрес. Не могу понять в чем проблема, кто сталкивался помогите пожалуйста :)

  1. ФРОНТ:

    let msgParams = JSON.stringify({
    
    types: {
    EIP712Domain: [
     { name: 'chainId', type: 'uint256' },
     { name: 'name', type: 'string' },
     { name: 'verifyingContract', type: 'address'},
     { name: 'version', type: 'string' },
    ],
    Person: [
     { name: 'name', type: 'string'},
     { name: 'wallets', type: 'address'},
    ],
    Mail: [
     { name: 'contents', type: 'string'},
     { name: '_from', type: 'Person' },
     { name: 'to', type: 'Person' },
    
     ]},
       primaryType: "Mail",
     domain: {
       chainId: 42,
       name: "Aibek, Hello!",
       verifyingContract: "0xDa2a0dE73e600fC111E1c324530000b739A68E1F",
       version: "1",
     },
     message: {
       contents: "Aibek, Hello!",
       _from: {
         name: "Aibek",
         wallets: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"},
       to: {
         name: "Timaaaaa",
         wallets: "0xfcb2b98856Aa507307748Ca0C6456F6BA7355ee9"}
       }
       }); 
       let from = '0xAE49BF7b702D9F2BF533a82fDf31e70A17D39f76';
       let params = [from, msgParams];
       let method = 'eth_signTypedData_v4';
       let vrsResult = window.ethereum.request({method, params, from})
    
  2. Cмарт контракт:

    pragma solidity ^0.8.4;
    
    import '../.deps/npm/@openzeppelin/contracts/token/ERC20/IERC20.sol';
    
    contract Сontract {
     mapping(address=>uint) private _balance;
     uint public counter;
    
     event Transfer(address indexed from, address indexed to, uint256 amount);
     event tokenInContract(address indexed from, uint256 amount);
     event hashDecode(address indexed from, address indexed hashDecode);
    
     struct EIP712Domain{
         uint256 chainId;
         string  name;
         address verifyingContract;
         string  version;
     }
    
     struct Person{
         string name;
         address wallets;
     }
    
     struct Mail{
         string contents;
         Person _from;
         Person to;
     }
    
     bytes32 DOMAIN_SEPARATOR = hashDomain(EIP712Domain({
         chainId: 42,
         name: "Aibek, Hello!",
         verifyingContract: 0xDa2a0dE73e600fC111E1c324530000b739A68E1F,
         version: "1"
     }));
    
     bytes32 private constant EIP712_DOMAIN_TYPEHASH = keccak256("EIP712Domain(uint256 chainId,string name, address verifyingContract,string version)");
     bytes32 private constant PERSON_TYPEHASH = keccak256("Person(string name,address wallets)");
     bytes32 private constant MESSAGE_TYPEHASH = keccak256("Mail(sting contents,Person _from,Person to)Person(string name,address wallets)");
    
     function hashDomain(EIP712Domain memory eip712domain) private pure returns(bytes32){
         return keccak256(abi.encode(
             EIP712_DOMAIN_TYPEHASH,
             eip712domain.chainId,
             keccak256(bytes(eip712domain.name)),
             eip712domain.verifyingContract,
             keccak256(bytes(eip712domain.version))));
     }
    
     function hashData(Person memory data) private pure returns(bytes32){
         return keccak256(abi.encode(
             PERSON_TYPEHASH,
             keccak256(bytes(data.name)),
             data.wallets
         ));
     }
    
     function hashMessage(Mail memory message) private view returns(bytes32){
         return keccak256(abi.encode(
             MESSAGE_TYPEHASH,
             keccak256(bytes(message.contents)),
             hashData(message._from),
             hashData(message.to)
             ));
     }
    
     function hashAllTheMessage(Mail memory message) private view returns(bytes32){
         return keccak256(abi.encodePacked(
             "\x19\x01",
             DOMAIN_SEPARATOR,
             hashMessage(message)
         ));
     }
    
     function hashCheck(Mail memory message, uint8 v, bytes32 r, bytes32 s) public returns(address){
         address sender = ecrecover(hashAllTheMessage(message), v, r, s);
         emit hashDecode(msg.sender, sender);
         return sender;
     } 
    
     function transferTokenToUser(Mail memory message, address erc20Address, uint amount, uint8 v, bytes32 r, bytes32 s) public payable
     returns(bool){
         address decodeHash = hashCheck(message, v, r, s);
         require(msg.sender == decodeHash, 'PROTOCOL: DIFFERENT_ADDRESS');
         require(amount >= msg.value, 'PROTOCOL: SENDING_TOKEN_NOT_EQUAL');
         IERC20 sendToken = IERC20(erc20Address);
         sendToken.transfer(msg.sender, amount);
         _balance[msg.sender] -= amount;
         emit tokenInContract(msg.sender, amount);
         return true;
     }
    
     function acceptTokenToContract(address erc20Address, uint amount) public payable returns (bool){
         IERC20 token = IERC20(erc20Address);
         require(token.balanceOf(msg.sender) >= amount, "PROTOCOL: BALANCE_INSUFFICIENT");
         require(token.allowance(msg.sender, address(this)) >= amount, "PROTOCOL: AMOUNT_NOT_ALLOWED");
         token.transferFrom(msg.sender, address(this), amount);
         _balance[msg.sender] += amount;
         emit Transfer(msg.sender, address(this), amount);
         return true;
     }
    
     function testVerify() public payable returns (bool) {
         Mail memory mails = Mail({contents:"Aibek, Hello!",
                                 _from: Person({name:"Aibek",
                                        wallets:0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826
                                     }),
                                 to: Person({name:"Timaaaaa",
                                     wallets:0xfcb2b98856Aa507307748Ca0C6456F6BA7355ee9
                                     })
                                  });
    
         bytes32 s = 0x558b1c363e2e88697eb5496295b5e27681d051cc7350676033c43bddbce6998c;
         bytes32 r = 0x1386bc67d8775ba0d6c6b5065dfc17d61ab86ce7fa765b7e861e99bae6c85a6a;
         uint8 v = 28;
         address signerAddr = 0xAE49BF7b702D9F2BF533a82fDf31e70A17D39f76;
         return signerAddr == hashCheck(mails, v, r, s);
     }
    

    }


Ответы (0 шт):