如何实现同质化代币(ERC20标准)购买非同质化代币(ERC721)两份合约如何交互

注:我是小白 A合约是ERC20(继承了ERC20的接口,ERC721也一样),B合约是ERC721,合约C是用来交互的。交互是指用A合约的Token购买B合约的NFT,C合约继承A和B都不行,会冲突。代码如下

pragma solidity ^0.8.1;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/ERC721URIStorage.sol";

interface ERC20Interface{
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);
    function totalSupply() external view returns (uint256);
    function balanceOf(address _owner) external view returns (uint256 balance);
    function transfer(address _to, uint256 _value)
        external
        returns (bool success);

    function transferFrom(
        address _from,
        address _to,
        uint256 _value
    ) external returns (bool success);

    function approve(address _spender, uint256 _value)
        external
        returns (bool success);

    function allowance(address _owner, address _spender)
        external
        view
        returns (uint256 remaining);

    event Transfer (address indexed _from, address indexed _to, uint256 _value);
    event Approval(
        address indexed _owner,
        address indexed _spender,
        uint256 _value
    );
}

contract Token is ERC20Interface {
    string private _name;
    string private _symbol;
    uint8 private _decimals;
    uint256 private _totalSupply;

    mapping(address => uint256) private balancesOf;
    mapping(address => mapping(address => uint256)) private allowanced;

    constructor() {
        _name = "mytoken";
        _symbol = "zan";
        _decimals = 0;
        _totalSupply = 10000000;
        balancesOf[msg.sender] = _totalSupply;
    }

    function name() external view override returns (string memory) {
        return _name;
    }

    function symbol() external view override returns (string memory) {
        return _symbol;
    }

    function decimals() external view override returns (uint8) {
        return _decimals;
    }

    function totalSupply() external view override returns (uint256) {
        return _totalSupply;
    }

    function balanceOf(address _owner)
        external
        override
        view
        returns (uint256 balance)
    {
        return balancesOf[_owner];
    }

    function transfer(address _to, uint256 _value)
        external
        override
        returns (bool success)
    {
        require(balancesOf[msg.sender] >= _value);
        require(_to != address(0));
        require(balancesOf[_to] + _value > balancesOf[_to]);
        balancesOf[msg.sender] -= _value;
        balancesOf[_to] += _value;
        emit Transfer(msg.sender, _to, _value);
        return true;
    }

    function transferFrom(
        address _from,
        address _to,
        uint256 _value
    ) external override returns (bool success) {
        uint256 _allowance = allowanced[_from][msg.sender]; // here keep sb's token which the owner give
        uint256 sbAllowance = _allowance - _value; // sb take the token
        require(_allowance >= _value, "not enough allowance");
        allowanced[_from][msg.sender] = sbAllowance;
        require(balancesOf[_from] > _value, "not enough");
        balancesOf[_from] -= _value;
        balancesOf[_to] += _value;
        emit Transfer(_from, _to, _value);
        return true;
    }

    function approve(address _spender, uint256 _value)
        external
        override
        returns (bool success)
    {
        allowanced[msg.sender][_spender] = _value;
        emit Approval(msg.sender, _spender, _value);
        return true;
    }

    function allowance(address _owner, address _spender)
        external
        view
        override
        returns (uint256 remaining)
    {
        return allowanced[_owner][_spender];
    }
}

contract zTokenNFT is ERC721URIStorage {
    uint256 public counter;

    constructor() ERC721("zTokenNFT", "zAnNFT") {
        counter = 0;
    }

    function createNFT(string memory tokenURI) public returns (uint256) {
        uint256 tokenId = counter;
        _safeMint(msg.sender, tokenId);
        _setTokenURI(tokenId, tokenURI);
        counter++;
        return tokenId;
    }

    function burn(uint256 tokenId) public virtual {
        require(
            _isApprovedOrOwner(msg.sender, tokenId),
            "error:owner or approved"
        );
        super._burn(tokenId);

    }
}
请先 登录 后评论

3 个回答

越泽 - 区块链爱好者
请先 登录 后评论
合约开发 - 开发工程师
请先 登录 后评论
张小风
请先 登录 后评论