网站建设未来发展前景,wordpress地址和找点地址,yxcms wordpress,自己怎么健网站视频教程#x1f978; 本教程来自官网#xff1a;https://docs.alchemy.com/docs。对原文部分内容进行了修改。教程中所有实例经过本人实践#xff0c;代码可见#xff1a;https://github.com/ChuXiaoYi/web3Study 区块链技术令人惊叹#xff0c;因为它使我们能够使用代码和软件编… 本教程来自官网https://docs.alchemy.com/docs。对原文部分内容进行了修改。教程中所有实例经过本人实践代码可见https://github.com/ChuXiaoYi/web3Study 区块链技术令人惊叹因为它使我们能够使用代码和软件编程货币。只需几行代码就可以构建各种应用程序和协议为世界各地的人们创造新的机会。 “Buy Me A Coffee”是一个流行的网站创作者、教育家、娱乐者和各种人们用它来创建一个着陆页任何人都可以发送一些钱作为他们的服务的感谢。然而为了使用它你必须有银行账户和信用卡。并非每个人都有 建立在区块链之上的分散化应用程序的一个好处是世界各地的任何人都可以使用一个以太坊钱包来访问该应用程序任何人都可以在不到1分钟的时间内免费设置一个以太坊钱包。让我们看看如何利用它来获得优势 在本教程中您将学习如何开发和部署一个分散化的“Buy Me A Coffee”智能合约允许访问者发送给您虚假以太作为小费并留下好的消息使用Alchemy、Hardhat、Ethers.js和以太坊Goerli。 通过本教程您将学习以下内容 使用Hardhat开发环境构建、测试和部署智能合约。 连接您的MetaMask钱包到Goerli测试网络使用Alchemy RPC端点。 从goerlifaucet.com获取免费的Goerli ETH。 使用Ethers.js与部署的智能合约进行交互。 使用Replit为您的分散化应用程序构建前端网站。 视频教程版本在此处: https://youtu.be/cxxKdJk55Lk 先决条件 为了准备本教程的其余部分您需要拥有 npm ( npx) 版本 8.5.5 node 版本 16.13.1 一个 Alchemy 帐户 在此免费注册 以下不是必需的但非常有用 一些熟悉 命令行 一些熟悉 JavaScript 现在让我们开始构建我们的智能合约 编写 BuyMeACoffee.sol 智能合约 Github 参考链接https://github.com/alchemyplatform/RTW3-Week2-BuyMeACoffee-Contracts 如果你之前使用过类似于 OpenZeppelin Wizard 和 Remix 的工具那么你已经准备好使用 Hardhat 了。 Hardhat 类似于开发环境和编码工具但它更加可定制并且从你自己计算机的命令行界面运行而不是浏览器应用程序。 我们将使用 Hardhat 来 生成项目模板 测试我们的智能合约代码 部署到 Goerli 测试网络 让我们开始吧 打开你的终端并创建一个新目录。 mkdir BuyMeACoffee-contractscd BuyMeACoffee-contracts 在此目录中我们想要启动一个新的npm项目默认设置即可 npm init -y 这将为您创建一个名为package.json的文件其内容应如下所示 (base) ➜ BuyMeACoffee-contracts git:(main) ✗ npm init -yWrote to /Users/chuxiaoyi/work/web3/web3Study/BuyMeACoffee-contracts/package.json:{ name: buymeacoffee-contracts, version: 1.0.0, description: , main: index.js, scripts: { test: echo \Error: no test specified\ exit 1 }, keywords: [], author: , license: ISC} 安装 Hardhat npm install --save-dev hardhat 现在我们创建一个示例项目 npx hardhat 您应该会看到一个欢迎消息和可以执行的操作选项。选择Create a JavaScript project: 888 888 888 888 888888 888 888 888 888888 888 888 888 8888888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888888 888 88b 888P d88 888 888 88b 88b 888888 888 .d888888 888 888 888 888 888 .d888888 888888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.888 888 Y888888 888 Y88888 888 888 Y888888 Y888 Welcome to Hardhat v2.14.0 同意所有默认设置项目根目录、添加.gitignore文件、安装所有示例项目依赖项 ✔ What do you want to do? · Create a JavaScript project✔ Hardhat project root: · /Users/chuxiaoyi/work/web3/web3Study/BuyMeACoffee-contracts✔ Do you want to add a .gitignore? (Y/n) · y✔ Do you want to install this sample projects dependencies with npm (nomicfoundation/hardhat-toolbox)? (Y/n) · y Hardhat会为我们生成一个hardhat.config.js文件以及一些包含示例代码的文件夹包括contracts、scripts和test。 要检查一切是否正常工作请运行 npx hardhat test 我们现在已经成功配置了我们的 hardhat 开发环境。 你的项目目录现在应该看起来像这样我在使用 tree 进行可视化 tree -C -L 1.├── README.md├── contracts├── hardhat.config.js├── node_modules├── package-lock.json├── package.json├── scripts└── test 重要的文件夹和文件包括 contracts - 存放智能合约的文件夹 在这个项目中我们只会创建一个智能合约来组织我们的 BuyMeACoffee 逻辑 scripts - 存放 Hardhat JavaScript 脚本的文件夹 我们将编写 deploy 逻辑 例如 buy-coffee 脚本 还有一个 withdraw 脚本来兑现我们的小费 hardhat.config.js - 配置文件包含 Solidity 版本和部署设置 现在使用任何代码编辑器打开项目文件夹我喜欢使用 VSCode。 您会注意到通过Hardhat示例项目工具已经自动生成了许多文件。我们将会替换所有这些文件从Lock.sol合约开始。 将合约文件重命名为 BuyMeACoffee.sol 用以下代码替换合约代码 //SPDX-License-Identifier: Unlicense// contracts/BuyMeACoffee.sol
pragma solidity ^0.8.9;// Switch this to your own contract address once deployed, for bookkeeping!
// Example Contract Address on Goerli: 0xDBa03676a2fBb6711CB652beF5B7416A53c1421Dcontract BuyMeACoffee {// Event to emit when a Memo is created.event NewMemo(address indexed from,uint256 timestamp,string name,string message);// Memo struct.struct Memo {address from;uint256 timestamp;string name;string message;}// Address of contract deployer. Marked payable so that// we can withdraw to this address later.address payable owner;// List of all memos received from coffee purchases.Memo[] memos;constructor() {// Store the address of the deployer as a payable address.// When we withdraw funds, well withdraw here.owner payable(msg.sender);}/*** dev fetches all stored memos*/function getMemos() public view returns (Memo[] memory) {return memos;}/*** dev buy a coffee for owner (sends an ETH tip and leaves a memo)* param _name name of the coffee purchaser* param _message a nice message from the purchaser*/function buyCoffee(string memory _name, string memory _message) public payable {// Must accept more than 0 ETH for a coffee.require(msg.value 0, cant buy coffee for free!);// Add the memo to storage!memos.push(Memo(msg.sender,block.timestamp,_name,_message));// Emit a NewMemo event with details about the memo.emit NewMemo(msg.sender,block.timestamp,_name,_message);}/*** dev send the entire balance stored in this contract to the owner*/function withdrawTips() public {require(owner.send(address(this).balance));}
}请花些时间阅读合同注释看看能不能了解目前的情况 以下是重点 当我们部署合同时 constructor将负责部署的钱包地址保存在 owner变量中作为可付款地址。这对于以后我们想要提取合同收集的任何小费非常有用。 buyCoffee函数是合同上最重要的函数。它接受两个字符串 _name和 _message同时也接受以太币由于 payable修饰符。它使用 _name和 _message输入创建一个在区块链上存储的 Memo结构体。 当访客调用 buyCoffee函数时他们必须提交一些以太币由于 require(msg.value 0)语句。以太币随后将被保留在合同 balance中直到提取。 memos数组存储所有从咖啡购买中生成的 Memo结构体。 NewMemo日志事件在每次购买咖啡时发出。这使我们能够从我们的前端网站上监听新的咖啡购买。 withdrawTips是任何人都可以调用的函数但只会发送资金到合同的最初部署者。 address(this).balance获取存储在合同上的以太币 owner.send(...)是创建带有以太币的发送交易的语法 包裹所有内容的 require(...)语句是为了确保如果出现任何问题交易将被回滚不会丢失任何东西 这就是我们得到 require(owner.send(address(this).balance))的方式 拥有这个智能合同代码我们现在可以编写一个脚本来测试我们的逻辑 创建一个buy-coffee.js脚本来测试你的合约 在scripts文件夹下应该已经有一个已经填好的示例脚本deploy.js。 让我们将该文件重命名为buy-coffee.js并粘贴以下代码 const hre require(hardhat);// Returns the Ether balance of a given address.
async function getBalance(address) {const balanceBigInt await hre.ethers.provider.getBalance(address);return hre.ethers.utils.formatEther(balanceBigInt);
}// Logs the Ether balances for a list of addresses.
async function printBalances(addresses) {let idx 0;for (const address of addresses) {console.log(Address ${idx} balance: , await getBalance(address));idx;}
}// Logs the memos stored on-chain from coffee purchases.
async function printMemos(memos) {for (const memo of memos) {const timestamp memo.timestamp;const tipper memo.name;const tipperAddress memo.from;const message memo.message;console.log(At ${timestamp}, ${tipper} (${tipperAddress}) said: ${message});}
}async function main() {// Get the example accounts well be working with.const [owner, tipper, tipper2, tipper3] await hre.ethers.getSigners();// We get the contract to deploy.const BuyMeACoffee await hre.ethers.getContractFactory(BuyMeACoffee);const buyMeACoffee await BuyMeACoffee.deploy();// Deploy the contract.await buyMeACoffee.deployed();console.log(BuyMeACoffee deployed to:, buyMeACoffee.address);// Check balances before the coffee purchase.const addresses [owner.address, tipper.address, buyMeACoffee.address];console.log( start );await printBalances(addresses);// Buy the owner a few coffees.const tip { value: hre.ethers.utils.parseEther(0.01) };await buyMeACoffee.connect(tipper).buyCoffee(Carolina, Youre the best!, tip);await buyMeACoffee.connect(tipper2).buyCoffee(Vitto, Amazing teacher, tip);await buyMeACoffee.connect(tipper3).buyCoffee(Kay, I love my Proof of Knowledge, tip);// Check balances after the coffee purchase.console.log( bought coffee );await printBalances(addresses);// Withdraw.await buyMeACoffee.connect(owner).withdrawTips();// Check balances after withdrawal.console.log( withdrawTips );await printBalances(addresses);// Check out the memos.console.log( memos );const memos await buyMeACoffee.getMemos();printMemos(memos);
}// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().then(() process.exit(0)).catch((error) {console.error(error);process.exit(1);});此时您的项目目录应该长这样 请随意花几分钟阅读脚本代码。在顶部定义了一些实用程序函数以方便执行诸如获取钱包余额并将其打印出来等操作。 脚本的主要逻辑在 main() 函数中。注释的代码显示了脚本的流程 获取我们将使用的示例帐户。 获取要部署的合约。 部署合约。 在购买咖啡之前检查余额。 给所有者买几杯咖啡。 在购买咖啡之后检查余额。 提款。 撤回后检查余额。 查看备忘录。 这个脚本测试了我们在智能合约中实现的所有功能太棒了。 您还可以注意到我们正在进行有趣的调用例如 hre.waffle.provider.getBalance hre.ethers.getContractFactory hre.ethers.utils.parseEther 等等。 这些代码行是我们利用 Hardhat (hre) 开发环境以及 Ethers 和 Waffle SDK 插件的功能来访问读取区块链钱包账户余额、部署合约和格式化 Ether 加密货币值等功能。 在本教程中我们不会过于深入地讨论这些代码但您可以通过查阅 Hardhat 和 Ethers.js 文档来了解更多信息。 说了这么多现在是时候玩乐了让我们运行脚本 npx hardhat run scripts/buy-coffee.js 你应该在终端看到类似于这样的输出 (base) ➜ BuyMeACoffee-contracts git:(main) ✗ npx hardhat run scripts/buy-coffee.jsCompiled 1 Solidity file successfullyBuyMeACoffee deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 start Address 0 balance: 9999.99857170375Address 1 balance: 10000.0Address 2 balance: 0.0 bought coffee Address 0 balance: 9999.99857170375Address 1 balance: 9999.989752217303447058Address 2 balance: 0.03 withdrawTips Address 0 balance: 10000.028525789500231956Address 1 balance: 9999.989752217303447058Address 2 balance: 0.0 memos At 1684043147, Carolina (0x70997970C51812dc3A010C7d01b50e0d17dc79C8) said: Youre the best!At 1684043148, Vitto (0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC) said: Amazing teacherAt 1684043149, Kay (0x90F79bf6EB2c4f870365E785982E1f101E93b906) said: I love my Proof of Knowledge 在脚本开始之初即在部署合约后请注意“0”地址有9999.99877086625个ETH。这是因为它作为一种预填充的hardhat地址之一开始时有10k个ETH但它必须花费少量ETH来部署到本地区块链。 在第二步“bought coffee”中地址1购买了一杯咖啡。其他两个未显示的钱包也购买了咖啡。总共购买了3杯咖啡小费总额为0.03个ETH。您可以看到地址2代表合约地址持有0.03个ETH。 在“withdrawTips”中调用“withdrawTips”函数后合约回到0个ETH并且原始的部署者即地址0现在已经赚了一些钱持有10000.028525789500231956ETH。 我们开心吗你能想象一下你即将赚到的小费吗我可以。 现在让我们实现一个孤立的部署脚本以保持真正的部署简单同时准备好部署到Goerli测试网络 使用Alchemy和MetaMask将您的BuyMeACoffe.sol智能合约部署到以太坊Goerli测试网 让我们创建一个新文件scripts/deploy.js非常简单只是为了将我们的合约部署到我们稍后选择的任何网络上如果您还没有注意到我们将选择Goerli。 deploy.js文件应如下所示 // scripts/deploy.jsconst hre require(hardhat);async function main() { // We get the contract to deploy. const BuyMeACoffee await hre.ethers.getContractFactory(BuyMeACoffee); const buyMeACoffee await BuyMeACoffee.deploy(); await buyMeACoffee.deployed(); console.log(BuyMeACoffee deployed to:, buyMeACoffee.address);}// We recommend this pattern to be able to use async/await everywhere// and properly handle errors.main() .then(() process.exit(0)) .catch((error) { console.error(error); process.exit(1); }); 为了审查项目结构我们现在有一个智能合约和两个Hardhat脚本 现在有了这个编码并保存的deploy.js脚本如果你运行以下命令 npx hardhat run scripts/deploy.js 你将会看到一行被打印出来 BuyMeACoffee deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 有趣的是如果您一遍又一遍地运行它每次都会看到完全相同的部署地址 (base) ➜ BuyMeACoffee-contracts git:(main) ✗ npx hardhat run scripts/deploy.jsBuyMeACoffee deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3(base) ➜ BuyMeACoffee-contracts git:(main) ✗ npx hardhat run scripts/deploy.jsBuyMeACoffee deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3(base) ➜ BuyMeACoffee-contracts git:(main) ✗ npx hardhat run scripts/deploy.jsBuyMeACoffee deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 为什么呢这是因为当你运行脚本时Hardhat工具默认使用本地开发网络直接在你的电脑上运行。它快速而确定性高非常适合快速进行一些基本检查。 然而为了实际部署到运行在全球各地节点上的测试网络我们需要更改我们的Hardhat配置文件以给我们提供这个选项。 这就是hardhat.config.json文件的作用。 在我们深入研究之前快速提醒一句 配置很难保护好你的秘密 有很多小细节可能出错而且事情总是在变化。最危险的是秘密值例如你的MetaMask私钥和Alchemy URL。 如果你遇到问题请查看Ethereum StackExchange、Alchemy Discord或者谷歌你的错误信息。 而且永远不要分享你的秘密你的密钥你的硬币 当您打开您的hardhat.config.js文件时您会看到一些示例部署代码。删除它并粘贴此版本 // hardhat.config.jsrequire(nomiclabs/hardhat-ethers);require(nomiclabs/hardhat-waffle);require(dotenv).config();// You need to export an object to set up your config// Go to https://hardhat.org/config/ to learn moreconst GOERLI_URL process.env.GOERLI_URL;const PRIVATE_KEY process.env.PRIVATE_KEY;/** * type import(hardhat/config).HardhatUserConfig */module.exports { solidity: 0.8.18, networks: { goerli: { url: GOERLI_URL, accounts: [PRIVATE_KEY], }, },}; 这里发生了一些事情: 在配置文件的顶部导入 hardhat-ethers、 hardhat-waffle和 dotenv我们的整个Hardhat项目都可以访问这些依赖项。 我知道我们还没有介绍 dotenv这是一个重要的工具我们稍后会谈到它。 process.env.GOERLI_URL和 process.env.PRIVATE_KEY是我们可以访问环境变量以在配置文件中使用而不暴露秘密值的方法。 在 modules.exports内部我们使用Solidity编译器版本 0.8.18。不同的编译器版本支持不同的功能和语法集因此匹配此版本与我们的 BuyMeACoffee.sol智能合约顶部的 pragma声明非常重要。 如果您返回到该文件您可以交叉检查语句 pragma solidity ^0.8.9;。在这种情况下即使数字不完全匹配也可以因为符号 ^表示任何大于或等于 0.8.9的版本都可以使用。 还在 modules.exports中我们定义了一个包含一个名为 goerli的测试网络配置的 networks设置。现在在我们进行部署之前我们需要确保安装最后一个工具即 dotenv模块。正如它的名字所示 dotenv帮助我们将 .env文件连接到我们项目的其余部分。让我们设置它。 安装 dotenv: npm install dotenv 创建.env文件 touch .env 将需要的变量填入 .env 文件中 GOERLI_URLhttps://eth-goerli.alchemyapi.io/v2/your api keyGOERLI_API_KEYyour api keyPRIVATE_KEYyour metamask api key 你会注意到我没有泄漏任何我的机密。是的。安全第一。你可以把它放在那个文件里只要你也有一个 .gitignore 来确保你不会意外地将该文件推送到版本控制。确保 .env 在你的 .gitignore 中列出。 node_modules.envcoveragecoverage.jsontypechaintypechain-types# Hardhat filescacheartifacts 此外为了获取所需的环境变量您可以使用以下资源 GOERLI_URL - 在 Alchemy上注册账户创建一个 Ethereum - Goerli 应用程序并使用 HTTP URL GOERLI_API_KEY - 从您相同的 Alchemy Ethereum Goerli 应用程序中您可以获取 URL 的最后一部分那将是您的 API KEY PRIVATE_KEY - 按照 MetaMask 的这些 说明导出您的私钥。 现在已经安装了 dotenv并在您的 .env 文件中填写了内容我们几乎准备好将其部署到 Goerli 测试网 我们需要做的最后一件事是确保您拥有一些 Goerli ETH。这是一种虚假以太币使您能够在 Goerli 测试网络上练习进行各种操作这是构建以太坊应用程序的实践区域。这样您就不必在以太坊主网上花费真钱。 请前往 https://www.goerlifaucet.com 并使用您的 Alchemy 账户登录以获取一些免费的测试以太币。 现在我们可以开始部署 运行部署脚本这次添加一个特殊标志来使用 Goerli 网络 npx hardhat run scripts/deploy.js --network goerli 如果你在这里遇到任何错误例如 Error HH8我强烈建议你在 Google、Stack Overflow 或 Ethereum Stackexchange 上搜索解决方案。当你的 hardhat.config.js、.env 或你的 dotenv 模块设置不正确时遇到这些问题是很常见的。 如果一切顺利几秒钟后你应该能够在控制台看到你的合约地址: BuyMeACoffee deployed to: 0xbDde17D0BEA683db1bDa89f26c5c8C786230525E 恭喜 您现在已经在Goerli测试网上部署了合约。您可以通过在此处粘贴您的地址来查看它https://goerli.etherscan.io/ 在我们继续本教程的前端网站(dapp)部分之前让我们准备一个我们稍后需要使用的脚本withdraw.js脚本。 实现一个withdraw脚本 稍后当我们发布我们的网站时我们需要一种方式来收集我们的朋友和粉丝留给我们的所有精彩小费。我们可以编写另一个hardhat脚本来实现这个目的 在scripts/withdraw.js中创建一个文件。 // scripts/withdraw.jsconst hre require(hardhat);
const abi require(../artifacts/contracts/BuyMeACoffee.sol/BuyMeACoffee.json);async function getBalance(provider, address) {const balanceBigInt await provider.getBalance(address);return hre.ethers.utils.formatEther(balanceBigInt);
}async function main() {// Get the contract that has been deployed to Goerli.const contractAddress 0xbDde17D0BEA683db1bDa89f26c5c8C786230525E;const contractABI abi.abi;// Get the node connection and wallet connection.const provider new hre.ethers.providers.AlchemyProvider(goerli,process.env.GOERLI_API_KEY);// Ensure that signer is the SAME address as the original contract deployer,// or else this script will fail with an error.const signer new hre.ethers.Wallet(process.env.PRIVATE_KEY, provider);// Instantiate connected contract.const buyMeACoffee new hre.ethers.Contract(contractAddress,contractABI,signer);// Check starting balances.console.log(current balance of owner: ,await getBalance(provider, signer.address),ETH);const contractBalance await getBalance(provider, buyMeACoffee.address);console.log(current balance of contract: ,await getBalance(provider, buyMeACoffee.address),ETH);// Withdraw funds if there are funds to withdraw.if (contractBalance ! 0.0) {console.log(withdrawing funds..);const withdrawTxn await buyMeACoffee.withdrawTips();await withdrawTxn.wait();} else {console.log(no funds to withdraw!);}// Check ending balance.console.log(current balance of owner: ,await getBalance(provider, signer.address),ETH);
}// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().then(() process.exit(0)).catch((error) {console.error(error);process.exit(1);});您的项目结构应该如下所示 这个脚本最重要的部分是当我们调用 withdrawTips() 函数时从合约余额中取出资金并发送到所有者的钱包中 // Withdraw funds if there are funds to withdraw.if (contractBalance ! 0.0) {console.log(withdrawing funds..)const withdrawTxn await buyMeACoffee.withdrawTips();await withdrawTxn.wait();}如果合约中没有资金我们会避免尝试提取以避免不必要地支付燃气费用。 运行脚本时您将看到如下输出 (base) ➜ BuyMeACoffee-contracts git:(main) ✗ npx hardhat run scripts/withdraw.jscurrent balance of owner: 3.164940181128555531 ETHcurrent balance of contract: 0.0 ETHno funds to withdraw!current balance of owner: 3.164940181128555531 ETH 请注意这次我们没有添加-network goerli标志这是因为我们的脚本直接在逻辑中硬编码网络配置 const provider new hre.ethers.providers.AlchemyProvider( goerli, process.env.GOERLI_API_KEY); 太好了现在我们有一种方法来提取合同的小费 让我们进入这个项目的 dapp 部分这样我们就可以与所有朋友分享我们的小费页面 :) 使用 Replit 和 Ethers.js 构建前端的 Buy Me A Coffee 网站 dapp 为了保持简洁和清晰我们将使用一个快速启动演示项目的神奇工具称为 Replit IDE。 访问我的示例项目然后分叉它以创建您自己的副本以进行修改https://replit.com/thatguyintech/BuyMeACoffee-Solidity-DeFi-Tipping-app https://files.readme.io/c0057db-Fork_repl.png 您还可以在此查看完整的网站代码https://github.com/alchemyplatform/RTW3-Week2-BuyMeACoffee-Website 在fork repl之后您会被带到一个IDE页面您可以 查看一个 Next.js Web应用程序的代码 获得访问控制台、终端和README.md文件的预览的权限 查看您dapp的热重新加载版本 它应该看起来像这样 https://files.readme.io/517c1cf-albert.png 这个教程的这个部分将会快速而有趣——我们将更新一些变量使其连接到我们在项目早期部署的智能合约并且在网站上显示您自己的名字 首先让我们将所有东西连接并使其正常工作然后我会向您解释每个部分的内容。 这里是我们需要进行的更改 更新 pages/index.js 中的 contractAddress 在 pages/index.js 中更新名称字符串为您自己的名称 确保 utils/BuyMeACoffee.json 中的合约ABI与您的合约匹配 在 pages/index.js 中更新 contractAddress 您可以看到 contractAddress 变量已经填充了一个地址。这是一个我部署的示例合约您可以使用它但是如果您这样做...所有发送到您的网站的小费都将发送到我的地址 :) 您可以通过从我们之前部署 BuyMeACoffee.sol 智能合约时粘贴您的地址来解决此问题。 https://files.readme.io/9f1ee86-buya.sol.png 在pages/index.js中更新名称字符串为您自己的名字 现在这个网站上到处都是我的名字。查找所有使用“Albert”的地方并将其替换为您的名字/匿名资料/ENS域或者您希望人们称呼您的任何内容。 您可以使用“cmd F”或“ctrl F”查找所有实例以进行替换。 https://files.readme.io/d03249f-theGuy.png 确保utils/BuyMeACoffee.json中的合同ABI匹配 这也是一个关键的检查点特别是当您稍后对智能合约进行更改在本教程之后时。 ABI是应用程序二进制接口它只是一种让我们的前端代码知道可以在智能合约上调用哪些函数的花哨方法。 ABI在智能合约编译时生成在json文件中。您可以在智能合约文件夹中的路径artifacts/contracts/BuyMeACoffee.sol/BuyMeACoffee.json找到它。 每当您更改您的智能合约代码并重新部署时您的ABI也会更改。将其复制并粘贴到Replit文件中utils/BuyMeACoffee.json https://files.readme.io/1aaabe1-utils.png 如果应用程序尚未运行您可以转到 shell 并使用“npm run dev”启动本地服务器以测试您的更改。该网站应在几秒钟内加载 https://files.readme.io/9ea1320-connect_wallet.png Replit的精妙之处在于一旦你的网站建好你可以回到你的个人资料找到Replit项目链接然后将其发送给朋友让他们访问你的小费页面。 现在让我们来逐步浏览一下网站和代码。你已经可以从上面的截图看出当你第一次访问Dapp时它会检查你是否已安装了MetaMask并且你的钱包是否已连接到该网站。第一次访问时你将无法连接所以会出现一个按钮要求你“连接你的钱包”。 当你点击“连接你的钱包”后MetaMask的窗口会弹出询问你是否要通过签署消息确认连接。这个消息签署不需要任何燃气费或成本。 一旦签名完成网站将确认你的连接你将能够看到咖啡表单以及其他访问者留下的任何以前的备忘录。 https://files.readme.io/ae9a697-momo.png 砰就是这样这就是整个项目。请花一秒钟时间为自己鼓掌并回顾一下你走过的旅程。 总结一下 我们使用 Hardhat 和 Ethers.js 编写、测试和部署了一个自定义的 Solidity 智能合约。 我们使用 Alchemy 和 MetaMask 将智能合约部署到 Goerli 测试网络。 我们实现了一个提款脚本以便我们能够享受我们的劳动成果。 我们使用 Ethers.js 来加载合约 ABI将一个使用 Next.js、React 和 Replit 构建的前端网站连接到智能合约上。 这是很多的工作 本文由 mdnice 多平台发布 文章转载自: http://www.morning.skcmt.cn.gov.cn.skcmt.cn http://www.morning.tqklh.cn.gov.cn.tqklh.cn http://www.morning.slqzb.cn.gov.cn.slqzb.cn http://www.morning.snktp.cn.gov.cn.snktp.cn http://www.morning.jxgyg.cn.gov.cn.jxgyg.cn http://www.morning.qnsmk.cn.gov.cn.qnsmk.cn http://www.morning.jqmqf.cn.gov.cn.jqmqf.cn http://www.morning.xqkcs.cn.gov.cn.xqkcs.cn http://www.morning.gjcdr.cn.gov.cn.gjcdr.cn http://www.morning.lmhh.cn.gov.cn.lmhh.cn http://www.morning.zlbjx.cn.gov.cn.zlbjx.cn http://www.morning.pjrgb.cn.gov.cn.pjrgb.cn http://www.morning.paoers.com.gov.cn.paoers.com http://www.morning.hwcln.cn.gov.cn.hwcln.cn http://www.morning.reababy.com.gov.cn.reababy.com http://www.morning.wkrkb.cn.gov.cn.wkrkb.cn http://www.morning.cwzzr.cn.gov.cn.cwzzr.cn http://www.morning.wmmtl.cn.gov.cn.wmmtl.cn http://www.morning.gczqt.cn.gov.cn.gczqt.cn http://www.morning.rhpgk.cn.gov.cn.rhpgk.cn http://www.morning.pflry.cn.gov.cn.pflry.cn http://www.morning.pmdlk.cn.gov.cn.pmdlk.cn http://www.morning.pmdzd.cn.gov.cn.pmdzd.cn http://www.morning.zqmdn.cn.gov.cn.zqmdn.cn http://www.morning.cylbs.cn.gov.cn.cylbs.cn http://www.morning.kpbgp.cn.gov.cn.kpbgp.cn http://www.morning.yzdth.cn.gov.cn.yzdth.cn http://www.morning.qbrdg.cn.gov.cn.qbrdg.cn http://www.morning.nrzbq.cn.gov.cn.nrzbq.cn http://www.morning.flxqm.cn.gov.cn.flxqm.cn http://www.morning.gnjtg.cn.gov.cn.gnjtg.cn http://www.morning.kxymr.cn.gov.cn.kxymr.cn http://www.morning.pynzj.cn.gov.cn.pynzj.cn http://www.morning.lkbyj.cn.gov.cn.lkbyj.cn http://www.morning.pndw.cn.gov.cn.pndw.cn http://www.morning.51meihou.cn.gov.cn.51meihou.cn http://www.morning.xhddb.cn.gov.cn.xhddb.cn http://www.morning.nzms.cn.gov.cn.nzms.cn http://www.morning.kzcfp.cn.gov.cn.kzcfp.cn http://www.morning.zcyxq.cn.gov.cn.zcyxq.cn http://www.morning.tsnwf.cn.gov.cn.tsnwf.cn http://www.morning.ljqd.cn.gov.cn.ljqd.cn http://www.morning.nrmyj.cn.gov.cn.nrmyj.cn http://www.morning.yqrfn.cn.gov.cn.yqrfn.cn http://www.morning.lgtzd.cn.gov.cn.lgtzd.cn http://www.morning.nfpkx.cn.gov.cn.nfpkx.cn http://www.morning.rklgm.cn.gov.cn.rklgm.cn http://www.morning.kfclh.cn.gov.cn.kfclh.cn http://www.morning.yxbdl.cn.gov.cn.yxbdl.cn http://www.morning.wplbs.cn.gov.cn.wplbs.cn http://www.morning.qywfw.cn.gov.cn.qywfw.cn http://www.morning.rzpkt.cn.gov.cn.rzpkt.cn http://www.morning.rmkyb.cn.gov.cn.rmkyb.cn http://www.morning.mhnrx.cn.gov.cn.mhnrx.cn http://www.morning.wttzp.cn.gov.cn.wttzp.cn http://www.morning.ysbhj.cn.gov.cn.ysbhj.cn http://www.morning.rwjtf.cn.gov.cn.rwjtf.cn http://www.morning.zdfrg.cn.gov.cn.zdfrg.cn http://www.morning.krlsz.cn.gov.cn.krlsz.cn http://www.morning.ypbp.cn.gov.cn.ypbp.cn http://www.morning.jpnw.cn.gov.cn.jpnw.cn http://www.morning.cmldr.cn.gov.cn.cmldr.cn http://www.morning.mrpqg.cn.gov.cn.mrpqg.cn http://www.morning.dybth.cn.gov.cn.dybth.cn http://www.morning.rrgqq.cn.gov.cn.rrgqq.cn http://www.morning.kpgbz.cn.gov.cn.kpgbz.cn http://www.morning.cfqyx.cn.gov.cn.cfqyx.cn http://www.morning.csdgt.cn.gov.cn.csdgt.cn http://www.morning.cpmwg.cn.gov.cn.cpmwg.cn http://www.morning.pzlhq.cn.gov.cn.pzlhq.cn http://www.morning.zxqyd.cn.gov.cn.zxqyd.cn http://www.morning.rxpp.cn.gov.cn.rxpp.cn http://www.morning.hlnrj.cn.gov.cn.hlnrj.cn http://www.morning.dgxrz.cn.gov.cn.dgxrz.cn http://www.morning.ykyfq.cn.gov.cn.ykyfq.cn http://www.morning.hfrbt.cn.gov.cn.hfrbt.cn http://www.morning.hnzrl.cn.gov.cn.hnzrl.cn http://www.morning.dtrzw.cn.gov.cn.dtrzw.cn http://www.morning.rgrdd.cn.gov.cn.rgrdd.cn http://www.morning.sbjbs.cn.gov.cn.sbjbs.cn