๋ '๋๋ชจ๋'ํ ๋๋ง๋ค ์ด ๋๋ชจ๋ฐ์ ์๊ฐ์ด ์ ๋,,๐
: ์ง๊ฐ์ ๋ณต๊ตฌํ๊ธฐ ์ํ ์ผ๋ฐ์ ์ธ ๋จ์ด๋ค์ ์กฐํฉ
Mnemonic์ด ํ์ํ ์ด์
์ํธํํ ์ง๊ฐ: ๋น๋์นญ ํค ์ํธ ๋ฐฉ์ -> ๊ณต๊ฐํค์ ๋น๋ฐํค ์ฌ์ฉ
์ด ๋, ๋น๋ฐ ํค๋ฅผ ์ฌ๋์ด ์ฐ๊ธฐ ํธํ๊ฒ ๋ง๋ ๊ฒ์ด ๋ฐ๋ก ๋๋ชจ๋
๋๋ชจ๋์ ๋๋คํ ์์ด ๋จ์ด๋ก ์ด๋ฃจ์ด์ ธ ์์ด
์ํธํํ ์ง๊ฐ ์ฌ์ฉ์๊ฐ ํน๋ณํ ๊ธฐ์ ์ดํด๋๊ฐ ์์ด๋ ํธ๋ฆฌํ๊ฒ ์ด์ฉํ ์ ์์
Mnemonic Wallet
โ ์ฌ์ค ์ํธํํ ์ง๊ฐ์๋ ๋์ด ๋ค์ด์์ง ์๋คโ
โ ์ํธํํ ์ง๊ฐ: Key Management Systemโ
eg. ๋ด ๊ณ์ ์ ์๋ ์ด๋๋ฆฌ์์ ๋ด ๊ฒ์ด๋ผ๊ณ ์ฆ๋ช ํ ์ ์๋ ๋น๋ฐ ํค ๊ด๋ฆฌ
Meemonic Wallet์ ๋น๋ฐํค๋ฅผ ์์ด๋ฒ๋ ธ์ ๋ ๋น๋ฐ ํค ๋ณต๊ตฌ๋ฅผ ์ํด ๋๋ชจ๋ ์ฌ์ฉ
Mnemonic Code
๋๋ชจ๋ ์ฝ๋๋ BIP-39์ ์ ์๋์ด ์์
๋๋ชจ๋ ์ฝ๋๋ ํด์ ํจ์๋ฅผ ์ฌ๊ท์ ์ผ๋ก ๋ฐ๋ณตํ๋ ํค ์คํธ๋ ์นญ ๊ณผ์ ์ ๊ฑฐ์ณ ์๋ ์์ฑ
๋ง์คํฐ ์๋๋ HD ์ง๊ฐ ์ฃผ์ ์์ฑ์ ๋ฐํ์ด ๋จ
์ฐ๋ฆฌ ๋ชจ๋ ์คํธ๋ ์นญํฉ์๋น
HD Wallet
: Hierarchical Deterministic Wallet ๊ณ์ธต์ ๊ฒฐ์ ์ ์ง๊ฐ
: ํ๋์ ์๋ ๊ฐ๋ง ๊ฐ์ง๊ณ ์์ผ๋ฉด ์ฌ๋ฌ ๊ฐ์ ์ฃผ์๋ฅผ ์ฝ๊ฒ ์์ฑํ ์ ์๋ ์ง๊ฐ
-> ์ฌ๋ฌ ๊ฐ์ ํค๋ฅผ ํ๋๋ก ๊ด๋ฆฌํ ์ ์์ด, ๋ค๋ชฉ์ ๊ด๋ฆฌ์ ์ฉ์ด
-> HD Wallet๋ BIP-32์์ ์ ์ ๋ฐ BIP-44์์ ๊ฐ์ ๋์์
HardWare๋ผ๊ณ ์๊ฐํ ์ฌ๋ ๋์
HD Wallet ๊ณ์ ์์ฑ ์ฃผ์ ๊ฐ๋
: HD Wallet์ผ๋ก ๊ณ์ ์ ๋ง๋ค๊ธฐ ์ํด์๋ ํฌ๊ฒ ๋ ๊ฐ์ง ํ์
1. ์ ์๋ก ๋ seed
2. ๊ทธ ๊ณ์ ๊น์ง์ path
-> seed์ path๋ก ํญ์ ๋์ผํ ๊ฐ์ ์์ํค๋ฅผ ๊ตฌํ ์ ์์
HD wallet์ ๊ฒฝ๋ก๋ ์ฌ๋ฌ ๊ฐ์ ์ ์๋ก ๊ตฌ์ฑ๋๋ฉฐ, ๊ฐ์ ์ ํ ์์
seed
: HD wallet์ ์๋๋ก๋ถํฐ ๋ง์คํฐํค ์์ฑ
: HD Wallet์ ๋ชจ๋ ํค๋ ๋ฃจํธ ์๋์์ ํ์
: ์์ฑ๋ ์๋๋ก๋ถํฐ ์์ HD Wallet ์ฌ์์ฑ ๊ฐ๋ฅ
path
: ๊ฐ ํธ๋ฆฌ ๋ ๋ฒจ์ ์ฌ๋์(/)๋ก ๊ตฌ๋ถ
: ๋ง์คํฐ ๋น๋ฐํค์์ ํ์๋ ๋น๋ฐํค๋ m์ผ๋ก ์์
: ๋ง์คํฐ ๊ณต๊ฐํค์์ ํ์๋ ๊ณต๊ฐํค๋ M์ผ๋ก ์์
m/0: ๋ง์คํฐ ๋น๋ฐํค์ ์ฒซ ๋ฒ์งธ ์์ ๋น๋ฐ ํค
m/0/1: ๋ง์คํฐ ๋น๋ฐํค์ ์ฒซ ๋ฒ์งธ ์์์ ๋ ๋ฒ์งธ ์์ ๋น๋ฐํค(๋ง์คํฐ ํค์ ์์ ๋น๋ฐํค)
eth.ligthwallet ๋ชจ๋
https://github.com/ConsenSys/eth-lightwallet#readme
keystore.generateRandomSeed([extraEntropy])
: ์์์ 12๋จ์ด ์๋๋ก ๊ตฌ์ฑ๋ ๋ฌธ์์ด ์์ฑ ๋ฐ ๋ฐํ
[extraEntropy]: JS RNG์ ์์ ๋ฐ์ดํฐ์ ์ฐ๊ฒฐ ๋ฐ ํด์ -> ์ต์ข
์๋ ์์ฑ
keystore.createVault(options, callback)
: ์๋ก์ด ligthWallet keystore ์์ฑ
keystore.keyFromPassword(password, callback)
: ์ํธ๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ ํ pwDerivedKey ๋ฐํ
keystore.generateNewAddress(pwDerivedKey, [num])
: ์๋ก์ด ์ฃผ์ ์์ฑ
keystore.serialize()
: ํ์ฌ ํค ์ ์ฅ์ ๊ฐ์ฒด๋ฅผ JSON ์ธ์ฝ๋ฉ ๋ฌธ์์ด๋ก ์ง๋ ฌํํ๊ณ ํด๋น ๋ฌธ์์ด ๋ฐํ
// get random Mnemonic code
router.post("/newMnemonic", async (req, res) => {
const mnemonic = lightwallet.keystore.generateRandomSeed();
console.log(mnemonic);
res.send(mnemonic);
});
// generate keystore and address
router.post("/newWallet", async (req, res) => {
const password = req.body.password;
const mnemonic = req.body.mnemonic;
lightwallet.keystore.createVault(
{
password: password,
seedPhrase: mnemonic,
hdPathString: "m/0'/0'/0'",
},
function (err, ks) {
if (err) throw err;
ks.keyFromPassword(password, function (err, pwDerivedKey) {
if (err) throw err;
ks.generateNewAddress(pwDerivedKey, 1);
const addr = ks.getAddresses();
const keystore = ks.serialize();
console.log(addr);
console.log(keystore);
fs.writeFile("wallet.json", keystore, function (err, result) {
if (err) {
res.send({ message: "Fault" });
} else {
res.send({
message: "Success. Check your 'wallet.json'",
});
}
});
});
}
);
});
POST
http://localhost:3000/wallet/newMnemonic
result: purpose boil drama cart captain scorpion enact frequent pluck once emerge federal
POST
http://localhost:3000/wallet/newWallet
mnemonic: newMnemonic์์ ๋ฐ์ mnemoic
password: ์์์ ์ซ์ ์
๋ ฅ
result: {"message": "Success. Check your 'wallet.json'"}
โ wallet.json์ ํ์ธํด ๋ณด๋ฉด keystore๊ฐ ๋ค์ด์๋คโ
https://github.com/mjlee0326/MnemonicWallet
git repo๋ ํ ๋ฒ ์น ์ ๋ฆฌํด์ผ ํ๋๋ฐ,,,
์ง๊ธ๊น์ง ๋ธ๋ก๊น
์ ์ ๋๋ก ํด ๋ณธ ์ ์ด ์๋๋ฐ(์ง๊ธ๊น์ง ๋ ์์ดํจ๋์ ์ ์ฅ)
์ ๋ค๋ค ๊ธฐ์ ๋ธ๋ก๊ทธ๋ฅผ ์ฐ๋์ง ์ ๊ฒ ๊ฐ๋ค :)
๋ ์ ๋ฆฌ๊ฐ ์ ๋๊ณ ๋จธ๋ฆฟ์์ ๋ค์ด์ค๋ ๊ธฐ๋ถ
๋จ์๊ฒ ์ค๋ช
ํ๋ ค๊ณ ํ๋ ๋ ํผ๋ฐ์ค๋ฅผ ๋ ์ฐพ์๋ณด๊ฒ ๋๋ฉด์ ๋ ๊ณต๋ถ๊ฐ ๋๋ค
๋ฌผ๋ก ๊ทธ๋งํผ ๋ ์ค๋ ๊ฑธ๋ฆผ
์ด์ '๋๋ชจ๋'์ด๋ผ๋ ๋จ์ด๋ฅผ ๋ค์ด๋
'๋๋ชจ๋ฅผ ์ฐพ์์'์ ๋๋ชจ๊ฐ ์๋ Mnemonic์ด ์๊ฐ๋ ๊ฒ ๊ฐ๋ค ใ
๐ ๐