简体   繁体   English

如何从另一个智能合约 function 调用智能合约 function?

[英]How to call a smart contract function from another smart contract function?

Some background first.先来点背景。 I have two smart contracts:我有两个智能合约:

  • ERC20 for fungible tokens where I minted my own token/crypto currency; ERC20用于可替代代币,我在其中铸造了自己的代币/加密货币;
  • ERC1155 for non-fungible tokens (NFTs); ERC1155用于不可替代代币(NFT);
  • The user will buy the NFT minted in the ERC1155 with the token I minted in the ERC20 smart contract.用户将使用我在ERC20智能合约中铸造的代币购买在ERC1155中铸造的 NFT。

The user calls the function buyNFT() in the ERC1155 that call the function transfer() inside the ERC20 smart contract.用户调用 ERC1155 中的function buyNFT()调用ERC20智能合约中的 function transfer() My problem relies in making the "bridge" between these two contracts.我的问题在于在这两个合同之间架起“桥梁”。 I've tried using the low-level function delegatecall() but with no success since it always returns a tuple whose first value is false .我试过使用低级 function delegatecall()但没有成功,因为它总是返回一个第一个值为false的元组。

在此处输入图像描述

This is my code so far:到目前为止,这是我的代码:

abstract ERC20 {
    function _transfer(
        address _from,
        address _to,
        uint256 _value
    ) internal {}

    function transfer(address _to, uint256 _value)
        public
        returns (bool success)
    {
        _transfer(msg.sender, _to, _value);
        return true;
    }
}

contract ERC1155 {
    function buyNFT(uint256 _NFTPrice, address _to)
        public
        returns (bytes memory)
    {
        (bool success, bytes memory returnData) = 0x00...00.delegatecall(
            abi.encodeWithSelector(HRC20.transfer.selector, _to, _NFTPrice)
        );

        if (!success) {
            if (returnData.length == 0) revert("here");

            assembly {
                revert(add(32, returnData), mload(returnData))
            }
        }

        return returnData;
    }

}

Sorry for no code highlight, it seems stack overflow doesn't support the .sol extension.抱歉没有代码突出显示,似乎堆栈溢出不支持.sol扩展名。

Also, I've tried using abi.encodePacked() , abi.encode() , abi.encodeWithSignature() .另外,我尝试过使用abi.encodePacked()abi.encode()abi.encodeWithSignature()

As @bbbbbbbbb had commented, the transaction flow would be:正如@bbbbbbbbbb 所评论的那样,交易流程将是:
1 - user calls approve function on ERC20 smart contract, passing the address of ERC1155 and the NFT price; 1 - 用户调用approve智能合约上的ERC20 ,传递ERC1155的地址和NFT价格;
2 - user calls the buyNFT function on ERC1155 which will call the transferFrom function of ERC20 ; 2 - 用户在 ERC1155 上调用buyNFT ERC1155将调用 ERC20 的transferFrom ERC20
3 - In this way, the tokens are debited from the user's account and credited to the ERC1155 contract, thus requiring a function to withdraw these payments. 3 - 通过这种方式,代币从用户账户中扣除并记入 ERC1155 合约,因此需要 function 来提取这些付款。

The drawback is that the user needs to sign two transactions to buy the NFT when the used currency to sell it isn't the network token.缺点是当用于出售 NFT 的货币不是网络代币时,用户需要签署两笔交易来购买 NFT。

The final code would be:最终代码将是:

interface ERC20 {
    function transferFrom(
        address _from,
        address _to,
        uint256 _value
    ) internal {}
}

contract ERC1155 {
    ERC20 erc20Contract = ERC20(0x1234...5678);

    function buyNFT(uint256 price)
        external
    {
        erc20Contract.transferFrom(msg.sender, price);
        // I'm assuming the `transferFrom` will revert if user
        // doesn't have sufficient balance, otherwise, we would need to check
        // for the return value and revert if needed

       _mint(msg.sender, tokenId, quantity);
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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