월하점
월하점의 개발 공부 일지
월하점
전체 방문자
오늘
어제
  • 분류 전체보기 (96)
    • Back-end (3)
    • PROJECT (1)
    • CS (15)
      • Operating System (0)
      • Network (4)
      • Data Structure (7)
      • Algorithm (0)
      • Database (4)
    • Problem Solving (52)
    • Programming Languages (1)
      • Javascript (0)
      • Python (1)
      • JAVA (0)
    • Codestates BEB 4기 (7)
    • Blockchain (12)
    • Linux (2)
    • Git (1)
    • 잡다한 (2)

공지사항

인기 글

태그

  • node.js
  • 프로그래머스
  • 알고리즘
  • javascript
  • SWEA
  • Python
  • baekjoon
  • CS
  • 자료구조
  • 네트워크
  • django

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
월하점

월하점의 개발 공부 일지

  • HOME
  • GUEST
  • WRITE
[Project#2] eth-lightwallet 모듈을 이용한 니모닉 지갑
Blockchain

[Project#2] eth-lightwallet 모듈을 이용한 니모닉 지갑

2022. 6. 10. 15:53

니모닉(Mnemonic)이란?

: 지갑을 복구하기 위한 12개의 단어로, 개인 키가 복잡한 단어들로 구성되어 입력이 불편하다는 단점을 보완하기 위한 형식이다.

암호화폐 지갑은 비대칭키 암호방식을 사용하기 때문에 공개키와 비밀키가 존재한다. 니모닉 단어 목록은 비밀키를 사용자가 쉽게 읽고 쓸 수 있도록 만들어주며, 덕분에 지갑을 백업하기에도 좋다.


니모닉 지갑 개발하기

니모닉 지갑을 직접 구현하지 않아도 손쉽게 만들 수 있게 해주는 라이브러리가 있다.

바로 eth-lightwallet 모듈이다.

 

eth-lightwallet 모듈의 공식 깃허브

 

GitHub - ConsenSys/eth-lightwallet: Lightweight JS Wallet for Node and the browser

Lightweight JS Wallet for Node and the browser . Contribute to ConsenSys/eth-lightwallet development by creating an account on GitHub.

github.com

 

니모닉 지갑의 원리를 이해하기 위해 eth-lightwallet 모듈을 이용하여 간단한 Mnemonic Wallet을 개발할 것이다.

또한 개발한 기능이 정상적으로 작동하는지 API 테스트를 통해 확인해보자.

 

 


개발 요구 사항

  • eth-lightwallet 모듈에 내장되어 있는 함수를 사용하여 개발
    • 랜덤한 니모닉 코드를 생성
    • 니모닉을 시드로 키스토어를 생성
    • 시드 값을 기반으로 파생된 주소 생성
  • fs 모듈을 이용한 키스토어 로컬 저장

 


프로젝트 구조

.
├── .gitignore
├── app.js
├── package.json
├── routes/
│   └── wallet.js
├── wallet.json   // fs모듈로 키스토어 로컬 저장시 생성되는 파일

 

API 명세 (Endpoint)

Method URI Request Body Response Description
GET / none status code: 200 서버 실행 정상 작동 확인
POST /wallet/newMnemonic none 니모닉 코드(json 형식) 니모닉 코드 생성
POST /wallet/newWallet - password
- 니모닉 코드
로컬 저장 성공 결과 코드
  - 1: 성공
  - 999: 실패
니모닉 코드를 시드로 한 키스토어와 주소 생성 후, 로컬에 키스토어 파일 저장

 


소스 코드

package.json : dependencies - 해당 프로젝트에 사용되는 라이브러리

{
  "name": "my-mnemonic-wallet",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "nodemon ./app.js"
  },
  "dependencies": {
    "cookie-parser": "~1.4.4",
    "cors": "^2.8.5",
    "debug": "~2.6.9",
    "eth-lightwallet": "^4.0.0",
    "express": "~4.16.1",
    "morgan": "~1.9.1"
  }
}

* package.json 파일이 있으면 한번에 필요한 라이브러리를 설치할 수 있다

    => 프로젝트 루트 위치에서 npm install 명령 입력

 

 

app.js : 웹 서버 생성

const express = require('express');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const cors = require('cors');

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

const app = express();
const port = 3000;

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(
  cors({
    origin: ['http://localhost:3000'],
    methods: ['GET', 'POST'],
    credentials: true,
  })
);

app.get('/', function (req, res, next) {
  res.status(200).send({ message: 'Mnemonic server is running...' });
});
app.use('/wallet', walletRouter);

// 404 Not Found 에러 핸들링
app.use((req, res, next) => {
  const err = new Error('Not Found');
  err['status'] = 404;
  next(err);
});

// 그 외의 에러 핸들링: 에러 코드를 메세지로 출력
app.use((err, req, res, next) => {
  res.status(err.status || 500);
  res.json({
    errors: {
      message: err.message,
    },
  });
});

app.listen(port, () => {
  console.log(`
  ################################################
  🛡️  Server listening on port: ${port} 🛡️
  http://localhost:${port}
  ################################################
  `);
});

module.exports = app;

 

 

routes/wallet.js : 지갑 생성과 관련 된 Router 모음

const express = require('express');
const router = express.Router();
const lightwallet = require('eth-lightwallet'); // TIP! github: https://github.com/ConsenSys/eth-lightwallet#readme
const fs = require('fs');

// 랜덤한 니모닉 코드 생성
router.post('/newMnemonic', async (req, res) => {
  let mnemonic;
  try {
    // generateRandomSeed(): Generates a string consisting of a random 12-word seed and returns it.
    mnemonic = lightwallet.keystore.generateRandomSeed();
    res.json({ mnemonic });
  } catch (err) {
    console.log(err);
  }
});

// 니모닉 코드와 패스워드를 이용해 keystore와 address 생성
router.post('/newWallet', async (req, res) => {
  let password = req.body.password;
  let mnemonic = req.body.mnemonic;

  try {
    // createVault(options, callback): the interface to create a new lightwallet keystore.
    lightwallet.keystore.createVault(
      {
        password: password,
        seedPhrase: mnemonic, //Optionally provide a 12-word seed phrase
        hdPathString: "m/0'/0'/0'", // Optional custom HD Path String; default:"m/0'/0'/0'"
      },
      function (err, ks) {
        // Some methods will require providing the `pwDerivedKey`,
        // Allowing you to only decrypt private keys on an as-needed basis.
        // You can generate that value with this convenient method:
        ks.keyFromPassword(password, function (err, pwDerivedKey) {
          // generateNewAddress(pwDerivedKey, [num]): default of num = 1
          // generate 'num' new address/private key pairs
          // the corresponding private keys are also encrypted
          ks.generateNewAddress(pwDerivedKey, 1);
          // getAddresses(): Returns a list of hex-string addresses currently stored in the keystore.
          let address = ks.getAddresses().toString();
          // serialize(): Serializes the current keystore object into a JSON-encoded string and returns that string.
          let keystore = ks.serialize();

          fs.writeFile('wallet.json', keystore, function (err, data) {
            if (err) {
              res.json({ code: 999, message: '실패' });
            } else {
              res.json({ code: 1, message: '성공' });
            }
          });
        });
      }
    );
  } catch (exception) {
    console.log('NewWallet ==>>>> ' + exception);
  }
});

module.exports = router;

lightWallet 모듈의 내장함수 각각에 대한 설명은 주석으로 달아놨다. 

주석의 내용은 오역이 있을 수도 있으니 lightWallet 모듈의 공식 깃허브에 적힌 원어설명을 그대로 적었다.

더 자세한 설명이 필요하다거나 다른 내장함수를 확인하고 싶다면 여기 Readme 에서 확인할 수 있다.

 

 


 

API 테스트 결과

1. 니모닉 코드 생성

    -> 니모닉 코드인 12개의 영단어가 잘 담긴 것을 확인할 수 있다.

 

 

2. 니모닉 코드를 시드로 한 키스토어와 주소 생성

  2-1. 키스토어와 주소를 json 형식으로 응답해줄 때

 res.json({ keystore: keystore, address: address });

 

  2-2. 키스토어 정보 객체를 로컬 파일에 저장하고 성공 여부만을 json으로 응답해줄 때

 

 

 


회고

 니모닉 지갑은 실습 주제 중에 공부한지 가장 오래된 주제였는데, 한번 더 복습하니까 머릿속에 내용이 더 잘 들어오는 것 같았다.

니모닉의 개념, 니모닉 지갑의 쓰임, 그리고 니모닉 지갑이 생성되는 과정에 대한 이해는 했지만, 모듈없이 니모닉 지갑을 생성하는 법은 아직 어려운 것 같다. lightwallet 모듈은 어떤 코드로 작성되어있는지 좀 더 들여다보고 깊게 공부해봐도 좋겠다는 생각이 들었다.

 

 

 

소스코드: https://github.com/Ahreum0714/My-Mnemonic-Wallet/tree/main

 

GitHub - Ahreum0714/My-Mnemonic-Wallet: eth-lightwallet 모듈을 이용한 간단한 니모닉 지갑

eth-lightwallet 모듈을 이용한 간단한 니모닉 지갑. Contribute to Ahreum0714/My-Mnemonic-Wallet development by creating an account on GitHub.

github.com

 

저작자표시 비영리 변경금지 (새창열림)

'Blockchain' 카테고리의 다른 글

[Project#1] DID를 활용한 백신 증명 시스템  (0) 2022.06.10
Error: invalid argument 0: json: cannot unmarshal hex string without 0x prefix into Go struct field TransactionArgs.data of type hexutil.Bytes  (0) 2022.05.23
[실습] 자바스크립트로 간단한 니모닉 지갑 (Mnemonic Wallet) 개발하기  (0) 2022.05.18
블록체인 심화 (4) - 합의 알고리즘 PoW, PoS, DPoS, BFT, PBFT  (0) 2022.05.13
블록체인 심화 (3) - 비트코인과 이더리움의 트랜잭션 데이터 구조 차이  (0) 2022.05.12
    'Blockchain' 카테고리의 다른 글
    • [Project#1] DID를 활용한 백신 증명 시스템
    • Error: invalid argument 0: json: cannot unmarshal hex string without 0x prefix into Go struct field TransactionArgs.data of type hexutil.Bytes
    • [실습] 자바스크립트로 간단한 니모닉 지갑 (Mnemonic Wallet) 개발하기
    • 블록체인 심화 (4) - 합의 알고리즘 PoW, PoS, DPoS, BFT, PBFT
    월하점
    월하점
    개발 공부를 기록합니다. 웹을 위주로 공부하며 컴퓨터과학 이론도 함께 정리할 계획입니다.

    티스토리툴바