solidity - How can i transfer ERC20 tokens from a contract to an user account? - Ethereum Stack Exchange

Tags
URLhttps://ethereum.stackexchange.com/questions/46318/how-can-i-transfer-erc20-tokens-from-a-contract-to-an-user-account/46360

Escrowing ERC20 tokens:

Your escrow contract needs to know when it received new tokens, from whom, and how many.

This is achieved by having the "seller" create two transactions:

  1. Approval: First transaction calls token contract
// tracker_0x_address is the address of the ERC20 contract they want to deposit tokens from ( ContractA )
// spender is your deployed escrow contract address

ERC20(tracker_0x_address).approve(address spender, uint tokens)
  1. Deposit: Second transaction calls a method in the escrow contract
mapping ( address => uint256 ) public balances;
deposit(uint tokens) {

  // add the deposited tokens into existing balance
  balances[msg.sender]+= tokens;

  // transfer the tokens from the sender to this contract
  ERC20(tracker_0x_address).transferFrom(msg.sender, address(this), tokens);
}

This updates the sender's balance, and then transfers the tokens from sender to escrow (contractB).

Releasing escrowed tokens:

All your smart contract has to do is call the

ERC20(tracker_0x_address).transfer(msg.sender, balances[msg.sender]);

on the token tracker address in order to transfer those tokens to an address.

If you're doing multiple tokens and multiple users in one contract you're going to have to implement a second layer mapping for the balances as well as support for a tracker variable in the deposit method.

Code Example

// ----------------------------------------------------------------------------
// ERC Token Standard #20 Interface
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
// ----------------------------------------------------------------------------
pragma solidity ^0.4.17;

contract ERC20 {
    function totalSupply() public constant returns (uint);
    function balanceOf(address tokenOwner) public constant returns (uint balance);
    function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
    function transfer(address to, uint tokens) public returns (bool success);
    function approve(address spender, uint tokens) public returns (bool success);
    function transferFrom(address from, address to, uint tokens) public returns (bool success);
    event Transfer(address indexed from, address indexed to, uint tokens);
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}

contract contractB {
  address tracker_0x_address = 0xd26114cd6EE289AccF82350c8d8487fedB8A0C07; // ContractA Address
  mapping ( address => uint256 ) public balances;

  function deposit(uint tokens) public {

    // add the deposited tokens into existing balance
    balances[msg.sender]+= tokens;

    // transfer the tokens from the sender to this contract
    ERC20(tracker_0x_address).transferFrom(msg.sender, address(this), tokens);
  }

  function returnTokens() public {
    balances[msg.sender] = 0;
    ERC20(tracker_0x_address).transfer(msg.sender, balances[msg.sender]);
  }

}