Hey everyone! I’m working on an NFT project using OpenZeppelin’s ERC721Full contract. I’ve got minting down, but I’m stuck on creating a purchase feature. Here’s what I’ve tried:
function purchaseToken(uint256 tokenId) public payable {
address payable currentOwner = address(uint160(ownerOf(tokenId)));
approve(currentOwner, tokenId);
setApprovalForAll(msg.sender, true);
transferFrom(currentOwner, msg.sender, tokenId);
currentOwner.transfer(msg.value);
emit TokenSold(currentOwner, msg.sender, msg.value);
}
The problem is, only the owner or an approved address can call approve. I’m not sure how to structure this correctly. Should I modify the approve function? That feels wrong.
Can anyone point me in the right direction for implementing a buy feature? I’ll add checks and requirements later, but first I just want to get it working in tests. Thanks for any help!
I’d recommend approaching this differently. Instead of trying to execute the transfer within a single function, consider implementing a two-step process:
-
Create a ‘listForSale’ function where the owner sets a price and approves the contract to transfer the token.
-
Implement a ‘buyToken’ function that checks if the token is for sale, ensures the correct payment is sent, transfers ownership, and pays the previous owner.
This separation of concerns is cleaner and more secure. It also aligns better with how most NFT marketplaces operate. Remember to include checks for ownership, sufficient payment, and current approval status.
Lastly, consider using SafeTransferFrom instead of TransferFrom for added security. Hope this helps point you in the right direction!
hey, instead of doin it all in one go, why not split it up? make a function for listing the token (owner sets price n approves) and another for buying (check if it’s for sale, transfer ownership, pay the seller). that way you don’t mess with approve. also, use safeTransferFrom for extra safety. good luck with ur project!
Heya Mia_17Dance!
ur project sounds super cool! i’ve been tinkering with NFTs too and ran into similar head-scratchers. have u thought about makin a marketplace contract that handles the buying/selling? it could work like:
contract NFTMarketplace {
function listForSale(uint256 tokenId, uint256 price) external {
// check if sender is owner
// set price and mark as for sale
}
function buyToken(uint256 tokenId) external payable {
// check if token is for sale and enough ETH sent
// transfer token to buyer
// send ETH to seller
}
}
this way, ur original contract stays clean and u can add more features to the marketplace later. what do u think? have u tried anything like this before? curious to hear more about ur project!