니모닉 지갑에 대한 개념은 따로 포스팅하겠다
* 니모닉 지갑에 대해 알아보기 *
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": "beb-sprint-hdwallet",
"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"
}
}
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);
// catch 404 and forward to error handler
app.use((req, res, next) => {
const err = new Error('Not Found');
err['status'] = 404;
next(err);
});
// error handler
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');
// TODO : lightwallet 모듈을 사용하여 랜덤한 니모닉 코드를 얻습니다.
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);
}
});
// TODO : 니모닉 코드와 패스워드를 이용해 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 모듈의 내장함수 각각에 대한 설명은 주석으로 달아놨다.
더 자세한 설명이 필요하다거나 다른 내장함수를 확인하고 싶다면 여기 Readme 에서 확인할 수 있다.
API 테스트 결과
1. 니모닉 코드 생성
-> 니모닉 코드인 12개의 영단어가 잘 담긴 것을 확인할 수 있다.
2. 니모닉 코드를 시드로 한 키스토어와 주소 생성
2-1. 키스토어와 주소를 json 형식으로 응답해줄 때
res.json({ keystore: keystore, address: address });
2-2. 키스토어 정보 객체를 로컬 파일에 저장하고 성공 여부만을 json으로 응답해줄 때
'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 |
블록체인 심화 (4) - 합의 알고리즘 PoW, PoS, DPoS, BFT, PBFT (0) | 2022.05.13 |
블록체인 심화 (3) - 비트코인과 이더리움의 트랜잭션 데이터 구조 차이 (0) | 2022.05.12 |
블록체인 심화 (2) - 분산원장기술 vs. 중앙집중원장 (0) | 2022.05.12 |