Metamask Issue: Validating ERC721 Tokens in Hardhat vs React
When working with the MetaMask API and Solidity contracts, there are certain edge cases that can lead to unexpected behavior. One of the most common problems is verifying the approval of ERC721 tokens using a for loop in a Hardhat script compared to a React application.
In this article, we will consider this problem and offer solutions for its elimination.
Hard Script Problem
In the Hardhat script, you can use the transfer
function to transfer ownership of an ERC721 token. When checking the approval of tokens in these contracts using a for loop, there may be problems with the correct update of the approval status.
const contractArr = ['0x1234567890abcdef'];
modifier isApproved ( address [] memory contractArr ) { ;
require ( contractArr . length > 0 , " LengthZero " ) ;
for ( let i = 0 ; i < contractArr . length ; i ++ ) { ;
const tokenAddress = contractArr[i];
contract [ tokenAddress ]. approve ( address . from , address . value );
} }
} }
The problem is that when performing a transfer using the transfer
function, it returns true
immediately after the transaction is processed. However, in the for loop it is necessary to check whether the approval status was updated correctly.
The React Problem
In a React application, verifying token assertions on ERC721 tokens can be more difficult due to the asynchronous nature of API calls.
import { contract } from './contracts/ERC721.sol';
import Web3 from 'web3';
const contractArr = ['0x1234567890abcdef'];
function isApproved ( address ) {
const web3 = new Web3(window.ethereum);
return contract . ERC721 . isApproved ( contract . address , address . value );
} }
In this React example, the isApproved
function uses a contract
object from Solidity contracts to check if the token has been approved.
Solution
To solve these problems both in Hardhat scripts and in React applications, you can use the second approach:
- Use the
transfer
function with an event generator: instead of directly checking the approval status, use theeventTransferComplete
event generated by the MetaMask API to update the status of your contract.
const contractArr = ['0x1234567890abcdef'];
modifier isApproved ( address [] memory contractArr ) { ;
require ( contractArr . length > 0 , " LengthZero " ) ;
for ( let i = 0 ; i < contractArr . length ; i ++ ) { ;
const tokenAddress = contractArr[i];
eventTransferComplete(tokenAddress).emit('approval', { status: true });
// Update the contract status
contract [ tokenAddress ]. approve ( address . from , address . value );
} }
} }
- Use a callback function in the
transfer
event: You can also pass a callback function to the
transfer
event generated by MetaMask, which will be called when the approval status is updated.
const contractArr = ['0x1234567890abcdef'];
eventTransferComplete(tokenAddress).on('approval', (status) => {
if ( status . status === true ) {
// Update the contract status
contract [ tokenAddress ]. approve ( address . from , address . value );
} }
});
Using these approaches, you can ensure that your contracts will be correctly checked for token approval in both Hardhat scripts and React applications.
Conclusion
When working with the MetaMask API and Solidity contracts, it is important to be aware of potential issues such as token approval verification on ERC721 tokens. By understanding the basic mechanics of the `transfer’ function and using event generators or callback functions, you can solve these problems in both Hardhat scripts and React applications.