본문으로 바로가기

이더리움의 스마트 컨트랙트를 이용하여 ICO에 사용할수 있는 ERC20 토큰을 생성해보도록 하겠습니다.

블록체인의 코인을 만들수 있는 방법은 크게 다음과 같이 나누어볼수 있습니다.


1. ERC20 표준을 만족하는 코드를 작성하여 작성

 - 가장 기본적인 작성방법으로 정의된 규약에 맞게 제작하는 방법입니다.

   하지만 해당 규약을 명확하게 이해를 해야하고, 충분한 검증이 선행되어야 한다는 문제가 있을수 있습니다.

   ERC20 표준에 대해서는 하기 페이지를 참고하시기 바랍니다.


     https://www.ethereum.org/token

     https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md

     https://theethereum.wiki/w/index.php/ERC20_Token_Standard

     

2. Open Zeppelin이나 Token factory등의 오픈소스 프로젝트를 사용하여 제작 

- 현재 ERC20 토큰을 제작하는데 가장 많이 사용되고 있으며, 충분히 검증이 이루어진 안정화된 재사용 코드를 사용하기 때문에 가장 추천할만한 제작방법입니다.


     https://github.com/ConsenSys/Token-Factory/blob/master/contracts/StandardToken.sol

     https://github.com/OpenZeppelin/zeppelin-solidity


3. 비트코인 기반 소스를 재사용하여 Alt coin 작성

- 가장 난이도가 높다고 할수 있는 방법으로 비트코인 이후 신규로 등장한 많은 alt 코인들의 제작에  사용된 방법으로 많은 alt 코인들이 비트코인 소스 기반으로 제작된 lite coin의 소스를 변경하여 각자 독자적인 코인을 만들었습니다. 비트코인 소스구조 파악과 빌드환경 구축이 필요하기 때문에 쉽게 접근하기는 어려운 방법이라고 할수 있습니다.


이번 포스팅은 Token factory를 사용하여 제작된 하기 포스팅을 참고로 하였습니다.


"How to build your own Ethereum based ERC20 Token and launch an ICO in next 20 minutes"


먼저 이번 포스팅에서는 geth와 Mist wallet을 사용하지않고, 구글 크롬 확장프로그램인 MetaMask 이더리움 Wallet과 Testnet을 사용하여 진행을 하도록 하겠습니다.

구글 크롬의 Web market에서 MetaMask를 검색하여 확장프로그램을 설치합니다.



그리고 스마트 컨트랙트 제작에 이더가 사용되기 때문에 테스트넷에서 테스트 이더를 사용하기 위해 다음과 같이 테스트넷으로 접속하고 테스트이더를 요청합니다. 하기와 같이 테스트넷에 접속후 Buy 를 선택하면 테스트 이더를 요청할수 있고, 한번 요청시 1 이더를 받을수 있습니다.



다음과 같이 5번 요청하여 5 이더를 받을수 있습니다.



이제 solidity 코드를 작성할 차례입니다.

전체 작성코드는 github 에서 다운로드 받을수 있습니다.


먼저 코드에서 contract Token 부분에서 ERC20 토큰의 인터페이스를 정의하고 있습니다.

이더리움상에서 사용하기 위한 ERC20 토큰은 하기 인터페이스를 반드시 정의하고 구현해놓아야 합니다.


// 현재까지 공급된 토큰수
function totalSupply() constant returns (uint256 supply) {}
// _owner가 보유한 토큰잔액을 반환
function balanceOf(address _owner) constant returns (uint256 balance) {}
// 수신자(_to) 로 해당금액(_value)를 송금. 송금이 성공하면 TRUE를 반환하고, 실패하면 FALSE를 반환.
function transfer(address _to, uint256 _value) returns (bool success) {}
//송신자(_from)주소에서 수신자(_to) 주소로 해당금액(_value)을 송금. 송금이 성공하면 TRUE를 반환하고, 실패하면 FALSE를 반환.
// transferFrom이 성공하려면 먼저 approve 인터페이스를 사용하여 일정금액을 인출할수 있도록 허락하여야 함.
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {}
// 송신자(msg.sender)가 보유한 토큰에서 일정금액(_value)만큼의 토큰을 인출할수 있는 권한을 수신자(_spender)에게 부여.
function approve(address _spender, uint256 _value) returns (bool success) {}
// 토큰 소유자(_owner)가 토큰 수신자(_spender)에게 인출을 허락한 토큰이 얼마인지를 반환.
function allowance(address _owner, address _spender) constant returns (uint256 remaining) {}
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);



가져온 토큰 코드에서 수정이 필요한 부분은 다음과 같습니다.

수정이 필요한 부분은 // CHANGE THIS 커멘트로 표시되어 있습니다.


하기의 코인이름을 만들고 싶은 코인명으로 변경합니다. 샘플코드에서는 "Super Ultra Power Coin~"으로 명시하였습니다.


contract SuperUltraPowerCoin is StandardToken { // CHANGE THIS. Update the contract name.


그리고 코인의 파라미터를 다음과 같이 변경가능합니다.


// This is a constructor function
// which means the following function name has to match the contract name declared above
function SuperUltraPowerCoin() {
balances[msg.sender] = 1000000000000000000000; // Give the creator all initial tokens. This is set to 1000 for example. If you want your initial tokens to be X and your decimal is 5, set this value to X * 100000. (CHANGE THIS)
totalSupply = 1000000000000000000000; // Update total supply (1000 for example) (CHANGE THIS)
name = "SuperUltraPowerCoin"; // Set the name for display purposes (CHANGE THIS)
decimals = 18; // Amount of decimals for display purposes (CHANGE THIS)
symbol = "SUPC"; // Set the symbol for display purposes (CHANGE THIS)
unitsOneEthCanBuy = 10; // Set the price of your token for the ICO (CHANGE THIS)
fundsWallet = msg.sender; // The owner of the contract gets ETH
}


balances, totalSupply : 만들고자 하는 토큰의 전체갯수 (위의 예는 1000개)

name : 만들고자 하는 토큰명 (SuperUltraPowerCoin"

decimals : 소수점단위를 의미하며 디폴트 18로 설정해놓는것이 이더 단위와 일치하기 때문에 좋습니다. 

symbol : 토큰의 단축약어

unitsOneEthCanBuy : 해당 컨트랙트 주소로 이더를 송금하였을경우 자동으로 받게되는 토큰의 갯수. 위의 예는 10으로 설정하였기 때문에 1이더를 전송하명 10 토큰을 받게 됩니다.


코드작성은 Remix IDE를 사용하고 코드작성을 완료후 Run tab에서 작성하고자하는 토큰명을 선택하고 Create를 한후 하기화면과 같이 Test net에 접속되어있음을 확인하고  Submit을 선택합니다.



정상적으로 생성이 된후 다음과 같이 결과화면에서 생성결과 확인이 가능합니다.



다음과 정상적으로 생성되었음을 확인할수 있습니다. 


Contract address를 선택하고 "Contract code" 탭의 "Verify and publish"를 선택하여 contract 코드를 배포할수 있습니다.



Contract Names과 Compiler, Optimization이 Remix 작성시와 동일하게 설정하고 동일한 Solidity 코드를 입력한후 "Verify and publich"를 선택하면 해당코드를 컴파일한후에 배포가 되고, 다음과 같이 Contract address로 컨트랙트 소스코드 확인이 가능하게 됩니다.



이제 생성한 토큰을 MetaMask wallet에서 확인을 할 차례입니다.

ERC20 토큰의 경우 자신의 지갑에 해당 코인의 Contract address를 등록해주어야 관리할수 있습니다.

다음과 같이 MetaMask 에서 Token 메뉴에서 "Add Token" 을 통해 등록을 해주어야 하고, Add 메뉴상에 "Token Contract Address"는 위에 컨트랙트 결과의 To 의 Contract address를 입력하면 됩니다.

최종결과 다음과 같이 1000개의 SUPC이 생성되었음을 확인할수 있습니다.



이제 해당 컨트랙트 주소로 이더를 전송하여 토큰구입을 확인하도록 하겠습니다.

다음과 같이 다른 지갑을 생성하고, 테스트 이더를 전송받은후에 위에서 생성한 컨트랙트 주소로 2 이더를 전송하도록 하겠습니다.



다음과 같이 최종결과를 확인할수 있습니다.

3 이더를 보유하던 지갑에서 컨트랙트 주소로 2 이더를 전송하여 수수료를 제외한 잔액이 남고, 2 이더를 전송하여, 그에대한 거래로 20 SUPC 토큰을 받았습니다.

그리고 해당 트랜잭션도 다음과 같이 확인 가능합니다.