Date: Fri, 5 Apr 2024 04:52:26 +0800 Subject: [PATCH 042/219] style: title font weight and Flex center --- src/components/StablecoinsTable.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/StablecoinsTable.tsx b/src/components/StablecoinsTable.tsx index 59a73f78a83..f92a25edc59 100644 --- a/src/components/StablecoinsTable.tsx +++ b/src/components/StablecoinsTable.tsx @@ -60,6 +60,7 @@ const StablecoinsTable = ({ |
- |
- |
- |
{url && (
From 281155ebc0a5185a1fe12bca1c2699ae2db7faf1 Mon Sep 17 00:00:00 2001
From: iepn
From 85a511b093874460d5817fdcde7509c4b2cd2604 Mon Sep 17 00:00:00 2001
From: Pablo Pettinari |
gas, addr, val, argOst, argLen, retOst, retLen | `success` | mem[retOst:retOst+retLen-1] := returndata |
From 0891bb2f6dc1d42696f5992ea3cf1188dc224c72 Mon Sep 17 00:00:00 2001
From: Pablo Pettinari Croath Liu 📖 💻 Hayatti 🖋 🐛 |
+ Jeffrey Owoloko 🚧 Colin McKerracher 🚧 Hayatti 🖋 🐛 Jeffrey Owoloko 🚧 |
+ Colin McKerracher 🚧 writegr 🐛 |
---|
{message}
+ +{status}
+ + ++ {" "} + 🦊 + You must install MetaMask, a virtual Ethereum wallet, in your + browser. + +
+ + ), + } + } +} +``` + +那么,这一大段代码究竟是做什么的呢? + +首先,该函数会检查你的浏览器是否启用了 `window.ethereum`。 + +`window.ethereum` 是一个由 MetaMask 和其他钱包提供商注入的全局应用程序接口,它允许网站请求用户的以太坊帐户。 如果被批准,它可以读取用户连接的区块链上的数据,并建议用户签署消息和交易。 参阅 [MetaMask 文档](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents)了解更多信息! + +如果 `window.ethereum` _ 不存在_,则表示未安装 MetaMask。 这会导致返回一个 JSON 对象,其中返回的 `address` 是一个空字符串,而 `status` JSX 对象指示用户必须安装 MetaMask。 + +现在如果 `window.ethereum` _存在_,那么事情就会变得有趣。 + +使用 try/catch 循环,我们将尝试通过调用 [`window.ethereum.request({ method: "eth_requestAccounts" });`](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts) 连接到 MetaMask。 调用此函数将在浏览器中打开 MetaMask,提示用户将他们的钱包连接到你的去中心化应用程序。 + +- 如果用户选择连接,`method: "eth_requestAccounts"` 将返回一个数组,其中包含连接到去中心化应用程序的用户的所有帐户地址。 总之,我们的 `connectWallet` 函数将返回一个 JSON 对象,其中包含此数组中的_第一个 _ `address` \(见第 9 行\),并返回一条 `status` 信息,提示用户向智能合约写入信息。 +- 如果用户拒绝连接,则 JSON 对象将包含返回的 `address` 的空字符串和反映用户拒绝连接的 `status` 信息。 + +现在我们已经编写了这个 `connectWallet` 函数,下一步是调用它到我们的 `HelloWorld.js` 组件中。 + +#### 将 `connectWallet` 函数添加到你的 `HelloWorld.js` 用户界面组件中 {#add-the-connectWallet-function-to-your-HelloWorld-js-ui-component} + +导航到 `HelloWorld.js` 文件中的 `connectWalletPressed` 函数,并将其更新为以下内容: + +```javascript +// HelloWorld.js + +const connectWalletPressed = async () => { + const walletResponse = await connectWallet() + setStatus(walletResponse.status) + setWallet(walletResponse.address) +} +``` + +注意我们的大部分函数是如何从 `interact.js` 文件中的 `HelloWorld.js` 组件中抽象出来的? 这就是我们遵守 M-V-C 规范的原因! + +在 `connectWalletPressed` 中,我们只需对导入的 `connectWallet` 函数进行 await 调用,并使用其响应,通过变量的状态挂钩更新我们的 `status` 和 `walletAddress ` 变量。 + +现在,让我们保存两个文件 \(`HelloWorld.js` 和 `interact.js`\) ,并测试一下我们目前的用户界面。 + +打开浏览器,在地址栏中输入 [localhost:3000](http://localhost:3000/),然后按页面右上角的“Connect Wallet”按钮。 + +如果你安装了 MetaMask,系统会提示你将钱包连接到去中心化应用程序。 接受邀请并连接。 + +你会看到钱包按钮现在反映你的地址已连接! 太棒了 🔥 ! + +接下来,尝试刷新页面......有点儿奇怪。 我们的钱包按钮提示我们连接 MetaMask,尽管它已经连接...... + +然而,不要害怕! 我们可以通过实现 `getCurrentWalletConnected` 轻松解决这个问题(明白了吗?),它将检查一个地址是否已经连接到我们的去中心化应用程序,并相应地更新我们的用户界面! + +#### `getCurrentWalletConnected` 函数 {#the-getcurrentwalletconnected-function} + +将 `interact.js` 文件中的 `getCurrentWalletConnected` 函数更新如下: + +```javascript +// interact.js + +export const getCurrentWalletConnected = async () => { + if (window.ethereum) { + try { + const addressArray = await window.ethereum.request({ + method: "eth_accounts", + }) + if (addressArray.length > 0) { + return { + address: addressArray[0], + status: "👆🏽 Write a message in the text-field above.", + } + } else { + return { + address: "", + status: "🦊 Connect to MetaMask using the top right button.", + } + } + } catch (err) { + return { + address: "", + status: "😥 " + err.message, + } + } + } else { + return { + address: "", + status: ( + ++ {" "} + 🦊 + You must install MetaMask, a virtual Ethereum wallet, in your + browser. + +
+ + ), + } + } +} +``` + +这段代码与我们刚刚在上一步中编写的 `connectWallet` 函数 _非常相似_ 。 + +主要区别在于,这里我们调用了 `eth_accounts` 方法,它只是返回一个数组,其中包含当前连接到我们的去中心化应用程序的 MetaMask 地址,而不是调用 `eth_requestAccounts` 方法来打开 MetaMask 以供用户连接他们的钱包。 + +为了看看这个函数在实际应用中的效果,让我们在 `HelloWorld.js` 组件的 `useEffect` 函数中调用它: + +```javascript +// HelloWorld.js + +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) + addSmartContractListener() + + const { address, status } = await getCurrentWalletConnected() + setWallet(address) + setStatus(status) +}, []) +``` + +请注意,我们使用调用 `getCurrentWalletConnected` 的响应来更新我们的 `walletAddress` 和 `status` 状态变量。 + +现在我们已经添加了这段代码,让我们刷新浏览器窗口,看看最新的效果如何。 + +很不错! 按钮应显示你已连接,并显示已连接钱包地址的预览 — 即使在你刷新后也是如此! + +#### 实现 `addWalletListener` {#implement-addwalletlistener} + +我们的去中心化应用程序钱包设置的最后一步是实现钱包监听器,以便我们的用户界面在钱包状态发生变化时更新,例如当用户断开或切换帐户时。 + +在你的 `HelloWorld.js` 文件中,按照以下方式修改你的 `addWalletListener` 函数: + +```javascript +// HelloWorld.js + +function addWalletListener() { + if (window.ethereum) { + window.ethereum.on("accountsChanged", (accounts) => { + if (accounts.length > 0) { + setWallet(accounts[0]) + setStatus("👆🏽 Write a message in the text-field above.") + } else { + setWallet("") + setStatus("🦊 Connect to MetaMask using the top right button.") + } + }) + } else { + setStatus( ++ {" "} + 🦊 + You must install MetaMask, a virtual Ethereum wallet, in your browser. + +
+ ) + } +} +``` + +我敢打赌,到了这一步你可能已经无需我们帮助就能理解这里发生的情况了,但为了确保详尽无遗,我们还是快速梳理一下: + +- 首先,我们的函数检查是否启用了 `window.ethereum` \(即 MetaMask 已安装\)。 + - 如果未启用,我们只需将 `status` 状态变量设置为提示用户安装 MetaMask 的 JSX 字符串。 + - 如果启用,我们会在第 3 行设置监听器 `window.ethereum.on("accountsChanged")` 监听 MetaMask 钱包中的状态变化,变化包括用户将其他帐户连接到去中心化应用程序、切换帐户或断开帐户。 如果至少连接了一个帐户,`walletAddress` 状态变量将更新为监听器返回的 `accounts` 数组中的第一个帐户。 否则,`walletAddress` 设置为空字符串。 + +最后,但同样重要的一点是,我们必须在 `useEffect` 函数中调用它: + +```javascript +// HelloWorld.js + +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) + addSmartContractListener() + + const { address, status } = await getCurrentWalletConnected() + setWallet(address) + setStatus(status) + + addWalletListener() +}, []) +``` + +就是这样! 我们已经成功完成了所有钱包功能的编程! 现在,我们来完成最后一个任务:更新智能合约中存储的消息! + +### 第六步:实现 `updateMessage` 函数 {#step-6-implement-the-updateMessage-function} + +好嘞,伙计们,我们已经来到最后阶段了! 在 `interact.js` 文件中的 `updateMessage` 函数中,我们将执行以下操作: + +1. 确保我们想要在智能合约中发布的消息有效 +2. 使用 MetaMask 钱包签署每项交易 +3. 从 `HelloWorld.js` 前端组件调用这个函数 + +这不会太耗时;我们把这个去中心化应用程序做完! + +#### 输入错误处理 {#input-error-handling} + +显然,我们在函数开头加入一些输入错误处理代码是有意义的做法。 + +如果未安装 MetaMask 扩展,或者钱包尚未连接 \(即传入的 `address` 为空字符串\),亦或是 `message` 为空字符串,我们希望函数能够提前返回。 让我们在 `updateMessage` 函数中添加以下错误处理代码: + +```javascript +// interact.js + +export const updateMessage = async (address, message) => { + if (!window.ethereum || address === null) { + return { + status: + "💡 Connect your MetaMask wallet to update the message on the blockchain.", + } + } + + if (message.trim() === "") { + return { + status: "❌ Your message cannot be an empty string.", + } + } +} +``` + +现在,我们已经实现了正确的输入错误处理,接下来就是通过 MetaMask 来签署交易的时候了! + +#### 签署交易 {#signing-our-transaction} + +如果你已经对传统的 web3 以太坊交易驾轻就熟,那么接下来我们要编写的代码将会非常熟悉。 在输入错误处理代码下方,向 `updateMessage` 函数添加以下内容: + +```javascript +// interact.js + +//set up transaction parameters +const transactionParameters = { + to: contractAddress, // Required except during contract publications. + from: address, // must match user's active address. + data: helloWorldContract.methods.update(message).encodeABI(), +} + +//sign the transaction +try { + const txHash = await window.ethereum.request({ + method: "eth_sendTransaction", + params: [transactionParameters], + }) + return { + status: ( + + ✅{" "} + + View the status of your transaction on Etherscan! + +.env
! 请确保永远不要与任何人共享或公开您的 .env
文件,因为这样做会泄露您的私钥。 如果您使用版本控制,请将您的 .env
添加到 gitignore 文件中。
+不要提交 .env
! 请确保永远不要与任何人共享或公开你的 .env
文件,因为这样做会泄露你的私钥。 如果你使用版本控制,请将你的 .env
添加到 gitignore 文件中。