contract StandardToken is ERC20, BasicToken{
  //ERC20에 선언된 인터페이스를 구현하는 컨트랙트.

  mapping (address => mapping (address => uint)) internal allowed;
  // allowed 매핑은 '누가','누구에게','얼마의' 인출권한을 줄지를 저장하는 것. ex) allowed[누가][누구에게] = 얼마;

  function transferFrom(address _from, address _to, uint _value) public returns (bool){
    require(_to != address(0));
    require(_value <= balances[_from]);
    require(_value <= allowed[_from][msg.sender]);
    //보내려는 토큰개수가 계좌주인 _from이 돈을 빼려는 msg.sender에게 허용한 개수보다 작거나 같으면 참.
    //_fromr에게 인출권한을 받은 msg.sender가 가스비를 소모함.

    balances[_from] = balances[_from].sub(_value);
    balances[_to] = balances[_to].add(_value);
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
    emit Transfer(_from,_to,_value);
    return true;

  }

  function approve(address _spender, uint _value) public returns (bool){
    allowed[msg.sender][_spender] = _value;
    //msg.sender의 계좌에서 _value 만큼 인출해 갈 수 있는 권리를 _spender 에게 부여한다.
    emit Approval(msg.sender,_spender,_value);
    return true;
  }

  function allowance(address _owner, address _spender) public view returns (uint){
    return allowed[_owner][_spender];
  }

}
function transferFrom(address _from, address _to, uint _value) public returns (bool){
  require(_to != address(0));
  require(_value <= balances[_from]);
  require(_value <= allowed[_from][msg.sender]);
  //보내려는 토큰개수가 계좌주인 _from이 돈을 빼려는 msg.sender에게 허용한 개수보다 작거나 같으면 참.
  //_fromr에게 인출권한을 받은 msg.sender가 가스비를 소모함.

  balances[_from] = balances[_from].sub(_value);
  balances[_to] = balances[_to].add(_value);
  allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
  emit Transfer(_from,_to,_value);
  return true;

}

// allowed 매핑은 '누가','누구에게','얼마의' 인출권한을 줄지를 저장하는 것. ex) allowed[누가][누구에게] = 얼마;