学習して使用する-ReactのMaterialUIフレームワークを使用して、Ethereumウォレットの単純なMetaMaskのようなWebバージョンを開発します(6)

前回の開発では、ウォレットのETH転送機能を完了しましたが、今回の開発では、アカウントのエクスポート機能を完了する予定です。

1.この開発計画

       ウォレットはWebバージョンであるため、アカウントの秘密鍵は暗号化されてローカルストレージに保存されます。ユーザーがブラウザのローカルストレージをクリアすると、アカウントは失われます。したがって、ユーザーの秘密鍵またはニーモニックをエクスポートするには、アカウントのエクスポート機能が必要です。ユーザーは、アカウントの損失を防ぐために、それをコピーして別の場所に保存できます。開発予定のページは以下の通りです。

       ユーザーがログインした後、右上隅にあるアカウントオプションをクリックすると、選択メニューがポップアップ表示され
ここに写真の説明を挿入
       ますクリックし在EtherScan上查看て新しいブラウザウィンドウ開き、EtherScanに移動してアカウントの詳細を表示します。アカウントの詳細をクリックすると、次のページが表示されます
ここに写真の説明を挿入
       。WeChatでQRコードをスキャンすると、アカウントのアドレスが表示されます。このページにも同じ在EtherScan上查看機能があります。下部には、ニーモニックのエクスポートボタンと秘密鍵のエクスポートボタンがあります。

       促す:

       [ニーモニックのエクスポート]ボタンは、ニーモニックフレーズを使用してアカウントをインポートする場合にのみ表示され、秘密鍵を使用してアカウントをインポートすることでニーモニックフレーズを取得することはできません。ウォレットは秘密鍵のみを保存するため、ログイン時に秘密鍵を使用してログインします。ニーモニックフレーズを取得できない場合、ニーモニックフレーズをエクスポートすることはできません。

       [秘密鍵のエクスポート
ここに写真の説明を挿入
       ]をクリックすると、次のインターフェイスが表示されます。パスワードを入力して[OK]をクリックすると、秘密鍵がテキストボックスに表示されます。秘密鍵をクリックしてペーストボードにコピーし、別の場所に保存します。
ここに写真の説明を挿入
       [完了]をクリックしてメインウォレットインターフェイスに戻り、左上隅の[戻る]ボタンをクリックしてアカウント詳細インターフェイスに戻ります。

第二に、ユーザーアドレスアイコンの実現

       MetaMaskでわかるように、各アカウントには、メインネットワークアカウント、次の図のKovanアカウント1および2など、アカウントを表すための異なる丸いアイコンがあります。
ここに写真の説明を挿入
       この関数jazziconを実装するためにライブラリを使用します。これはそのドキュメントアドレスです:=> https://www.npmjs.com/package/jazziconこれは、HTMLノードオブジェクト(含ま返します)。通常、アイコンを追加するには、親要素(通常は1つメソッドを使用します。svgdivdivappendChild

       Reactでは、要素の配置には通常、次の方法が使用されます。

const ref = useRef()
......
<div ref={
    
    ref} />

       次に、子ノードを追加してを使用しますref.current.appendChild(node)ウォレットでは、アカウント詳細インターフェイスがDialogコンポーネントを使用して実装されているだけです。理由は不明ですが、Dialogコンポーネントの子要素のrefプロパティバインドすることはできません(Dialogコンポーネント自体もバインドできません)。そのため、上記の方法を使用してアカウントアイコンを表示することはできません。迂回しました。最初にノードオブジェクトを文字列に変換してから、親オブジェクトのinnerHTMLプロパティを設定します。関連するコードを以下に示します。

  1. アイコンを生成するコード
import {
    
    useMemo} from 'react';
import Jazzicon from 'jazzicon'

export function useAddressIcon(address,size) {
    
    
  return useMemo(() => {
    
    
      return Jazzicon(size, parseInt(address.slice(2, 8), 100))
  }, [address,size])
}

       コードからわかるように、アドレスとアイコンサイズを指定すると、ノードオブジェクトが返されます。使用しているためuseMemo、パラメータとしてのアドレスとサイズが変わらない場合は、再計算せずに最後の戻り値を直接返します。

  1. 文字列へのノードオブジェクト、これは他の実装を指します
//将一个html节点对象转换成字符串
function nodeToString(node) {
    
    
    let tmpNode = document.createElement( "div" );
    tmpNode.appendChild( node.cloneNode( true ) );
    let str = tmpNode.innerHTML;
    tmpNode = node = null; // prevent memory leaks in IE
    return str;
}
  1. divアイコン文字列を表示します
<div dangerouslySetInnerHTML={
    
    {
    
    __html: nodeToString(icon)}}  />

       MetaMaskと比較すると、もう1つ小さな違いがあります。これは、MetaMaskのアカウント詳細インターフェイスです。
ここに写真の説明を挿入
       アカウントアイコンの半分が詳細の下部paperの上に表示されていることがわかりますここDialogコンポーネントを直接使用しているためpaper、境界線から移動したはアイコンを表示できず、アイコンは上に移動しません。また、読者が問題の原因を指摘したり、解決策を示したりすることを願っています。

第三に、QRコードの実現

       QRコードの実現は非常に簡単で、qrcode-reactこのライブラリを使用するだけです。関連するコードは次のとおりです。

import QRCode from 'qrcode-react';
......
<QRCode size={
    
    150} value={
    
    ETHEREUM_PREv + address}/>

size属性value       設定して直接表示してもかまいません

4、マテリアルUIコンポーネントの外観をカスタマイズします

       当初の計画から、ボタンをクリックするとメニューの背景色が黒く透明になり、メニューのデフォルトの背景が白になっていることがわかります。これには、マテリアルUIコンポーネントの一部のプロパティを変更する必要があります公式ドキュメントのカスタムコンポーネントの詳細なガイドは次のとおりです:https//material-ui.com/zh/customization/components/

       ここでは、ドキュメントに記載されているアプローチを採用しています用类覆盖样式この開発に適用されるのは、メニューの背景色を変更することです。まず、メニューコンポーネントのAPIガイドを開きます:https//material-ui.com/zh/api/menu/ページの下部に、書き換え
ここに写真の説明を挿入
       可能なCSSスタイルシートのルールが一覧表示されます。paperルールがPaper要素(メニューの背景を含む)に適用されていることがわかるので、設定する必要があります。関連するコードは次のとおりです。

const useStyles = makeStyles(theme => ({
    
    
    menuPaper:{
    
    
        border: '1px solid #d3d4d5',
        backgroundColor:"#000000BB",
        color:'white'
    }
}));
......
const classes = useStyles();
......
<Menu
    id="customized-menu-account"
    anchorEl={
    
    anchorRefAccount.current}
    keepMounted
    open={
    
    state.accountOpen}
    onClose={
    
    handleCloseAccount}
    onKeyDown={
    
    handleListKeyDownAccount}
    classes={
    
    {
    
    
        paper:classes.menuPaper
    }}
    elevation={
    
    0}
    getContentAnchorEl={
    
    null}
    anchorOrigin={
    
    {
    
    
      vertical: 'bottom',
      horizontal: 'right',
    }}
    transformOrigin={
    
    {
    
    
      vertical: 'top',
      horizontal: 'right',
    }}
>

       メニューコンポーネントには多くの属性が設定されています。メニューAPIで各属性の特定の意味を確認できます。リンクは、上記のとおりです。次に、classes属性に焦点を当てましょう。ここでpaperは、ルールをプリセットの名前付きmenuPaperスタイルに設定します。

5、その他の詳細

  1. アカウントをエクスポートするときにパスワードを確認する必要があるため、簡単にするために、アカウントログイン(アカウントの作成、アカウントのインポートを含む)のパスワードをグローバル変数、つまりに保存し、GlobalProvider.js使用時に直接比較します。
  2. hooks\index.jsアドレスアイコンを生成するフックなど、ユーザー定義を格納するための新しいフックを作成しましたツールutils\index.jsとは異なり、分離する必要があります。
  3. 私たちのウォレットはデスクトップのWebページの中央のごく一部しか占めていないため、メッセージバーは左下隅に少し離れて表示されます。そのため、デスクトップのメッセージバーが変更され、下部の中央に表示されます。
  4. アカウントのエクスポートでは、ウォレットの秘密鍵またはニーモニックを直接表示します。もちろん、さらに拡張して、暗号化されたjsonウォレットとしてエクスポートすることもできます。これは、ここでの開発計画には含まれていません。

6、まとめ

       今回の開発では、アカウントのエクスポート機能を実装し、ポップアップメニューの背景色を変更しました。適用される知識ポイントは、主にアドレスアイコンの生成と追加、2次元コードの生成、およびクラスカバレッジスタイルによるコンポーネントの外観のカスタマイズです。

       開発中に2つの問題が発生しました。1つは、Dialogコンポーネント(それ自体を含む)refサブ要素の属性をバインドできないことです。次に、ダイアログコンポーネントの子要素は、下のPaper境界を超えると表示できません。時間の問題があるため、これ以上の詳細な調査はありません。時間があるときに後で確認します。また、経験豊富な読者の皆様には、根本的な原因を指摘したり、解決策を提示していただきたいと思います。

       次の開発では、ERC20トークンをユーザーに追加する機能を実装する予定です。

       このウォレットコードクラウド(gitee)ウェアハウスアドレスは次のとおりです。=> https://gitee.com/TianCaoJiangLin/khwallet

       読者は、エラーを指摘したり、改善を提案したりするためにメッセージを残すことができます。

おすすめ

転載: blog.csdn.net/weixin_39430411/article/details/104121393