使用しながら学ぶ-ReactのMaterialUIフレームワークを使用して、EthereumウォレットのシンプルなMetaMaskのようなWebバージョンを開発します(9)

1.前回のレビューと現在の計画

       開発の最終段階では、ERC20トークン転送の機能を実装しました。この開発では、計画どおりにトランザクションに署名する機能を実装しました。前の章で述べたように、私たちのウォレットはWebウォレットであるため、署名トランザクションを実装する方法は少し醜いです。ユーザーは、クエリ文字列を介してトランザクションオブジェクトのパラメータを送信し、トランザクションを分析してから署名することしかできません。署名されたトランザクションとETH転送の本質は実際には同じです。どちらも最初にトランザクションオブジェクトを作成し、次に秘密鍵を使用してトランザクションオブジェクトに署名します。トランザクションオブジェクトの作成方法について、JsでEthereumトランザクションオブジェクトを作成する方法の詳細な説明を書きました。時間があるときにそれを見てみましょう。

       ウォレットがlocalhost:3000(つまり、開発サーバー)で実行されているとします。次のURLを指定した場合:
http:// localhost:3000 / transfer?data = 0x07391dd6000000000000000000000000000000000000000000000000000000000000000a&to = 0x0cbde7fbf0f97726b804135fa638a86ceecae633&chainId = 42

       ウォレットはクエリ文字列を解析してトランザクションオブジェクトを作成し、秘密鍵を使用してトランザクションに署名して送信します。もちろん、分析が完了した後、ユーザーは最初にログインする必要があります。今回開発された署名済みトランザクションオブジェクトページは次のとおりです。
ここに写真の説明を挿入
       クリックして確認します。トランザクションが送信された後、簡単なトランザクション情報インターフェイスに入ります。
ここに写真の説明を挿入
       ここで、戻るボタンをクリックしてメインウォレットインターフェイスに戻ります。

2.機能の実現

2.1UIの実装

       UIインターフェイスはMetaMaskインターフェイスを参照しますが、これを組み合わせるのは少し面倒です。主なポイントは次のとおりです。

       1.flexレイアウトの使用ですflexレイアウトで最も一般的に使用されるのは、長軸と短軸の配置を含む要素の配置です。スピンドルアライメントのjustifyContent属性通常はspace-betweenまたはに設定されcenterます。2次軸のalignItems属性は、通常、に設定されcenterます。次のコードスニペットなど:

const useStyles = makeStyles(theme => ({
    
    
    container: {
    
    
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
    },
    containerHeader: {
    
    
        display: 'flex',
        justifyContent: 'space-between'
    },
}));

       2.もう1つの重要なポイントは、状況に応じて柔軟に設定する必要があるロケーション属性です。ここでは、ロケーション属性について簡単に紹介します。CSSでは、の要素positionプロパティが4つのありstatic(默认值):値をfixed(固定值)、、absolute(绝对的)relative(相对的)

  • 静的静的とは、通常のフローレイアウトを使用することを意味します。静的は定位置ではないため、左上、右下、およびz-indexの影響を受けません。
  • 固定位置が固定されている要素が最もわかりやすく、常に表示され、ウィンドウに従って位置が計算されます。私たちのウォレットはウェブの中央のサイズの一部しか占めていないため、ウォレット全体が固定位置要素を使用していません。
  • 相対位置は静的位置とほぼ同じで、通常のレイアウトフローに従います。ただし、左上、右下などの位置パラメータを使用できます。
  • 絶対位置は固定位置に似ていますが、最も近い非静的要素に基づいて位置を決定します。

       それらの中で、相対位置は非静的であるため、相対位置要素は絶対位置要素の基点を提供することもできます。アドレスアイコンの高さとウォレット内のアドレスを調整するために、相対位置を使用します。コードスニペットは次のとおりです。

address:{
    
    
    position:'relative',
    marginLeft:theme.spacing(1),
    top:theme.spacing(0.5),
},

フロントエンドの開発がすでにマスターされている限り、もう1つの一般的に使用される設定はパディングとマージンです。

2.2コードロジックの要点

       今回の開発は比較的簡単です。複雑なUIスティッチングを除いて、ウォレットの既存のコンテンツにいくつかの変更を加えることでコードロジックが完成します。主に、現在構築されているトランザクションオブジェクトとトランザクション応答を記録するために2つのグローバル変数が追加されます。もう1つのポイントは、クエリ文字列を使用して、トランザクションオブジェクトを構築するのに十分な情報を取得することです。

2.2.1クエリ文字列の値を取得する

ReactのURLでクエリ文字列を取得する方法はたくさんあります。これは、このウォレットでクエリ文字列を取得する方法です
。1。withRouter主にlocation属性を提供するために、出力コンポーネントをパッケージ化するために使用します

export default withRouter(SignTransaction)

2.関数コンポーネントでlocation属性を使用する

function SignTransaction({
    
    history,location}) {
    
    
}

3、URLSearchParamsクエリ文字列を取得するために使用され、特定のgetメソッドを取得するためのクエリオブジェクト、属性値を返します

let search = location.search
let query = new URLSearchParams(search)
let transaction_info = convertQuery(query)
......
updateGlobal({
    
    
    transaction:transaction_info
})

2.2.2トランザクションオブジェクトの構築

       この読者は、この記事の冒頭で述べた記事を最初に読むことができます。もちろん、読者がすでに非常に熟練している場合は、その記事をスキップできます。

const {
    
    isLogin,transaction,wallet} = useGlobal()
let trans = {
    
    
    ...transaction,
    gasPrice:utils.parseUnits("" + price,'gwei'),
    value:utils.parseEther("" + (transaction.value || 0)),
}

       ユーザーにgasPriceをリセットさせることができるため、ここでgasPriceが置き換えられます。また、簡単にするために、合意する必要があります。urlクエリ文字列から送信される値はすべて10進数(16進数ではない)であり、すべて共通の単位です。したがってvalue=0.01クエリ文字列の代わりにvalue=10000000000000000同様にgasPrice、値もGweiユニット番号に基づいています。chainIdの値は10進数であり、覚えやすい1,3,4,42しかないため、ネットワーク名ではありません。注:data値は16進文字列で、「0x」で始まる必要があります。

2.2.3トランザクションの送信

       トランザクションの署名はETH転送と同じですが、トランザクションオブジェクトにはさらにいくつかの属性値があります。トランザクションが送信された後、いくつかのルーティングおよびナビゲーション処理が必要です。

setCircleOpen(true)
//签名并发送交易
let provider = ethers.getDefaultProvider(net)
let tx_wallet = wallet.connect(provider)
tx_wallet.sendTransaction(trans).then(tx => {
    
    
    setCircleOpen(false)
    //todo 跳到交易信息界面
    updateGlobal({
    
    
        txGlobal:{
    
    
            tx,
            symbol:(!trans.data || trans.data==='0x') ? "ETH" : '',
            status:'pending',
        },
        transaction:null,
    })
    history.push('/send')
}).catch(err =>{
    
    
    setCircleOpen(false)
    return showSnackbar("交易发送失败",'error')
})

       コードスニペットで、最初に進行状況バーのアニメーションを開いて、トランザクションが送信されていることを示します。sendTransaction戻るときは、進行状況バーを閉じます。次に、グローバル変数txGlobalを設定し、トレーディングオブジェクトをリセットしてnull、トレーディングインターフェイスに再入らないようにします(現時点transactionでは不要であり、トランザクションが送信されています)。最後にに移動しSendEther.jsxます。SendEther.jsxコードスニペットを見てみましょう

const {
    
    txGlobal} = useGlobal()
const [values,setValues] = useState({
    
    
    ...values_init,
    ...txGlobal
})
const {
    
    status,tx,amount,symbol} = values
if(status === BEGIN){
    
    
    return (
        <SendEtherForm cancelCallback={
    
    resverseBack} sendCallback={
    
    sendOver} />
    )
}else if(status === PENDING) {
    
    
    return (
        <TransactionInfo tx={
    
    tx} amount={
    
    amount} symbol={
    
    symbol} reverseCallback={
    
    resverseBack} />
    )
}else {
    
    
    return null
}

       ナビゲートする前にステータスを「保留中」に設定したため、送信インターフェイスではなく、トランザクション情報インターフェイスが表示されます。

2.2.4transferルーティング処理

       署名トランザクションインターフェイスは他のインターフェイスとは異なり、ウォレットのヘッダーがないため、ルート比較の場所を変更してtransfer、ウォレット本体ではなく以前の場所で比較する必要があります。これは次src\views\Main.jsxのコードスニペットです:

import SignTransaction from './SignTransaction'
....
<Router >
    <Switch>
        <Route path='/transfer' component={
    
    SignTransaction} />
        <Route path='/'>
             <WalletBar />
             <Routes />
        </Route>
    </Switch>
</Router>

       ここから、一致する場合transferは対応するページに直接ジャンプし、一致しない場合は最初にウォレットのタイトルバー(つまり、ロゴとネットワーク切り替えボタン)を表示し、次にメインコンテンツがルートに従って再度一致することがわかります。

三、ちょっとした経験

       この開発には、主にUIスティッチングなどのコンテンツはあまりありません。ここに少し個人的な経験があります。div底がない、または他の要素がないと感じた場合は、背景色を明るい色に設定して、サイズ、形状、範囲などを簡単に確認できます。以下のようにそれとも、あなたはChromeデベロッパーツールを開くことができますし、あなたがそれを見ることができます
ここに写真の説明を挿入
       開発ツールでクリックしてElements、あなたはノードを展開し、それらのいずれかをクリックし、全体のHTMLノードツリーを見ることができdiv、あなたは左側に1が表示されます青色の背景には、それはこのことを表し、ブロックをマークしdiv、右に表示marginborderpaddingというように。

4、まとめ

       この開発は、主にウォレット署名トランザクションの実現を完了します。トランザクションは、トランザクションオブジェクトの属性値をクエリ文字列の形式でWebページに渡し、Webページによって解析されることによって実行されます。Webページのバージョンの制限により、署名するたびに新しいページを開く必要がありますが、これは欠点です。このウォレットの開発の主な目的は、それがどれだけうまくできるかではなく、何ができるかを学ぶことであるためです。

       ウォレットのメインインターフェイスにはトランザクションレコードがありますが、現在開発は計画されていません。興味のある読者は自分で試すことができます。主な目的は、各トランザクション送信のステータス(完了したかどうか、トランザクションハッシュなど)を保存し、対応するアカウントに対応するネットワークに保存し、ローカルストレージを使用することです。ウォレットにログインした後、これらのトランザクションのステータスを取得して更新します。

       このウォレットプランの機能はすべて開発されています。1つの機能を1つの機能ごとに開発しているため、全体的な設計と相互の調整が不足しているため、もう少し時間をかける予定codereviewです。主にコードを最適化または簡素化すると同時に、パッケージ化してWebサイトに公開します。

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

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

おすすめ

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