mnemonic wallet dev


シード


決定的な財布は、プライマリシードから階層化されて秘密鍵を生成する.したがって、財布の中のすべての鍵を覚える必要はなく、メインシードを覚えるだけで、すべてのサブ鍵を再生成し、財布全体を復元することができます.

ニモニックって何?


これは決定的な財布の中で数字を12個から24個の英語単語にコードした英語の単語の組み合わせです.数字と文字からなる乱順キーはユーザに記憶されにくいが,ニモニック号はユーザが記憶しやすく使用しやすい形で構成されている.

アニメーションコードの生成


  • 、128ビットまたは256ビット長の数字
  • を生成する.
    生成する
  • の番号をSHA-256にハッシュし、この値(シード鍵の長さ)/32からチェックサム
  • を分離する.
  • 1で作成する数字の後に2で作成したチェックサム
  • を加える.
  • のチェックサムを有する番号を11ビット長のセグメント
  • に分割する.
  • は、各11 bit値を事前定義単語リスト
  • にマッピングする.

    シードの作成


    BIP−39の基準に従って、主シードは、キー延伸プロセスによって生成される.
    キーストレッチとは、入力されたパスワードに対して、特定のハッシュ関数によって要約を再帰的に繰り返し生成することを意味する.
    BIP−39では、キー引張関数PBKDF 2が用いられる.
  • PBKDF 2関数にNIMONICコードとSoltを入力します.(この場合、ソルトは「mnemonic」に任意のパスワードを付加する)
  • PBKDF 2関数は入力したNINICコードとSoltを用いてHMAC-SHA 512により2048回ハッシュし、シードキーとなる512ビットの値を生成する.
  • かいはつ


    本プロジェクトでは,MetamacのNIMONIC生成情報をクローニングし,フロントエンドを作成し,NIMONICを用いてNIMONICを生成し,パスワードを用いてプライマリシードを作成できるサーバを開発した.
    ニモニックの財布を作る簡単なアプリです.

    Client


    MetamacのNIMONIC生成過程とそれによって主シードが発せられるのを見てクローン符号化で符号化した.
    反応器を用い,muiという素子ライブラリを用いて構成を簡素化した.
    muiは公式サイトに入ってから、使い方を親切に説明してくれたので使いやすいです.
    https://mui.com/

    構成部品



    ルータを通じて、APPのすべてのコンポーネントをSPAに設定し、エンドポイントに応じて変更します.
    さらに,appでアニメーションコード,パスワード,生成アドレスの状態を管理し,propsを必要なコンポーネントに渡す方法も用いた.

    1-1. APP.jsx

    import React, { useState } from "react";
    import { Box, Stack } from "@mui/material";
    import { Route, Switch } from "react-router-dom";
    import CreatePw from "./pages/CreatePw";
    import Main from "./pages/Main";
    import MakeWallet from "./pages/MakeWallet";
    import Mnemonic from "./pages/Mnemonic";
    import NewWallet from "./pages/NewWallet";
    import ValiMnemonic from "./pages/ValiMnemonic";
    import KeyIcon from "@mui/icons-material/Key";
    
    function App() {
      const [password, setPassword] = useState("");
      const [mnemonic, setMnemonic] = useState({});
      const [address, setAddress] = useState("");
    
      const updateMnemonic = (mnemo) => {
        setMnemonic(mnemo);
      };
    
      const updatePw = (pw) => {
        setPassword(pw);
      };
    
      const updateAddress = (add) => {
        setAddress(add);
      };
    
      return (
        <Switch>
          <Route exact path="/">
            <Main />
          </Route>
    
          <Stack sx={{ height: "100vh" }}>
            <Stack sx={{ height: 40 }}>
              <Box sx={{ fontSize: 40 }}>
                <KeyIcon color="primary" sx={{ margin: 1 }} />
                BEBMASK
              </Box>
            </Stack>
            <Stack sx={{ flexGrow: 1 }}>
              <Route path="/makewallet">
                <MakeWallet updateMnemonic={updateMnemonic} />
              </Route>
              <Route path="/mnemonic">
                <Mnemonic mnemonic={mnemonic} />
              </Route>
              <Route path="/createpw">
                <CreatePw updatePw={updatePw} password={password} />
              </Route>
              <Route path="/valimnemonic">
                <ValiMnemonic
                  mnemonic={mnemonic}
                  password={password}
                  updateAddress={updateAddress}
                />
              </Route>
              <Route path="/newwallet">
                <NewWallet address={address} />
              </Route>
            </Stack>
          </Stack>
        </Switch>
      );
    }
    
    export default App;

    GIF説明


    この開発の主な内容は反応ではないので,コードよりもGIFで実施内容を説明することが望ましい.

    最初のページに入ると「スタート」ボタンが表示され、ボタンを押すと新しいウォレットか「アニメーション」でウォレットをインポートするかを尋ねられます.

    [新規](New)をクリックすると、axiosを使用してサーバ上でアニメーションを実行してapiを作成し、生成されたアニメーションコードを受信してレンダリングします.

    次のページはパスワードを生成し、新しいパスワードを入力して、もう一度確認します.この場合、別のパスワードを入力すると、次のボタンにジャンプすることはアクティブになりませんので、両方とも正しいパスワードを入力する必要があります.

    最後に、先ほど生成したnimonicコードを入力してkeystoreファイルを生成しアドレスを付与し、生成したnimonicコードとは異なる値を入力するとスキップできないように設計します.

    Server


    サーバはnodeです.jsのexpressを用い,eth-lightwalletモジュールを用いてnimonicコードのパブリケーションとシード生成を行った.

    ニモニックコード生成関数

    const lightwallet = require("eth-lightwallet");
    
    router.post("/newMnemonic", async (req, res) => {
      let mnemonic;
      try {
        mnemonic = lightwallet.keystore.generateRandomSeed();
        res.json({ mnemonic });
      } catch (err) {
        console.log(err);
      }
    });
    クライアントがリクエストを受信すると、keystoreはeth-light財布モジュールに存在します.アニメーションコードはgenerateRandomSeed()関数で生成され、応答として送信されます.
    generateRandomSeed()関数は、nimonicコードの発行に必要な一連のプロセスを処理する関数です.
    英語の単語をどのように生成するか分からないので、時間があれば研究したいです.

    keystoreファイルとアドレス関数の作成

    const lightwallet = require("eth-lightwallet");
    
    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 addresses = ks.getAddresses();
              let keystore = ks.serialize();
    
              fs.writeFile("wallet.json", keystore, function (err, data) {
                if (err) {
                  res.json({ code: 999, message: "실패" });
                } else {
                  res.json({ address: addresses[0], message: "성공" });
                }
              });
            });
          }
        );
      } catch (exception) {
        console.log("NewWallet ==>>>> " + exception);
      }
    });
    クライアントから発行されたNIMONICコードと生成したパスワードをpostリクエストに入れ、受信した場合は各変数に保存し、lightwalletを使用します.keystore.createVault()関数を実行します.この関数の構造はコールバック関数が別のコールバック関数を呼び出すので,最初は理解しにくい.
    createVault関数は、オブジェクト形式のオプションのアニメーションコード、Solt値、HDウォレットパスをパラメータとして受け入れ、keystoreを作成してコールバック関数を実行します.
    keyFromPasswordは入力したpasswordを受信し、key-pairを生成してコールバック関数を実行します.
    GenerateNewAddressでは、keyFromPasswordによって生成されたキーによってアドレスが発行され、アドレス変数に配列形式で含まれます.
    keystoreファイルは、ローカルに格納するために、シーケンス化によりJSON形式でシリアル化されます.
    その後、fsモジュールを使用してkeystoreファイルを格納し、アドレスを応答としてクライアントに渡すことができます.

    完全なコード


    コード全体に引用符アドレスが付いています.
    https://github.com/sujin96/mnemonic-wallet

    振り返る


    メリット


    多くの対処法を忘れてしまったようで、今回の機会を通じて、救援をつかむことから、すべてのことを自分でやってみたので、もっと自信を得ました.サーバー側は既に誰かが作ったモジュールを使っていて、簡単にNimonic財布の開発が完了しました.

    足りないところ


    反応処理には有効性検査にかなりの時間がかかった.まだ完璧な答えは見つからず、ただまともにやっただけだ.もっと柔軟な練習が必要だ.また,モジュールを導入する過程で,そのモジュールの公式文書を正しく読むことができず,機能の実現に専念するため,実際の関数の動作を理解するのに多くの時間がかかった.機能を実現するよりも、理解を目的に、本書をゆっくり読む習慣を身につけましょう.

    改善点


    シンプルな機能とフロントエンドしか提供されていないので、実際の財布に近い外観にしたいと思います.