니모닉(Mnemonic)

블록체인에서 니모닉(Mnemonic)은 지갑을 복구하기 위한 일반적인 단어들의 조합을 뜻합니다.

사전적 의미로는 정보의 기억을 위한 기억술입니다.

숫자의 나열처럼 직관적인 관계가 없어 외우기 어려운 정보에 다른 정보를 연결하여

외우기 쉽도록 하는 데 쓰입니다.

(니모닉에 대한 설명은 블로그 Blockchain 글 Section 4-1 (https://koartifact.tistory.com/8) 에 블로깅 하였습니다.)

 

Mnemonic Wallet 개발하기

진행 내용은 eth-lightwallet 모듈을 이용하여 간단한 Mnemonic Wallet을 개발하고,

Postman을 사용하여 API 테스트를 하는 것 입니다.

 

  • 랜덤한 니모닉 코드를 생성
  • 니모닉을 시드로 키스토어를 생성
  • Postman을 사용하여 결과 확인
  • fs 모듈을 이용한 키스토어 로컬 저장

 

1)  먼저 API 테스트를 위한 Postman을 설치 합니다.

https://nhj12311.tistory.com/393

 

포스트맨(postman) 사용법(설치, 다운로드)

전부터 웹 개발을 하면서 아주 유용하게 사용했던 프로그램(서비스)가 있어 소개해보려고 합니다. 바로 포스트맨(postman)입니다. 쉽게 말하자면 http(https 포함) 요청을 날리고 응답을 보여주는 서

nhj12311.tistory.com

 

2) MnemonicMini 폴더를 만들고(폴더명은 마음대로) 비쥬얼 스튜디오 코드에서 작업을 시작합니다.

 

(1) 해당 깃허브 내용을 다운 받는다.

https://github.com/Koartifact/mnemonic_wallet

 

GitHub - Koartifact/mnemonic_wallet

Contribute to Koartifact/mnemonic_wallet development by creating an account on GitHub.

github.com

  수업내용에서의 소스코드를 사용하였습니다.

  아래 설명 이외의 부분은 꼭 살펴 보도록 합니다.

  포트 설정, 페이지 구조 등 작성되어있는 부분이 좀 더 발전된 프로젝트로 이어질 것이란 플레그 같습니다(?)

 

(2) package.json에 내용이 아래와 같은 지 확인한다.

{

  "name": "폴더 이름",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },            
  "dependencies": {
    "cookie-parser": "~1.4.4",
    "cors": "^2.8.5",
    "debug": "~2.6.9",
    "eth-lightwallet": "^4.0.0",
    "express": "~4.16.1",
    "http-errors": "~1.6.3",
    "morgan": "~1.9.1",
    "pug": "2.0.0-beta11"
  }
}

(3) npm i 명령어를 이용하여 express,  eth-lightwallet, nodemon 등의 모듈을 설치한다.

    ->  ' npm i ' 한번 타이핑 해줍니다.

 

(4) wallet/index.js 파일에서 작업 

mnemonic변수를 만들고 변수에 lightwallet.keystore.generateRandomSeed()을 담아서 mnemonic을 응답한다.

두개 TODO 중 위의 첫번째 TODO에 아래 코드 작성 (제공한 깃헙 소스에는 작성이 다되어 있습니다.)

 

Reference code

더보기
router.post('/newMnemonic', async(req,res) => {
  let mnemonic;
  try {
      mnemonic = lightwallet.keystore.generateRandomSeed();
      res.json({mnemonic});
  } catch(err) {
      console.log(err);
  }
});

 

 

 

3) Postman으로 테스트하여 니모닉코드 얻기

 

로컬 서버를 실행  ' npm run start '

- console에 나오는 로컬주소를 Postman에 입력

- Postman에서 정확한 method와 end point를 입력하고, send를 누른다.

- Request 니모닉 코드를 확인

 

 

4) mnemonic code와 password를 이용해 newWallet API 만들기

 

요청에 포함되어 있는 password 와 mnemonic을 각 변수에 할당한다

 

(request) lightwallet.keystore.createVault를 사용하여 키스토어를 생성한다.

  • 첫번째 인자(options)에는 password, seedPhrase, hdPathString을 담는다.
  • 두번째 인자(callback)에는 키스토어를 인자로 사용하는 함수를 만든다.
    • eth-lightwallet 모듈의keystore.keyFromPassword(password, callback) 내장 함수 사용
      • 첫번째 인자에는 password,
      • 두번째 인자(callback)에는 pwDerivedKey를 인자로 사용하는 함수를 만든다.
        • 두번째 콜백함수가 실행되면, eth-lightwallet 모듈의 keystore.generateNewAddress(pwDerivedKey, [num])을 이용해 새로운 주소 생성 함수가 실행
        • address 변수를 만들어, keystore.getAddresses()을 문자열로 할당
        • keystore 변수를 만들어, keystore.serialize()을 할당
        • 위에서 만들어준 변수를 응답으로 보내준다.

Reference code

더보기
router.post('/newWallet', async(req, res) => {
    let password = req.body.password
    let mnemonic = req.body.mnemonic;

    try {
      lightwallet.keystore.createVault(
        {
          password: password, 
          seedPhrase: mnemonic,
          hdPathString: "m/0'/0'/0'"
        },
        function (err, ks) {
          ks.keyFromPassword(password, function (err, pwDerivedKey) {
            ks.generateNewAddress(pwDerivedKey, 1);
            
            let address = (ks.getAddresses()).toString();
            let keystore = ks.serialize();

            res.json({ keystore: keystore, address: address });
          });
        }
      );
    } catch (exception) { 
      console.log("NewWallet ==>>>> " + exception);
    }
});

 

5) Postman을 이용해 keystore와 address가 잘 응답 받는지 API 테스트 해보기

   

  로컬 서버를 실행 ctrl + c 로 서버 정지 후 재실행 --> 'npm run start'

 

  console에 나오는 로컬주소를 Postman에 입력한다.

  Postman에서 정확한 method와 end point를 입력한다.

  3)에서 나온 니모닉 코드를 mnemonic이라는 키의 값으로, password에는 임의의 숫자를 입력 후 send

 

6) 생성된 keystore를 json형태의 파일로 만들어 로컬 서버에 저장하기

 

fs모듈을 wallet/index.js 파일에 import 시킨다.

4)에 응답을 주는 keyFromPassword의 콜백 함수에서 응답대신 fs.writeFile로 변경한다.

  • 첫번째 인자에는 .json 형식의 파일이름
  • 두번째 인자에는 keystore
  • 세번째 인자에는 응답에 대한 콜백 함수를 만들어준다.
    • 로컬 서버에 저장되기에 응답으로는 성공 & 실패 메세지만 준다

즉, 위에 작성한 소스코드를 밑의 소스코드로 변경

 

Reference code

더보기
router.post('/newWallet', async(req, res) => {
    let password = req.body.password
    let mnemonic = req.body.mnemonic;

    try {
        lightwallet.keystore.createVault({
                password: password, 
                seedPhrase: mnemonic,
                hdPathString: "m/0'/0'/0'"
            },
            function (err, ks) {
                ks.keyFromPassword(password, function (err, pwDerivedKey) {
                    ks.generateNewAddress(pwDerivedKey, 1);

                    let address = (ks.getAddresses()).toString();
                    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);
    }
});

 

7)  Postman을 실행하여, 로컬에 키스토어 파일이 생기는지 확인하기

 

5번 과 같이 실행 후 로컬 서버 파일이 생기는지 확인

 

작업 동영상으로 한번에 보기 

https://youtu.be/u_p13A1F5EE

 

- 회고

Keep

기존 학습 내용을 블로깅하면서 정리할 수 있는 시간이 된 것 같다.

 

Problem

단순히 니모닉을 생성하여 키스토어를 로컬에 저장하는 것 만을 작업해보았다.

 

Try

앞으로 eth-lightwallet 모듈사용법을 더 숙지하고 section4 에서 배운 몇가지 기술들을

더 추가할 수 있다면 또한 초반 수업에서 배운 '리액트'까지 잘 사용 할 수 있다면

'웹 지갑' 사이트도 만들 수 있을 거란 생각을 해본다.

 

(물론 꽤나 어렵게지만;....)

+ Recent posts