简体   繁体   中英

how to approve the spend of ERC20 tokens from the javascript file?

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.

  1. call ERC20.transferfrom in ERC721 transferFrom function
  2. 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>)

I suspect this line:

votingcontractInstance.balanceOf(web3.eth.accounts[1]))

Can you check its type? I think it returns "string" but it must be number. If it is string either wrap it with Number

 Number(votingcontractInstance.balanceOf(web3.eth.accounts[1])))

Or use web3.utils.toBN()

  web3.utils.toBN(votingcontractInstance.balanceOf(web3.eth.accounts[1])))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM