GETH, Ganache, 이더스캔 만들어보기

geth (Go Ethereum) 사용해보기

Geth다운로드 후 설치, Cmder mini버전으로 다운, 설치후에

Cmder mini 관리자권한으로 실행

genesis.json 파일 받고 바탕화면에 eth라는 폴더 생성, genesis.json 넣기

Json 파일

{
  "config": {
    "chainId": 10,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "constantinopleBlock": 0,
    "petersburgBlock": 0,
    "istanbulBlock": 0,
    "ethash": {}
  },
  "nonce": "0x0",
  "timestamp": "0x5e4a53b2",
  "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "gasLimit": "0x47b760",
  "difficulty": "0x80000",
  "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "alloc": {
  },
  "number": "0x0",
  "gasUsed": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}

Geth 실행

//제네시스 블록 초기화 실행
$ geth init genesis.json

//geth 실행 명령어
$ geth --maxpeers 10 --rpc --rpcport 8545 --rpcaddr "0.0.0.0" --rpccorsdomain "*" --rpcapi "admin,db,eth,miner,personal,web3,net,txpool" --allow-insecure-unlock console 2>> eth.log
// account 생성
// 마이너는 코인베이스 계정 설정이 필요하기 때문에 계정 생성 필요
> personal.newAccount("passphrase")

// 생성된 키 스토어 파일은 다른 지갑에서 임포트하여 사용
// 어카운트 생성할 때 마다 키스토어 파일 생성

// ether 밸런스 확인
> eth.getBalance(eth.accounts[0])

// set coinbase
> eth.coinbase
> miner.setEtherbase(eth.accounts[1])

// mining
> miner.start()
> miner.stop()

// 블록 넘버 확인
> eth.blockNumber

// ether 전송
> eth.sendTransaction({from:eth.accounts[0], to:eth.accounts[1], value:web3.toWei(1, "ether")})

// unlock account
> personal.unlockAccount(eth.accounts[0], 'passphrase')

// txpool 확인
> txpool

// enode 확인
> admin.nodeInfo.enode

// 피어 연결
> admin.addPeer(enode)

마이닝이 진행되고 블록의 개수가 40개 정도 된다면 멈춰도 ok, 계정별 소지 이더를 확인하고 unlock으로 계정이 풀린다면 계정간 sendTransaction으로 이더 송금이 가능. 송금한 후에 txpool을 보면 pending된 trx가 생길텐데 sendTransaction을 실행하고 mining을 진행해주어야 거래가 처리된다.

enode확인을 통해 채굴자들 간의 주소를 확인하고 피어연결을 통해 피어를 연결시킬 수 있다. 피어가 성공적으로 연결된다면 blockNumber를 확인해보았을 때 피어들 중 가장 긴 블록이었던 사람의 블록이 메인으로 설정되고, 나머지 블록은 거짓블록이 된다. 따라서 피어연결을 했다면 mining을 통해 다시 채굴을 진행하여야 한다.

컨트랙트를 배포하고 싶다면 remix를 통해 컨트랙트를 작성하고, remix 좌측의 Environment설정을 web3 Provider로 변경하여 자신의 localhost주소로 연결한다면 생성한 계정의 정보도 불러와지고, 배포도 가능하다

가나슈 설치

가나슈는 시드구문을 바탕으로 여러개의 개인 키를 만들어주고, remix의 js vm과 같이 쉽게 테스트해볼수 있는 임시 환경을 조성해주는 것이다.
사용을 위해서는 우선 vsc에서 사용할 폴더를 만들고 터미널에



npm install -g ganache-cli

ganache-cli

입력 및 실행,

그리고나서 폴더 생성후에 index.html 파일 하나 만들고,

lib.zip

압축파일 속 파일 두개와 같이 폴더에 넣는다.

Ganache Scan

<!DOCTYPE html>
<html lang="en">

<head>
  <title>Ganache Scan</title>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  <script type="text/javascript" src="./bignumber.min.js"></script>
  <script type="text/javascript" src="./web3.js"></script>

  <script type="text/javascript">
    if (typeof web3 !== "undefined") {
      web3 = new Web3(web3.currentProvider);
    } else {
      // set the provider you want from Web3.providers
      web3 = new Web3(
        new Web3.providers.HttpProvider("http://localhost:8545")
      );
    }

    console.log(web3);

    if (web3.isConnected()) {
      console.log("connected");
    } else {
      console.log("not connected");
    }

    let accounts = web3.eth.accounts;
    console.log(accounts);

    let balance = web3.eth.getBalance(accounts[0]);
    console.log(web3.fromWei(balance).toNumber() + "ETH");

    for (var i = 0; i < accounts.length; i++) {
      document.getElementById().innerHTML = accounts[i];
      document.getElementById().innerHTML =
        web3.fromWei(web3.eth.getBalance(accounts[i])).toNumber() + "ETH";
    }

    function table() {
      var h = [];
      for (var address of accounts) {
        h.push("<tr>");
        h.push("<td>" + address + "</td>");
        h.push(
          "<td>" +
          web3.fromWei(web3.eth.getBalance(address)).toNumber() +
          "ETH" +
          "</td>"
        );

        h.push("</tr>");
      }

      document.getElementById("tb").innerHTML = h.join("");
    }

    function sendETH() {
      let from = document.getElementById("accountFrom").value;
      console.log();
      let to = document.getElementById("accountTo").value;
      let ethValue = document.getElementById("amountETH").value;
      let txhash = web3.eth.sendTransaction({
        from: from,
        to: to,
        value: web3.toWei(ethValue, "ether"),
      });
      console.log(typeof txhash);
      document.getElementById("txHash").value = txhash;
      table();
      getTrxDetail()



    }

    function getBlockDetail() {
      var D = [];
      let num = document.getElementById("blockNum").value;

      web3.eth.getBlock(num, function (error, block) {
        console.log(block);
        for (i in block) {
          D.push("<tr>");

          D.push("<td>" + i + "</td>");
          D.push("<td>" + block[i] + "</td>");

          D.push("</tr>");
        }
        document.getElementById("BD").innerHTML = D.join("");
      });
    }

    function getTrxDetail() {
      var T = [];
      let trxHash = document.getElementById("txHash").value;

      web3.eth.getTransaction(trxHash, function (error, tx) {
        console.log(tx);
        for (j in tx) {
          T.push("<tr>");

          T.push("<td>" + j + "</td>");
          T.push("<td>" + tx[j] + "</td>");

          T.push("</tr>");
        }
        document.getElementById("trx").innerHTML = T.join("");
      });
    }

    function createAccount() {
      let pwd = document.getElementById("PW").value;
      web3.personal.newAccount(pwd);

    }
  </script>

  <style>
    table,
    th,
    tb {
      border-collapse: collapse;
      max-width: 736px;
    }

    table {
      width: 100%;
      max-width: 736px;
    }

    th,
    td {
      border: 1px solid #ddd;
      padding: 10px;
      max-width: 736px;
      word-break: break-all;
    }
  </style>

  <title>Document</title>
</head>

<body>
  <div>
    <h1>Ganache Scan</h1><br>
    <label for="">Create Account </label>
    <input type="password" placeholder="Set your PW" value="" id="PW">
    <button onclick="createAccount()">Create</button>
  </div>
  <button onclick="table()">Show</button>
  <button onclick="sendETH()">Send</button>
  <button onclick="getBlockDetail()"> Get Block info</button>
  <button onclick="getTrxDetail()"> Get Trx info</button>

  <br />
  <label for="">From</label>
  <input type="text" id="accountFrom" value="" />
  <label for="">To</label>
  <input type="text" id="accountTo" value="" />
  <label for="">Value</label>
  <input type="text" id="amountETH" value="" />
  <br />
  <label for="">Trx hash address</label>
  <input type="text" id="txHash" value="" placeholder="Enter Trx hash" />
  <label for="">Search Block Info</label>
  <input type="text" id="blockNum" value="" placeholder="Enter BlockNum" />
  <div>
    <table>
      <thead>
        <tr>
          <th>Address</th>
          <th>Balance(ETH)</th>
        </tr>
      </thead>
      <tbody id="tb">
        <tr>
          <td>Press "show" button, address will be loaded</td>
          <td>Balance</td>
        </tr>
      </tbody>
    </table>
  </div>

  <div>
    <table>
      <thead>
        <tr>
          <th colspan="2">Trx Detail</th>
        </tr>
      </thead>
      <tbody id="trx">
        <tr>
          <td></td>
          <td></td>
        </tr>
      </tbody>
    </table>
  </div>
  <div>
    <table>
      <thead>
        <tr>
          <th colspan="2">Block Detail</th>
        </tr>
      </thead>
      <tbody id="BD">
        <tr>
          <td></td>
          <td></td>
        </tr>
      </tbody>
    </table>
  </div>
</body>

</html>

자바스크립트 HTML의 경우 이런식으로 script의 type과 src를 지정을 통해 js파일들을 사용하고, vsc 익스텐션 설치를 통해 확인한다

위의 코드는 간단히 작성해본 Ganache Scan으로, 가나슈로부터 생성된 10개의 account주소를 바탕으로 간단한 계정별 balance확인, 비밀번호 입력을 통한 새 계정 생성, 계정 간 송금, 해시주소를 통한 트랜잭션의 상세정보와 블록넘버를 통한 블록 상세정보를 확인해볼수 있는 html페이지이다.

이 같이 Ganache나 geth 등의 가상 테스트넷과 유사한 환경으로부터 계정, 블록, Trx등 체인의 여러 구성요소들을 불러오고 활용하여 web상에 표현해주는 연습을 많이 해보는 것이 중요하다. 이번 연습의 경우에는 자바스크립트로 진행했지만 vue를 활용하거나 다른 방법으로 프론트 영역에서 블록체인 데이터를 사용하는 것이 가능하다.

cf. Ganache 사용법, function들

+코드설명 추가
web3.eth.sendTransaction는 송금이 이루어진 수 자동으로 송금에 대한 Trx값을 리턴해준다.
web3.eth.getBlock(num, function (error, block), 또는 web3.eth.getTransaction(trxHash, function (error, tx) 같은 경우 error가 발생하면 error시 실행할 상황을 지정할 수 있다.

좋은 웹페이지 즐겨찾기