4. Code Example

erc20.jpg

https://solidity-by-example.org/app/erc20/

4-1. Buy and sell token

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import "<https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol>";

contract Ethswap {

    ERC20 public token;     //ERC20 token이라는 토큰 변수
    uint public  rate = 100;
    
    constructor(ERC20 _token){
        token = _token;
    }

    function getToken() public view returns(address) {
        //getToken은 CA값을 리턴하는 함수, token상태변수를 address형으로 변경
        return address(token); //Aiden token CA
    }

    function getSwapBalance() public view returns (uint) {
        return token.balanceOf(msg.sender); //토큰 CA와 상호작용으로 토큰 자체 balanceOf함수로 잔액호출
    }

    function getThisAddress() public view returns (address) {
        return address(this); //this = ethswap CA를 구하기 위함
    }
    
    function getMsgSender() public view returns (address){
        return msg.sender; //이더를 실행시킨사람, txObject 참고
    }

    // function getTokenOwner() public view returns(address){
    //     return token.getTokenOwner(msg.sender);
    // }
    function buyToken() public payable {
        uint256 tokenAmount = msg.value * rate;
        require(token.balanceOf(address(this)) >= tokenAmount, "ERROR [1]");
        token.transfer(msg.sender, tokenAmount);
    }

    function sellToken(uint256 _amount) public  payable {
        require(token.balanceOf(msg.sender) >= _amount);
        uint256 etherAmount = _amount / rate ;
        require(address(this).balance >= etherAmount); // EthSwap이 가지고 있는 이더가 etherAmount보다 많은가?
        token.transferFrom(msg.sender, address(this), _amount);  // accoun1 -> EthSwap token 전송
        payable(msg.sender).transfer(etherAmount);
    }
}

4-2. Swap token

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "<https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.0.0/contracts/token/ERC20/IERC20.sol>";

/*
How to swap tokens

1. Alice has 100 tokens from AliceCoin, which is a ERC20 token.
2. Bob has 100 tokens from BobCoin, which is also a ERC20 token.
3. Alice and Bob wants to trade 10 AliceCoin for 20 BobCoin.
4. Alice or Bob deploys TokenSwap
5. Alice approves TokenSwap to withdraw 10 tokens from AliceCoin
6. Bob approves TokenSwap to withdraw 20 tokens from BobCoin
7. Alice or Bob calls TokenSwap.swap()
8. Alice and Bob traded tokens successfully.
*/

contract TokenSwap {
    IERC20 public token1;
    address public owner1;
    uint public amount1;
    IERC20 public token2;
    address public owner2;
    uint public amount2;

    constructor(
        address _token1,
        address _owner1,
        uint _amount1,
        address _token2,
        address _owner2,
        uint _amount2
    ) {
        token1 = IERC20(_token1);
        owner1 = _owner1;
        amount1 = _amount1;
        token2 = IERC20(_token2);
        owner2 = _owner2;
        amount2 = _amount2;
    }

    function swap() public {
        require(msg.sender == owner1 || msg.sender == owner2, "Not authorized");
        require(
            token1.allowance(owner1, address(this)) >= amount1,
            "Token 1 allowance too low"
        );
        require(
            token2.allowance(owner2, address(this)) >= amount2,
            "Token 2 allowance too low"
        );

        _safeTransferFrom(token1, owner1, owner2, amount1);
        _safeTransferFrom(token2, owner2, owner1, amount2);
    }

    function _safeTransferFrom(
        IERC20 token,
        address sender,
        address recipient,
        uint amount
    ) private {
        bool sent = token.transferFrom(sender, recipient, amount);
        require(sent, "Token transfer failed");
    }
}