블록체인

ERC20 각 라인마다 코드 이해하기

이영훈닷컴 2025. 3. 1. 10:33
728x90
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.8.0;

// 기본 토큰 인터페이스 정의
contract Token {
    // 특정 주소의 잔액을 조회하는 함수 (가상함수 - 상속받은 계약에서 구현해야 함)
    function balanceOf(address _owner) public virtual view returns (uint256 balance){}
    
    // 토큰을 다른 주소로 전송하는 함수 (가상함수)
    function transfer(address _to, uint256 _value) public virtual returns (bool success){}
    
    // 허가된 주소가 토큰을 전송하도록 하는 함수
    function transferFrom(address _from, address _to, uint256 _value) public returns(bool success){}
    
    // 특정 주소에게 토큰을 사용할 권한을 부여하는 함수
    function approve(address _spender, uint256 _value) public returns (bool success){}
    
    // 허가된 주소가 사용할 수 있는 토큰의 양을 반환
    function allowance(address _owner, address _spender) public view returns (uint256 remaining){}
    
    // 토큰 전송이 발생했을 때 이벤트 발생
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    
    // 허가가 발생했을 때 이벤트 발생
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}

// Token 인터페이스를 구현하는 기본 토큰 컨트랙트
contract StandardToken is Token {
    // 주소별 잔액을 저장하는 매핑
    mapping(address => uint256) balances;
    
    // 토큰 전송 함수 구현
    function transfer(address _to, uint256 _value) public override returns (bool success){
        // 보낸 사람이 충분한 잔액이 있는지와 전송 금액이 0보다 큰지 확인
        if(balances[msg.sender] >= _value && _value > 0){
            balances[msg.sender] -= _value; // 보낸 사람 잔액 감소
            balances[_to] += _value; // 받는 사람 잔액 증가
            emit Transfer(msg.sender, _to, _value); // 이벤트 발생
            return true;
        } else {
            return false; // 전송 실패
        }
    } 
    
    // 잔액 조회 함수 구현
    function balanceOf(address _owner) public override view returns (uint256 balance){
        return balances[_owner];
    }
}

// DiabetesToken (DBT) 토큰 컨트랙트 구현
contract DiabetesToken is StandardToken{
    string public name; // 토큰 이름
    uint8 public decimals; // 소수점 자릿수 (18로 설정하면 1 토큰 = 10^18)
    string public symbol; // 토큰 심볼 (DBT)
    string public version = 'H1.0'; // 버전
    uint256 public Token_OneEthCanBuy; // 1 ETH당 구매 가능한 토큰 개수
    uint256 public totalEthInWei; // 컨트랙트에 들어온 이더리움 총액 (Wei 단위)
    address payable public fundManager; // 펀드 관리자 주소
    uint256 public totalSupply; // 토큰 총 발행량
    
    // 생성자: 토큰 발행 및 초기화
    constructor(){
        balances[msg.sender] = 300000000000000000000; // 300 DBT 발행 (18자리 소수 포함)
        totalSupply = 300000000000000000000; // 총 발행량
        name = "DiabetesToken"; // 토큰 이름 설정
        decimals = 18; // 소수점 자릿수 설정
        symbol = "DBT"; // 심볼 설정
        Token_OneEthCanBuy = 10; // 1 ETH당 10 DBT 구매 가능
        fundManager = msg.sender; // 배포한 주소를 펀드 관리자 지정
    }

    // 이더리움을 컨트랙트에 보냈을 때 자동 실행되는 함수
    fallback() external payable { 
        totalEthInWei += msg.value; // 들어온 이더리움 총액 증가
        uint256 amount = msg.value * Token_OneEthCanBuy; // 구매 가능한 토큰 수량 계산
        require(balances[fundManager] >= amount, "Not enough tokens"); // 펀드 관리자에게 충분한 토큰이 있는지 확인

        balances[fundManager] -= amount; // 펀드 관리자 토큰 감소
        balances[msg.sender] += amount; // 구매자에게 토큰 전송
        
        emit Transfer(fundManager, msg.sender, amount); // 토큰 전송 이벤트 발생
        
        fundManager.transfer(msg.value); // 이더리움을 펀드 관리자에게 전송
    }
}
728x90