string public name; //fancy name: eg Simon Bucks uint8 public decimals; //How many decimals to show. string public symbol; //An identifier: eg SBX
functionEIP20( uint256 _initialAmount, string _tokenName, uint8 _decimalUnits, string _tokenSymbol ) public{ balances[msg.sender] = _initialAmount; // Give the creator all initial tokens totalSupply = _initialAmount; // Update total supply name = _tokenName; // Set the name for display purposes decimals = _decimalUnits; // Amount of decimals for display purposes symbol = _tokenSymbol; // Set the symbol for display purposes }
web3를 이용하여 테스트넷에 접속하기 위해서 www.infura.io 에 회원가입하여 API_KEY를 발급받습니다.테스트넷 접속 URL는 https://ropsten.infura.io/[API_KEY]의 형태가 됩니다. 아래와 같이 테스트넷에 연결합니다.
1 2 3 4 5
var Web3 = require('web3');
// 이더리움 테스트넷 연결 var TEST_NET_URL = 'https://ropsten.infura.io/[infura_api_key_here]'; var web3 = new Web3(new Web3.providers.HttpProvider(TEST_NET_URL));
컨트랙트 컴파일
이제 소스코드 EIP20.sol 파일을 컴파일합니다. 그리고 이더리움 노드에 등록할 토큰 컨트랙트를 생성하도록 하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
var path = require('path'); var solc = require('solc');
// 컴파일 하기 var contractSource = fs.readFileSync(path.resolve(__dirname, 'ERC20Token.sol'), 'utf8'); var compiledCode = solc.compile(contractSource.toString(), 1).contracts[':EIP20']; var bytecode = compiledCode.bytecode; var abiDefinition = JSON.parse(compiledCode.interface); var contract = web3.eth.contract(abiDefinition);
// 토큰 정보 입력 var name = '안피곤 코인'; // 코인 이름 var symbol = 'ANP'; // 코인 기호 var amount = 10000; // 초기 코인량 var decimals = 18; // 자연 단위수(10^18) var txInputData = '0x' + contract.new.getData(amount, name, decimals, symbol, {data: bytecode});
개인키 생성
트랜잭션을 서명할 개인키는 니모닉 워드를 사용하여 생성하겠습니다.
1 2 3 4 5 6 7 8 9
var Bitcore = require('bitcore-lib'); var Mnemonic = require('bitcore-mnemonic');
// 니모닉 워드(보통 12단어로 구성) var mnemonicWords = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'; var xPriKey = Mnemonic(mnemonicWords).toHDPrivateKey('', 'testnet'); // 확장 개인키 생성 var privkey = xPriKey.deriveChild("m/44'/60'/0'/0/0").privateKey; // 서명할 개인키 var fromAddress = '0x' + ethUtil.privateToAddress(privkey.toBuffer()).toString('hex'); console.log('fromAddress:', fromAddress); // 이더리움 주소
var EthTx = require('ethereumjs-tx'); var ethUtil = require('ethereumjs-util');
// 서명자의 주소 var fromAddress = '0x' + ethUtil.privateToAddress(privkey).toString('hex');
// 트랜잭션 생성 var nonce = web3.eth.getTransactionCount(fromAddress); // 트랜잭션 Nonce값 조회 var gasPrice = web3.eth.gasPrice; // 네트워크 가스 가격 조회 const rawTx = { nonce: web3.toHex(nonce), gasPrice: web3.toHex(gasPrice), // 가스 1개당 가격(wei 단위) gasLimit: web3.toHex(3000000), // 가스 최대 사용량 data: txInputData, // 컨트랙트 excute 함수 호출 데이터 chainId: 3, //네트워크 ID }
// 트랜잭션 서명 const tx = new EthTx(rawTx); // 트랜잭션 객체 생성 tx.sign(privkey); // tx 서명
트랜잭션 전송 및 컨트랙트 배포
이제 이더리움 네트워크에 트랜잭션을 전송합니다.
참고로 컨트랙트를 배포하기 위해서는 수수료를 지불할 수 있을 정도의 Ether가 있어야합니다. 테스트넷의 Ether를 받는 방법은 Faucet를 이용하는 것입니다.
1 2 3 4 5 6 7 8
var serializedTx = tx.serialize(); // hex serialize binary 생성 web3.eth.sendRawTransaction('0x' + serializedTx.toString('hex'), function(err, hash) { if (err) { console.log(err); return; } console.log('txHash:', hash); // tx hash 생성 });
트랜잭션을 전송하고 나서 출력된 txHash값을 이용하여 테스트넷 이더스캔(https://ropsten.etherscan.io/)에서 컨트랙트 주소를 확인합니다. 채굴이 완료되면 방금 등록한 토큰의 address가 보일 것 입니다.
토큰 확인
컨트랙트 주소가 생성되면 아래와 같이 토큰을 확인 할 수 있다.
1 2 3 4 5 6
var contractAddress = '[컨트랙트 주소]'; var contractInstance = web3.eth.contract(abiDefinition).at(contractAddress); console.log('symbol:', contractInstance.symbol.call()); console.log('decimals:', contractInstance.decimals.call().toNumber()); console.log('name:', contractInstance.name.call()); console.log('balance:', contractInstance.balanceOf.call(fromAddress).toNumber());