본문 바로가기

이더리움

이더리움 simple wallet 만들기 (2)

안녕하세요 저번 글에이어 이더리움 wallet만들기 두번째 글입니다.

 

eth-lightwallet 모듈을 사용해 mnemonic 코드와 wallet를 생성하고 keystore를 저장하는 부분까지 했었는데 오늘은 web3.js 모듈을 사용해 직접 이더리움 테스트넷에 tx를 배포하도록 하겠습니다.

 

이더리움 테스트넷에는 kovan,ropsten,rinkby등등 여러가지가 있는데 저희는 ropsten을 사용하도록 하겠습니다.

또한, 저희는 이더리움 노드를 구축할 환경이 안되기 때문에 infura를 통해서 ropsten 테스트넷과 통신을 할 예정입니다.

 

https://infura.io/ 

 

첫번째로, 위 링크에 들어가서 회원가입을 해주세요.

로그인을 해주시면 처음에 이 화면이 나오실텐데 CREATE NEW PROJECT를 클릭해 프로젝트를 먼저 생성하겠습니다.

 

 

 

프로젝트 이름을 정해주시고, 생성되면  VIEW PROJECT를 클릭해 프로젝트에 접속해주세요.

아래 빨간색으로 포인트준 ENDPOINT 부분을 ROPSTEN으로 바꿔주세요.

앞으로 저희는 geth로 만든 이더리움네트워크가 아닌 아래있는 주소를 저희의 endpoint로 사용하도록 하겠습니다.

 

마찬가지로 저희는 truffle나 geth를 사용하는게 아니기때문에 http/https통신을 하기위해 web3 provider라는게 필요합니다.

여러 좋은 provider가 있는데 저희는 빠르고 손쉽게 만들기 위해서 다루기 쉬운 hooked-web3-provider 를 사용할 예정입니다.

하지만 이 provider는 운영환경에서 사용하는건 가급적 자제해주시기 바랄게요. 테스트용으로만 사용해주세요.

 

운영 환경에서 사용하실 provider는 아래 두개를 사용해주시기 바랍니다.

https://github.com/ethjs/ethjs-provider-signer

https://github.com/metamask/provider-engine

 

그럼이제 web3.js hooked-web3-provider 모듈을 npm을 사용해 설치해주세요.

 

그리고 web3와 hookedweb3provider을 이용해서 제 address의 eth잔액을 조회해 보도록 하겠습니다.

 

exports.getBalance = async (req, res) => {

    var wallet = await readFile("wallet.json")

    var keystore = await lightwallet.keystore.deserialize(wallet);

    var address = await keystore.getAddresses()

    var eth= 0;

 

    var web3 = new Web3(

        new HookedWeb3Provider({

          host: "https://ropsten.infura.io/v3/사용자 계정 프로젝트마다 달라요!",

          transaction_signer: keystore

        })

      );

 

    await web3.eth.getBalance(address.toString(), async (err, data) => {

        if (err) console.log(err);

        

        eth = data.toString()

    

      });

      res.json({code:1,eth:eth})

}

 

위와같이 코드를 작성하시고 postman으로 api호출을 해보시면 위와같이 response가 날아올겁니다.

 

저는 미리 이더리움을 제 키스토어 wallet주소로 보내놨기 때문에 1.1이더리움이 있고, 아마 여러분은 0으로 나올거예요.

 

다들 아시다시피 이더리움은 decimal이 18자리까지 있어요 gwei, wei에 대해서 잘 모르시는분은 한번 찾아보시길 권장드립니다.

 

이제 제 지갑에 있는 이더리움을 다른지갑으로 보내는 트랜잰셕을 만드는 api를 만들어 보겠습니다.

 

그전에 저희는 앞으로 ropsten테스트넷에 연결된 web3를 자주 사용할 예정이기 때문에 따로 미들웨어로 만들고, eth-lightwallet 모듈자체를 수정해야 하기때문에 이 모듈도 따로 폴더로 빼서 수정하고 경로도 바꿔주려고 합니다.

 

eth-lightwallet가 front에서 사용되도록 설계되었는데 지금 저희는 express api서버로 만들기때문에 모듈의 수정이 불가피하네요.

 

일단 node-modules폴더안에서 eth-lightwallet 폴더를 찾아 my_modules폴더로 옮겨주세요.

wallet.js파일의 lightwallet 경로까지 바꿔주시면 됩니다.

 

 

이제 web3 미들웨어를 만들겠습니다.

이 미들웨어에는 현재 이더리움 네트워크의 가스비정보 조회도 같이 포함시키겠습니다.

아래 스크린샷은 현재 폴더 구조입니다.

 

web3.js 안에 아래와 같이 코드를 작성해주세요.

 

var Web3 = require("web3");

var lightwallet = require("eth-lightwallet");

var HookedWeb3Provider = require("hooked-web3-provider");

 

var fs = require('fs')

var util = require('util');

var readFile = util.promisify(fs.readFile)



const web3 = async (req,res,next)=>{

    try{

        var wallet  = await readFile("wallet.json")

        var keystore =await lightwallet.keystore.deserialize(wallet); 

        var address = keystore.getAddresses()      

 

        var web3 =await new Web3(

            new HookedWeb3Provider({

              host:"https://ropsten.infura.io/v3/ea99edfbfe4943cd83c853f68d27ce89",

              transaction_signer: keystore

            })

          );

 

          //가스비 정보 조회

          await web3.eth.getGasPrice(function(err,gas){

            if(err){

              console.log(err)

                res.json({code:999,err:"가스비 정보 조회 실패"})

            }

            console.log("####GASPRICE ::: ",gas)

            req.gas= gas

        })

 

          req.web3 = await web3;

          req.address = await address;

          next()

 

    }catch(err){

        console.log(err)

    }

}

 

module.exports=web3

 

미들웨어를 작성했으니 미들웨어를 호출해서 사용해봐야겠죠? wallet폴더안에 있는 index.js에

getBalance라는 api가 호출될때 미들웨어가 먼저 호출되도록 코드를 작성해주세요.

const web3Middleware = require('../../my_modules/web3/web3') //web3 미들웨어 import

router.use('getBalance',web3Middleware)

router.post('/getBalance',wallet.getBalance)

 

그 후에 wallet.js 파일의 getBance를 아래와 같이 수정해주시면 코드도 훨씬 가벼워지고 보기도 편해집니다.

 

exports.getBalance = async (req, res) => {

 

    var web3 = req.web3

    var eth= 0;

 

    await web3.eth.getBalance((req.address.toString()), async (err, data) => {

        if (err) console.log(err);

        eth = data.toString()

      });

      res.json({code:1,eth:eth})

}

 

이제 미들웨어도 만들었으니 다음 포스팅에서 sendTransaction 함수를 사용하여 이더리움 네트워크에 직접 tx를 만들고 배포해보도록 하겠습니다.

 

수고하셨습니다.

 

https://github.com/MinhoKim1018/eth-wallet/tree/ch02

 

 

이더리움 simple wallet 만들기 (3) 보러가기