I come late to the party but I want to answer as I was working on a similar problem for several days and the answer is quite simple.
I am showing here an example to use USDC inside a ERC721 contract. The first step is to use an interface in your ERC721 contract so you can access the functions in the ERC20 contract:
interface USDC{
function balanceOf(address owner) external view returns (uint);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
}
Then in your constructor you have to add the address of the ERC20 token contract (in my case I used the goerli USDC contract):
constructor() ERC721("Mavon Minted NFTs", "MNFTs") {
owner = msg.sender;
USDc = USDC(0x98339D8C260052B7ad81c28c16C0b98420f2B46a);
}
And finally, in the function where the transaction is made, you add the following ERC20 function:
USDc.transferFrom(msg.sender, seller, priceUSD);
Now, a very important thing and that took me a couple of days to discover, is that to use transferFrom, the buyer has to give your contract approval to move the funds in his wallet. This is accomplished by using the ERC20 function approve(spender, amount)
. The thing is, this approve function cannot be called within the same contract where you have the function that makes the funds transaction, so you have two options:
- make another contract to approve the transaction so you can use transferFrom;
- call the approve function in the ERC20 contract from the frontend, like you would do with any other contract.