当前位置: 首页 > wzjs >正文

旅游景点介绍网页制作网站怎么优化自己免费

旅游景点介绍网页制作,网站怎么优化自己免费,Wordpress虚拟资源交易idown,做彩票交流网站犯法吗项目介绍 在这个项目中,我们建立一个小型智能合约应用,他允许用户向合约地址捐赠,允许合约所有者从合约中提取余额;并且还设定了捐赠的金额门槛;针对直接对地址进行的捐赠行为,我们也予以记录 源代码 ht…

项目介绍

在这个项目中,我们建立一个小型智能合约应用,他允许用户向合约地址捐赠,允许合约所有者从合约中提取余额;并且还设定了捐赠的金额门槛;针对直接对地址进行的捐赠行为,我们也予以记录

源代码

https://github.com/PatrickAlphaC/fund-me-fcc


代码分析

PriceConverter.sol
✅ 函数 1:getPrice()
我们先创建一个价格转化器,这里我们先引入clainlink的包。然后,创建一个 getPrice()函数,他可以通过chainlink获取到真实世界的eth的价格,调用 Chainlink 的 latestRoundData() 方法,从中提取价格 answer(ETH/USD,单位通常是8位小数),代码如下:

(, int256 answer, , , ) = priceFeed.latestRoundData();

为了与以太坊中的 18 位小数精度统一,这里乘以 1e10(即 10^10),因为原始数据是 8 位精度(即 1 ETH = 1234.56789000 USD),我们希望它变成 18 位精度(1234.567890000000000000 USD),代码如下:

return uint256(answer * 10000000000);

✅ 函数 2:getConversionRate(uint256 ethAmount)
根据传入的 ETH 数量(单位为 Wei),返回对应的 USD 金额(同样以 18 位精度表示)。
调用上面那个函数,得到当前 ETH 的价格(单位为 USD,18 位小数)。

uint256 ethPrice = getPrice();

下面一步是核心:

  • ethPrice 是每 1 ETH 的价格(18 位精度)
  • ethAmount 是传入的 ETH 数量(单位是 Wei,18 位精度)
  • 乘积是 36 位小数
  • 除以 1e18,得到结果回到 18 位精度的美元数值
uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1e18;

完整代码如下:

pragma solidity ^0.8.8;import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";library PriceConverter {// We could make this public, but then we'd have to deploy it// We can get eht price with this functionfunction getPrice() internal view returns (uint256) {// Sepolia ETH / USD Address// https://docs.chain.link/data-feeds/price-feeds/addresses#Sepolia%20TestnetAggregatorV3Interface priceFeed = AggregatorV3Interface(0x694AA1769357215DE4FAC081bf1f309aDC325306);(, int256 answer, , , ) = priceFeed.latestRoundData();// ETH/USD rate in 18 digitreturn uint256(answer * 10000000000);// or (Both will do the same thing)// return uint256(answer * 1e10); // 1* 10 ** 10 == 10000000000}// 1000000000function getConversionRate(uint256 ethAmount)internalviewreturns (uint256){uint256 ethPrice = getPrice();uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1000000000000000000;// or (Both will do the same thing)// uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1e18; // 1 * 10 ** 18 == 1000000000000000000// the actual ETH/USD conversion rate, after adjusting the extra 0s.return ethAmountInUsd;}
}

FundMe.sol
🧱 状态变量

mapping(address => uint256) public addressToAmountFunded;
address[] public funders;
address public /* immutable */ i_owner;
uint256 public constant MINIMUM_USD = 50 * 10 ** 18;

addressToAmountFunded:记录每个地址捐了多少 ETH。

  • funders:所有捐赠者的地址列表。

  • i_owner:部署合约的地址,是这个合约的管理员。 建议加上 immutable 关键字提高效率(只能在构造函数中赋值)。

  • MINIMUM_USD:捐款的最小限制,50 美元(以 18 位精度计算,单位 Wei)。

🚀 构造函数

constructor() {i_owner = msg.sender;
}

部署合约的人自动成为合约的拥有者。

💸 捐款函数 fund()

function fund() public payable {require(msg.value.getConversionRate() >= MINIMUM_USD, "You need to spend more ETH!");addressToAmountFunded[msg.sender] += msg.value;funders.push(msg.sender);
}
  • msg.value 是用户发送的 ETH 数量(单位为 Wei)
  • getConversionRate() 是库函数,转化为对应美元价值
  • 如果小于 MINIMUM_USD(即 50 美元),就 require 失败
  • 记录捐款金额,添加到地址映射中,追加到 funders 数组

🛡️ 只有管理员可调用的 modifier

modifier onlyOwner {if (msg.sender != i_owner) revert NotOwner();_;
}
  • 限制某些函数(比如 withdraw)只能由 i_owner 调用。
  • 使用 revert NotOwner() 自定义错误节省 gas。
  • _ 的含义是这个类修饰的函数接下来的代码逻辑

🏧 取款函数 withdraw()

    function withdraw() public onlyOwner {for (uint256 funderIndex=0; funderIndex < funders.length; funderIndex++){address funder = funders[funderIndex];addressToAmountFunded[funder] = 0;}funders = new address[](0);// // transfer// payable(msg.sender).transfer(address(this).balance);// // send// bool sendSuccess = payable(msg.sender).send(address(this).balance);// require(sendSuccess, "Send failed");// call(bool callSuccess, ) = payable(msg.sender).call{value: address(this).balance}("");require(callSuccess, "Call failed");}
  • 清空每个捐赠者在 mapping 里的记录
  • 重置 funders 数组
  • 将所有合约余额通过 .call{value:…}() 的方式发送给合约拥有者
  • 使用 call 而不是 transfer 或 send 是最佳实践(更灵活,处理 gas 限制更好)。

📥 fallback / receive 函数

fallback() external payable { fund(); }
receive() external payable { fund(); }
  • receive():处理空 msg.data 的 ETH 转账
  • fallback():处理非空 msg.data 的 ETH 转账
  • 它们都调用 fund(),意味着无论是直接转账还是调用错误函数名,都能正常执行捐赠逻辑

完整代码:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import "./PriceConverter.sol";error NotOwner();contract FundMe {using PriceConverter for uint256;mapping(address => uint256) public addressToAmountFunded;address[] public funders;// Could we make this constant?  /* hint: no! We should make it immutable! */address public /* immutable */ i_owner;uint256 public constant MINIMUM_USD = 50 * 10 ** 18;constructor() {i_owner = msg.sender;}function fund() public payable {require(msg.value.getConversionRate() >= MINIMUM_USD, "You need to spend more ETH!");// require(PriceConverter.getConversionRate(msg.value) >= MINIMUM_USD, "You need to spend more ETH!");addressToAmountFunded[msg.sender] += msg.value;funders.push(msg.sender);}function getVersion() public view returns (uint256){// ETH/USD price feed address of Sepolia Network.AggregatorV3Interface priceFeed = AggregatorV3Interface(0x694AA1769357215DE4FAC081bf1f309aDC325306);return priceFeed.version();}modifier onlyOwner {// require(msg.sender == owner);if (msg.sender != i_owner) revert NotOwner();_;}function withdraw() public onlyOwner {for (uint256 funderIndex=0; funderIndex < funders.length; funderIndex++){address funder = funders[funderIndex];addressToAmountFunded[funder] = 0;}funders = new address[](0);// // transfer// payable(msg.sender).transfer(address(this).balance);// // send// bool sendSuccess = payable(msg.sender).send(address(this).balance);// require(sendSuccess, "Send failed");// call(bool callSuccess, ) = payable(msg.sender).call{value: address(this).balance}("");require(callSuccess, "Call failed");}// Explainer from: https://solidity-by-example.org/fallback/// Ether is sent to contract//      is msg.data empty?//          /   \ //         yes  no//         /     \//    receive()?  fallback() //     /   \ //   yes   no//  /        \//receive()  fallback()fallback() external payable {fund();}receive() external payable {fund();}}

大家可以在 remix官网 上运行部署这两个合约,进行实战测试

http://www.dtcms.com/wzjs/284262.html

相关文章:

  • 网站改版工作方案福建百度推广开户
  • 外贸出口工艺品怎么做外贸网站怎样留别人电话在广告上
  • 中国建设部官方网站证件查询交换友情链接的意义是什么
  • 昆山移动网站建设今天合肥刚刚发生的重大新闻
  • 影视文化网站建设百度搜索资源平台官网
  • 上海网站建设官方网站视频seo优化教程
  • 政府采购网招标公告怎么下载aso优化方法
  • 义乌建设局网站打不开网络营销推广公司有哪些
  • appcms程序怎么做网站域名注册管理中心网站
  • 广州网站建设大公司排名阿里关键词排名查询
  • 怎么样网站吸引人自然搜索优化
  • 免费企业网站wordpress免费网站
  • 网站制作结构站长之家seo查询
  • 找人做的网站第二年多钱百度关键词排名查询
  • 日本有一个做青蛙模型的网站网站域名查询ip地址
  • 汕头seo推广优化重庆seo教程博客
  • h5网站开发定制关键词怎么选择技巧
  • 鞍山网站制作谁家好谷歌seo详细教学
  • 做网站价格注册网站流程
  • 网站开发所需能力建立网站平台需要多少钱
  • 设计网站建设seo优化网站教程百度
  • wordpress 建站 图床东莞网站建设推广平台
  • 90设计网站会员全站通与电商模板的区别营销策划公司主要做些什么
  • 策划案需要给做网站吗推广小程序拿佣金
  • 网站宣传页网站维护费用一般多少钱
  • 哪个网站可以做社工试题域名查询备案
  • 收录网站工具西安seo霸屏
  • 做游戏特效的网站百度快速排名软件
  • 基于ssh框架的网站开发流程太原网站快速排名提升
  • 深圳专业做网站电话推广普通话奋进新征程