首页 > 解决方案 > 如何从用户的以太坊地址进行 Tx?

问题描述

我想做的事

最终目标是使用 Next.js 和 Metamask 让访问主页的用户发出汇款 Tx。当前的实现将助记词(如密钥)存储在隐藏文件中并调用它,这允许我们执行转账交易但不允许我们更改每个用户的地址。

问题

另外,由于我已经成功地从 Metamask 调用了地址,我所要做的就是将此地址传递给发出 Tx 的外部库(ethers),但我不知道该怎么做。

这是我在项目中使用的库的文档

https://docs.metamask.io/guide/ethereum-provider.html#methods https://docs.ethers.io/v5/api/signer/#Wallet.fromMnemonic

我做了什么

实际代码是这样实现的。点击connectMetamask按钮会获取用户的地址,然后点击Exchange按钮会发出一个Tx(表单只是装饰)。

import { useState } from "react";
import { Contract, utils, ethers } from 'ethers'
import ConnectMetamaskButton from '../components/ConnectMetamaskButton';
import zkswapABI from '../../zkswap.ABI.json'
import * as zksync from "zksync"

export default function ConnectWallet(props) {
    const [Accounts, setAccounts] = useState("Connect Metamask");
    const ethersProvider = ethers.getDefaultProvider("ropsten");

    var MNEMONIC = process.env.MNEMONIC;
    const ethWallet = ethers.Wallet.fromMnemonic(MNEMONIC).connect(ethersProvider);
    console.log("Accounts = ", Accounts);

    async function ConnectMetamask() {

        try {
            const newAccounts = await ethereum.request({
                method: 'eth_requestAccounts',
            })

            let accounts = newAccounts;
            setAccounts(accounts[0]);
            console.log("Accounts = ", Accounts);

        } catch (error) {
            console.error(error);
        }
        getBalases();
    };

    async function getBalases() {
        const address = Accounts;
        console.log("address = ", address);
        const zkSyncUrl = "https://api.zks.app/v2/3/account/0x2D1Ac1CA744da293c5AcceAe25BE8DCd71168241/balances";
        const response = await fetch(zkSyncUrl);
        const data = await response.json();
        console.log("data = ", data);
    };

    async function withdrawETH() {

        const syncProvider = await zksync.getDefaultProvider("ropsten");
        const syncWallet = await zksync.Wallet.fromEthSigner(ethWallet, syncProvider);

        const withdraw =
            await
                syncWallet.withdrawFromSyncToEthereum({
                    ethAddress: ethWallet.address,
                    token: "ETH",
                    amount: ethers.utils.parseEther("0.01"),
                });
    }

    async function depositETH() {
        let ABI = zkswapABI;
        let ZKSwapContract = '0x010254cd670aCbb632A1c23a26Abe570Ab2Bc467'
        const contract = new Contract(ZKSwapContract, ABI, ethWallet)
        const tx = await contract.depositETH(ethWallet.address, {
            value: utils.parseEther('0.01')
        })
        return tx
    }

    async function zkSyncToZKSwap() {
        event.preventDefault();
        console.log("amount = ", event.target.amount.value);

        withdrawETH();
        depositETH();
    }

    return (
        <div>
            <header className="text-gray-100 bg-gray-900 body-font shadow w-full">
                <div className="container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center">
                    <nav className="flex lg:w-2/5 flex-wrap items-center text-base md:ml-auto">
                        <a className="mr-5 hover:text-gray-900 cursor-pointer border-b border-transparent hover:border-indigo-600"></a>
                    </nav>
                    <a
                        className="flex order-first lg:order-none lg:w-1/5 title-font font-medium items-center lg:items-center lg:justify-center mb-4 md:mb-0">
                        <span className="ml-3 text-xl">L2 DEX HUB</span>
                    </a>
                    <div className="lg:w-2/5 inline-flex lg:justify-end ml-5 lg:ml-0">
                        <ConnectMetamaskButton Accounts={Accounts} onClick={() => { ConnectMetamask(); }}></ConnectMetamaskButton>

                    </div>
                </div>
            </header>

            <div>
                <section className="h-screen w-4/5 max-w-5xl mx-auto flex items-center justify-center flex-col">
                    <form onSubmit={zkSyncToZKSwap}>
                        <div className="flex flex-col rounded-lg overflow-hidden sm:flex-row">
                            <label htmlFor="amount"></label>
                            <input className="py-3 px-4 bg-gray-200 text-gray-800 border-gray-300 border-2 outline-none placeholder-gray-500 focus:bg-gray-100" id="amount" type="text" amount="amount" placeholder="Amount" />
                            <button className="py-3 px-4 bg-gray-700 text-gray-100 font-semibold uppercase hover:bg-gray-600" type="submit" >Exchange</button>
                        </div>
                    </form>
                </section>
            </div>
        </div>
    );
};

这两个函数实际上都可以工作,但我们想在不使用助记符的情况下实现它!

据我从文档中可以看出,它从助记符或私钥生成 Wallet 对象,因此无法从像我这样的地址处理?

(也许 web3.js 可以做到?)

标签: reactjsnext.jsethereummetamaskethers.js

解决方案


推荐阅读