๐Ÿ Mnemonic Wallet ๊ฐœ๋ฐœ๐Ÿ 

์ด๋ฏผ์ •ยท2021๋…„ 12์›” 13์ผ
1

blockChain

๋ชฉ๋ก ๋ณด๊ธฐ
2/10


๋‚œ '๋‹ˆ๋ชจ๋‹‰'ํ•  ๋•Œ๋งˆ๋‹ค ์ด ๋‹ˆ๋ชจ๋ฐ–์— ์ƒ๊ฐ์ด ์•ˆ ๋‚˜,,๐Ÿ™„

๊ฐœ๋… ์„ค๋ช…

Mnemonic

: ์ง€๊ฐ‘์„ ๋ณต๊ตฌํ•˜๊ธฐ ์œ„ํ•œ ์ผ๋ฐ˜์ ์ธ ๋‹จ์–ด๋“ค์˜ ์กฐํ•ฉ

Mnemonic์ด ํ•„์š”ํ•œ ์ด์œ 

์•”ํ˜ธํ™”ํ ์ง€๊ฐ‘: ๋น„๋Œ€์นญ ํ‚ค ์•”ํ˜ธ ๋ฐฉ์‹ -> ๊ณต๊ฐœํ‚ค์™€ ๋น„๋ฐ€ํ‚ค ์‚ฌ์šฉ
์ด ๋•Œ, ๋น„๋ฐ€ ํ‚ค๋ฅผ ์‚ฌ๋žŒ์ด ์“ฐ๊ธฐ ํŽธํ•˜๊ฒŒ ๋งŒ๋“  ๊ฒƒ์ด ๋ฐ”๋กœ ๋‹ˆ๋ชจ๋‹‰

๋‹ˆ๋ชจ๋‹‰์€ ๋žœ๋คํ•œ ์˜์–ด ๋‹จ์–ด๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์–ด
์•”ํ˜ธํ™”ํ ์ง€๊ฐ‘ ์‚ฌ์šฉ์ž๊ฐ€ ํŠน๋ณ„ํ•œ ๊ธฐ์ˆ  ์ดํ•ด๋„๊ฐ€ ์—†์–ด๋„ ํŽธ๋ฆฌํ•˜๊ฒŒ ์ด์šฉํ•  ์ˆ˜ ์žˆ์Œ

Mnemonic Wallet

โœ… ์‚ฌ์‹ค ์•”ํ˜ธํ™”ํ ์ง€๊ฐ‘์—๋Š” ๋ˆ์ด ๋“ค์–ด์žˆ์ง€ ์•Š๋‹คโœ…
โœ… ์•”ํ˜ธํ™”ํ ์ง€๊ฐ‘: Key Management Systemโœ…
eg. ๋‚ด ๊ณ„์ •์— ์žˆ๋Š” ์ด๋”๋ฆฌ์›€์„ ๋‚ด ๊ฒƒ์ด๋ผ๊ณ  ์ฆ๋ช…ํ•  ์ˆ˜ ์žˆ๋Š” ๋น„๋ฐ€ ํ‚ค ๊ด€๋ฆฌ
Meemonic Wallet์€ ๋น„๋ฐ€ํ‚ค๋ฅผ ์žƒ์–ด๋ฒ„๋ ธ์„ ๋•Œ ๋น„๋ฐ€ ํ‚ค ๋ณต๊ตฌ๋ฅผ ์œ„ํ•ด ๋‹ˆ๋ชจ๋‹‰ ์‚ฌ์šฉ

Mnemonic Code

๋‹ˆ๋ชจ๋‹‰ ์ฝ”๋“œ๋Š” BIP-39์— ์ •์˜๋˜์–ด ์žˆ์Œ
๋‹ˆ๋ชจ๋‹‰ ์ฝ”๋“œ๋Š” ํ•ด์‹œ ํ•จ์ˆ˜๋ฅผ ์žฌ๊ท€์ ์œผ๋กœ ๋ฐ˜๋ณตํ•˜๋Š” ํ‚ค ์ŠคํŠธ๋ ˆ์นญ ๊ณผ์ •์„ ๊ฑฐ์ณ ์‹œ๋“œ ์ƒ์„ฑ
๋งˆ์Šคํ„ฐ ์‹œ๋“œ๋Š” HD ์ง€๊ฐ‘ ์ฃผ์†Œ ์ƒ์„ฑ์˜ ๋ฐ”ํƒ•์ด ๋จ

์šฐ๋ฆฌ ๋ชจ๋‘ ์ŠคํŠธ๋ ˆ์นญํ•ฉ์‹œ๋‹น

Mnemonic code์™€ ์‹œ๋“œ ์ƒ์„ฑ 9๋‹จ๊ณ„


HD Wallet

: Hierarchical Deterministic Wallet ๊ณ„์ธต์  ๊ฒฐ์ •์  ์ง€๊ฐ‘
: ํ•˜๋‚˜์˜ ์‹œ๋“œ ๊ฐ’๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ฃผ์†Œ๋ฅผ ์‰ฝ๊ฒŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์ง€๊ฐ‘
-> ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ‚ค๋ฅผ ํ•˜๋‚˜๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด, ๋‹ค๋ชฉ์  ๊ด€๋ฆฌ์— ์šฉ์ด
-> HD Wallet๋Š” BIP-32์—์„œ ์ œ์•ˆ ๋ฐ BIP-44์—์„œ ๊ฐœ์„ ๋˜์—ˆ์Œ
HardWare๋ผ๊ณ  ์ƒ๊ฐํ•œ ์‚ฌ๋žŒ ๋‚˜์™€

HD Wallet ๊ตฌ์กฐ

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: ๋งˆ์Šคํ„ฐ ๋น„๋ฐ€ํ‚ค์˜ ์ฒซ ๋ฒˆ์งธ ์ž์‹์˜ ๋‘ ๋ฒˆ์งธ ์ž์‹ ๋น„๋ฐ€ํ‚ค(๋งˆ์Šคํ„ฐ ํ‚ค์˜ ์†์ž ๋น„๋ฐ€ํ‚ค)

Mnemonic Wallet ๊ฐœ๋ฐœ

  1. newMnemonic API
  2. newWallet API

eth.ligthwallet ๋ชจ๋“ˆ
https://github.com/ConsenSys/eth-lightwallet#readme

eth.lightwallet ์ฃผ์š” ํ•จ์ˆ˜

keystore.generateRandomSeed([extraEntropy])
: ์ž„์˜์˜ 12๋‹จ์–ด ์‹œ๋“œ๋กœ ๊ตฌ์„ฑ๋œ ๋ฌธ์ž์—ด ์ƒ์„ฑ ๋ฐ ๋ฐ˜ํ™˜
[extraEntropy]: JS RNG์˜ ์ž„์˜ ๋ฐ์ดํ„ฐ์™€ ์—ฐ๊ฒฐ ๋ฐ ํ•ด์‹œ -> ์ตœ์ข… ์‹œ๋“œ ์ƒ์„ฑ

keystore.createVault(options, callback)
: ์ƒˆ๋กœ์šด ligthWallet keystore ์ƒ์„ฑ

  • options
    (ํ•„์ˆ˜) password
    (ํ•„์ˆ˜) seedPhrase: ๊ณ„์ • ์ƒ์„ฑ์‹œ ํ•„์š”ํ•œ ๋‹ˆ๋ชจ๋‹‰
    (์„ ํƒ) salt: ๋ณผํŠธ ์•”ํ˜ธํ™” ๋ฐ ํ•ด๋…์— ์‚ฌ์šฉ
    (ํ•„์ˆ˜) hdPathString: HD ๊ฒฝ๋กœ ๋ฌธ์ž์—ด

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๊ฐ€ ๋“ค์–ด์žˆ๋‹คโœ…

Git

https://github.com/mjlee0326/MnemonicWallet
git repo๋„ ํ•œ ๋ฒˆ ์‹น ์ •๋ฆฌํ•ด์•ผ ํ•˜๋Š”๋ฐ,,,

ํšŒ๊ณ 

์ง€๊ธˆ๊นŒ์ง€ ๋ธ”๋กœ๊น…์„ ์ œ๋Œ€๋กœ ํ•ด ๋ณธ ์ ์ด ์—†๋Š”๋ฐ(์ง€๊ธˆ๊นŒ์ง€ ๋Š˜ ์•„์ดํŒจ๋“œ์— ์ €์žฅ)
์™œ ๋‹ค๋“ค ๊ธฐ์ˆ  ๋ธ”๋กœ๊ทธ๋ฅผ ์“ฐ๋Š”์ง€ ์•Œ ๊ฒƒ ๊ฐ™๋‹ค :)
๋” ์ •๋ฆฌ๊ฐ€ ์ž˜ ๋˜๊ณ  ๋จธ๋ฆฟ์†์— ๋“ค์–ด์˜ค๋Š” ๊ธฐ๋ถ„
๋‚จ์—๊ฒŒ ์„ค๋ช…ํ•˜๋ ค๊ณ  ํ•˜๋‹ˆ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋” ์ฐพ์•„๋ณด๊ฒŒ ๋˜๋ฉด์„œ ๋” ๊ณต๋ถ€๊ฐ€ ๋œ๋‹ค
๋ฌผ๋ก  ๊ทธ๋งŒํผ ๋” ์˜ค๋ž˜ ๊ฑธ๋ฆผ

์ด์ œ '๋‹ˆ๋ชจ๋‹‰'์ด๋ผ๋Š” ๋‹จ์–ด๋ฅผ ๋“ค์–ด๋„
'๋‹ˆ๋ชจ๋ฅผ ์ฐพ์•„์„œ'์˜ ๋‹ˆ๋ชจ๊ฐ€ ์•„๋‹Œ Mnemonic์ด ์ƒ๊ฐ๋‚  ๊ฒƒ ๊ฐ™๋‹ค ใ…Ž ๐Ÿ ๐Ÿ 

0๊ฐœ์˜ ๋Œ“๊ธ€