본문 바로가기

이더리움

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

안녕하세요.

 

저번글에서 이더리움 테스트넷에서 나의 지갑주소에서 다른지갑주소로 이더리움 보내는부분에 대해 진행하였는데,

hooked-web3-provider이 보안성문제로 Deprecated되었다고 운영환경에선 다른 모듈을 사용하라고 말씀드렸었죠

 

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

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

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

 

 

테스트용 심플월렛이라 그냥 hooked-web3-provider을 사용해 만들려고했는데, 저도 살짝 찝찝함때문에 ethjs-provider-signer을 사용해 다시 코드를 작성하였습니다.

 

어떤모듈을 사용해도 별 상관없으신분은 그냥 이번 포스팅은 스킵하셔도 좋습니다.

 

 

먼저 npm이나 yarn을 사용해 ethjs-provider-signer , ethjs-signer, ethjs-query를 설치해주세요.

 

 

설치를 하셨으면 my_modules/web3 폴더안에 미들웨어로 사용할 web3Provider.js 파일을 만들어주세요.

 

이 모듈에선 저희 keystore에서 private key를 직접 추출해서 사용해야합니다. 

 

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

const SignerProvider = require('ethjs-provider-signer')

const sign = require('ethjs-signer').sign;

const Eth = require('ethjs-query');

 

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 privateKey;

 

        //private key 추출하기

        await keystore.keyFromPassword("123", (err, data) => {

            var key = keystore.exportPrivateKey(address.toString(), data)

            privateKey = '0x' + key

        })

 

        const provider = new SignerProvider('https://ropsten.infura.io/v3/ea99edfbfe4943cd83c853f68d27ce89', {

            signTransaction: (rawTx, cb) => cb(null, sign(rawTx, privateKey.toString())),

            accounts: (cb) => cb(null, [address.toString()]),

        });

 

        const eth = await new Eth(provider)

        req.eth = eth

 

//이부분은 현재 이더리움 네트워크의 평균 가스비를 가져오는 함수입니다.

        await eth.gasPrice(function (err, gas) {

            if (err) {

                console.log(err)

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

            }

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

            req.gas = gas.toString()

            next()

 

        })



    } catch (err) {

        console.log(err)

    }

}

 

module.exports = web3

 

그리고 wallet폴더의 index.js에서 sendEth API가 호출되었을때 미들웨어를 사용한다고 선언해주세요.

 

const router = require('express').Router();

const wallet = require('./wallet');

const web3Middleware = require('../../my_modules/web3/web3')

const keyMiddleware = require('../../my_modules/getPK')

const web3ProviderMiddleware = require('../../my_modules/web3/web3Provider') //추가된 부분

 

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

 

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

 

router.use('/getBalance',web3ProviderMiddleware) // 바뀐 부분

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



router.use('/sendEth',web3ProviderMiddleware) //바뀐 부분

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

 

module.exports = router

 

다음으로 wallet.js 파일의 sendEth API부분을 수정하겠습니다.

 

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

 

    var gasPrice = req.gas

 

    await req.eth.sendTransaction({

        from: "보내는사람 지갑주소", 

        to: "받는사람 지갑주소",

        gas: 50000,

        gasPrice: gasPrice * 1.5, //곱하기 1.5를 해준이유는 가스비를 평균보다 높혀 tx속도를 높히기위함입니다.

        data: "0x",

        value: 100000000000000,

    }, function (err, tx) {

        if (err)

            console.log(err)

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

    })

 

}

 

이렇게 새로운 모듈을 사용하여 코드를 수정하였습니다.

다음 포스팅부터는 hooked-web3-provider이 아닌 ethjs-provider-signer를 사용하여 모든 테스트를 진행하겠습니다.

 

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

 

 

 

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