eth-lightwallet 모듈
을 이용하여 간단한 Mnemonic Wallet을 개발하고, Postman을 사용하여 API 테스트를 진행하려고 합니다.
eth-lightwallet 모듈
에 내장되어 있는 함수를 사용하여 개발Postman
을 사용하여 결과 확인fs 모듈
을 이용한 키스토어 로컬 저장 "dependencies": {
"cookie-parser": "^1.4.6", // 요청된 쿠키를 쉽게 추출할 수 있도록 도와주는 미들웨어
"cors": "^2.8.5", // API를 차단하는 문제해결 미들웨어
"debug": "^4.3.4",
"eth-lightwallet": "^4.0.0", // 지갑을 만들 때 필요한 모듈
"express": "^4.18.1",
"morgan": "^1.10.0"
}
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;
1. mnemonic 변수를 만듭니다.
2. 응답 > mnemonic 변수에 lightwallet.keystore.generateRandomSeed()을 담아, mnemonic을 응답으로 전송합니다. 하단에 generateRandomSeed() 기능 작성.
3. 에러 > 에러를 응답합니다.
keystore.generateRandomSeed([extraEntropy])
Generates a string consisting of a random 12-word seed and returns it. If the optional argument string extraEntropy is present the random data from the Javascript RNG will be concatenated with extraEntropy and then hashed to produce the final seed. The string extraEntropy can be something like entropy from mouse movements or keyboard presses, or a string representing dice throws.
wallet.js
const express = require("express");
const router = express.Router();
const lightwallet = require("eth-lightwallet");
const fs = require("fs");
router.post("/newMnemonic", async (req, res) => {
let mnemonic;
try {
mnemonic = lightwallet.keystore.generateRandomSeed();
res.send({ mnemonic });
} catch (err) {
console.log(err);
}
});
sever를 실행시킨 다음 Postman에 http://localhost:3000/wallet/newMnemonic 엔드포인트를 입력, POST method를 선택 후 send
1. password 와 mnemonic 을 입력값으로, 서버에 요청을 보냅니다.
2. (응답) lightwallet.keystore.createVault를 사용하여 키스토어를 생성합니다.
3. (오류) 에러를 응답합니다.
wallet.js
router.post('/newWallet', async(req, res) => {
// password 와 mnemonic 변수를 만듭니다.
let password = req.body.password
let mnemonic = req.body.mnemonic;
// 요청에 포함되어 있는 password 와 mnemonic을 각 변수에 할당합니다.
try {
lightwallet.keystore.createVault(
{
// 첫번째 인자(options)에는 password, seedPhrase, hdPathString을 담습니다.
password: password,
seedPhrase: mnemonic,
hdPathString: "m/0'/0'/0'"
},
function (err, ks) {
// 두번째 인자(callback)에는 키스토어를 인자로 사용하는 함수를 만듭니다.
ks.keyFromPassword(password, function (err, pwDerivedKey) {
// 첫번째 인자에는 password, 두번째 인자(callback)에는 pwDerivedKey를 인자로 사용하는 함수를 만듭니다.
ks.generateNewAddress(pwDerivedKey, 1);
// 새로운 주소 생성 함수
let address = (ks.getAddresses()).toString();
let keystore = ks.serialize();
// keystore.getAddresses()을 문자열로 할당합니다.
// keystore.serialize()을 할당합니다.
res.json({ keystore: keystore, address: address });
// 위에서 만들어준 변수를 응답으로 전송합니다.
});
}
);
} catch (exception) {
console.log("NewWallet ==>>>> " + exception);
}
});
keystore.keyFromPassword(password, callback)
This instance method uses any internally-configured salt to return the appropriatepwDerivedKey
.
Takes the user's password as input and generates a symmetric key of typeUint8Array
that is used to encrypt/decrypt the keystore.
keystore.generateNewAddress(pwDerivedKey, [num])
Allows the vault to generate additional internal address/private key pairs.
The simplest usage isks.generateNewAddress(pwDerivedKey)
.
Generates num new address/private key pairs (defaults to 1) in the keystore from the seed phrase, which will be returned with calls toks.getAddresses()
.
keystore.serialize()
Serializes the current keystore object into aJSON-encoded
string and returns that string.
keystore.getAddresses()
Returns a list of hex-string addresses currently stored in the keystore.
http://localhost:3000/wallet/newWallet 앤드포인트를 작성 후 body input에 아까 얻은 니모닉 코드를 mnemonic이라는 키의 값으로, password에는 원하는 비밀번호를 입력 후 send 버튼을 누릅니다.
1. wallet.js 파일에 fs 모듈을 import 합니다. (fs 모듈은 Node.js 내장 모듈입니다.)
2. 함수 keyFromPassword의 콜백 함수에서, 응답대신 fs.writeFile 또는 fs.writeFileSync 를 사용합니다.
wallet.js
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){
// 첫번째 인자에는 .json 형식의 파일이름을, 두번째 인자에는 keystore 을 입력합니다. 세번째 인자에는 응답에 대한 콜백 함수를 입력합니다.
if(err) {
// 로컬 서버에 파일을 저장하기 때문에, 응답으로는 성공 또는 실패 메세지만 전송합니다.
res.json({code:999,message:"실패"});
} else {
res.json({code:1,message:"성공"});
}
});
});
}
);
} catch (exception) {
console.log("NewWallet ==>>>> " + exception);
}
});
로컬 서버의 경로에 파일이 생기는지 확인합니다.
keystore file(wallet.json)이 생성된 것을 확인할 수 있다.
eth-lightwallet
의 다른 내장 함수도 사용해보자.