I have two contracts ERC20, and ERC721.
and everytime erc721 transferFrom function is called, I want to send some erc20 tokens to the creator (minter) of the ERC721.
After some research, I’ve found that I have to do two things.
- call ERC20.transferfrom in ERC721 transferFrom function
- Approve the spending of erc20 tokens from the frontend
it seems like the second is giving me some problems. Please see my code below:
Your help will be very much appreciated.
++ I am also not so sure if I am calling ERC20.transferFrom correctly from ERC721 contract. Is this the correct way to do it?
ERC721 contract:
import "../openzeppelin-contracts/contracts/token/ERC721/IERC721.sol";
import "../openzeppelin-contracts/contracts/token/ERC721/ERC721.sol";
import "../openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol";
import "../openzeppelin-contracts/contracts/math/SafeMath.sol";
import "../openzeppelin-contracts/contracts/utils/Address.sol";
import "../openzeppelin-contracts/contracts/utils/Counters.sol";
import "./ERC20Token.sol";
contract NFTtoken is ERC721 {
.
.
.
ERC20Token Erc20Contract;
constructor(address tokenAddress) ERC721("NC NFT example", "NCNFT") {
owner = msg.sender;
decimals = 0;
Erc20Contract = ERC20Token(tokenAddress);
}
function mint(string calldata nftName) external payable {
uint256 newItemId = _tokenIds.current();
_mint(msg.sender, newItemId);
nftInfo[msg.sender].name = nftName;
nftInfo[msg.sender].creator = msg.sender;
allValidTokenIndex[newItemId] = allValidTokenIds.length;
allValidTokenIds.push(newItemId);
_tokenIds.increment();
}
function transferNFT(address from, address to, uint256 tokenId) public returns (bool){
transferFrom(from, to, tokenId);
Erc20Contract.transferFrom(to, nftInfo[from].creator, 10);
}
}
.
.
.
app.js
transferNFT: function() {
NFTContract.deployed().then(function(contractInstance) {
let toAddress = $("#to-address").val();
// function transferFrom(address _from, address _to, uint256 _tokenId) public payable {
let NFTid_temp = $("#nft-id").val();
let NFTid = NFTid_temp.substring(7);
console.log("to = " + toAddress);
console.log("nftid = " + NFTid);
Voting.deployed().then(function(votingcontractInstance) { votingcontractInstance.approve(contractInstance.address, votingcontractInstance.balanceOf(web3.eth.accounts[1]))});
contractInstance.transferNFT(web3.currentProvider.selectedAddress, toAddress, NFTid, {gas: 140000, from: web3.eth.accounts[0]});
})
}
error message
app.js:10169 Uncaught (in promise) BigNumber Error: new BigNumber() not a number: [object Object]
at raise (http://localhost:8080/app.js:10169:25)
at http://localhost:8080/app.js:10157:33
at new BigNumber (http://localhost:8080/app.js:9184:67)
at new BigNumber (http://localhost:8080/app.js:9194:25)
at toBigNumber (http://localhost:8080/app.js:2084:12)
at Object.toTwosComplement (http://localhost:8080/app.js:2095:21)
at SolidityTypeAddress.formatInputInt [as _inputFormatter] (http://localhost:8080/app.js:2995:38)
at SolidityTypeAddress.SolidityType.encode (http://localhost:8080/app.js:3648:17)
at http://localhost:8080/app.js:15577:29
at Array.map (<anonymous>)