简体   繁体   English

如何通过另一个智能合约转移 ERC20 代币?

[英]How can I transfer ERC20 token by another smart contract?

I have designed an erc20 token and a smart contract to transfer that token, but when I trigger the function to transfer, the remix told me the following graph.我设计了一个 erc20 代币和一个智能合约来传输该代币,但是当我触发 function 进行传输时,remix 告诉我下图。

在此处输入图像描述

What I did was to deploy the token smart contract and then the DAO smart contract, then call the creatSubDAO function to start the transfer.我所做的是部署token智能合约,然后部署DAO智能合约,然后调用creatSubDAO function开始转账。

The relative code is below:相关代码如下:

// SPDX-License-Identifier: GPL-3.0
 pragma solidity >=0.7.0 <0.9.0;


interface IERC20 {

function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);

function transfer(address recipient, uint256 amount) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);


event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}

contract Dtoken:合约Dtoken:

contract Dtoken is IERC20{

string public name = "DAO Token";
string public symbol = "D";
uint256 public totalSupply = 1000000000000000000000000;
uint8 public decimals = 18;

mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;

constructor() {
    balanceOf[msg.sender] = totalSupply;
}

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

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

function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
    require(_value <= balanceOf[_from]);
    require(_value <= allowance[_from][msg.sender]);
    balanceOf[_from] -= _value;
    balanceOf[_to] += _value;
    allowance[_from][msg.sender] -= _value;
    emit Transfer(_from, _to, _value);
    return true;
   }
 }

contract MasterDao:合约MasterDao:

import "./Dtoken.sol";

contract MasterDAO {

uint proposalNum;

mapping (address => Member) public members;
mapping (uint => Proposal) public proposals;
mapping (uint => SubDAO) public subDAOs;
// SubDAO[] public subDAOs;

function createSubDAO (uint _poolGap, uint _DAOID, uint _rate, Dtoken _token) public returns (address daoAddress) {
    SubDAO subDAO = new SubDAO(_poolGap, _DAOID, msg.sender, _rate, this, _token);
    daoAddress = address(subDAO);
}} 

SubDao Contract: SubDao 合约:

 contract SubDAO {

uint proposalNum;
address lender;
uint poolGap;
uint currentStake;
uint256 public DAOID;
MasterDAO master;
address stakeItem;
uint rate;
Dtoken public token;

mapping(address => Member) members;
mapping (uint => Proposal) public proposals;

string[] description;

event Transfrom(address, uint);

struct Member {
    address memberAddress;
    string nickName;
    bool alreadyExist;
}


struct Proposal {
    string description;
    address payable recipient;
    bool executed;
    uint proposalID;
    address[] agreeMembers;
    address[] disagreeMembers;
    bool exectuable;
    uint amount;
    Dtoken token;
}

modifier membership (MasterDAO masterDAO, address _staker){
    require(masterDAO.addressExist(_staker) == true);
    _;
}

modifier lenderLimit {
    require(msg.sender == lender);
    _;
}

modifier balanceLimit(uint amount) {
    require(amount <= poolGap - currentStake);
    _;
}

constructor (uint _poolGap, uint _DAOID, address _lender, uint _rate, MasterDAO caller, Dtoken _token) {
    currentStake = 0;
    poolGap = _poolGap;
    DAOID = _DAOID;
    lender = _lender;
    master = caller;
    rate = _rate;
    token = _token;
    token.transferFrom(address(this), address(this), 10);
}

Did I do anything wrong to transfer the token?我在转移令牌时做错了什么吗? Thanks!谢谢!

From the SubDao constructor:从 SubDao 构造函数:

token.transferFrom(address(this), address(this), 10);

This snippet is trying to transfer tokens from the just created SubDao address (1st argument) to the very same address (2nd argument).这个片段试图将令牌从刚刚创建的 SubDao 地址(第一个参数)转移到同一个地址(第二个参数)。

The newly created SubDao address most likely doesn't own any tokens to transfer from in the first place.新创建的 SubDao 地址很可能一开始不拥有任何可以转移代币。


If you want to transfer tokens from the MasterDao to the newly created SubDao , you can remove the transferFrom() from the SubDao constructor, and implement the transfer in the MasterDao function createSubDAO() :如果您想将令牌从MasterDao转移到新创建的SubDao ,您可以从SubDao构造函数中删除transferFrom() ,并在MasterDao function createSubDAO()中实现转移:

function createSubDAO (uint _poolGap, uint _DAOID, uint _rate, Dtoken _token) public returns (address daoAddress) {
    SubDAO subDAO = new SubDAO(_poolGap, _DAOID, msg.sender, _rate, this, _token);
    daoAddress = address(subDAO);

    // transfer 10 units of the `Dtoken`
    // from the `MasterDao` address
    // to the newly created `SubDao` address
    // assuming that `MasterDao` has sufficient token balance
    Dtoken(_token).transfer(daoAddress, 10);
}}

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

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