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

百度收录网站名字最好免费观看高清播放

百度收录网站名字,最好免费观看高清播放,想学管理方面的培训班,新手怎么做自媒体项目介绍 在这个项目中,我们建立一个小型智能合约应用,他允许用户向合约地址捐赠,允许合约所有者从合约中提取余额;并且还设定了捐赠的金额门槛;针对直接对地址进行的捐赠行为,我们也予以记录 源代码 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/a/612690.html

相关文章:

  • 服装网站建设网网站建设方式优化
  • 外贸展示型模板网站破解asp网站后台地址
  • 上海刚刚宣布新郑网站优化
  • 成都优化网站建设长沙中建设计院网站
  • 资阳网站建设方案nanopi neo做网站
  • 东莞建设网站推广公司地址深圳企业网站制作设计方案
  • 深圳专业营销网站公司网站新闻模板
  • 惠州+网站建设公司物联网app开发平台
  • 中英文网站开发费用wordpress 显示微信
  • 做视频网站如何利用用户的弱点少儿编程是智商税吗
  • 个人网站的建设与管理mit网站可以做app
  • 网站建设个人网上银行公众号文章排版编辑器
  • 网站打开加速淘宝发布网站建设
  • 三星单片机开发网站我们高清中国免费观看
  • 多域名指向同一网站网站界面设计有哪些
  • 域名换了网站需要备案么专做和田玉的网站
  • 怎样做好网站运营武昌网站建设价格多少钱
  • 企业网站建设 租用服务器哪些网站的网站怎么做的
  • 海南网站优化公司软件技术好找工作吗
  • 深圳本地招聘网站建设企业网站对公
  • 景安企业网站建设温州营销网站制作费用
  • 宝山手机网站制作公司在一个网站的各虚拟目录中默认文档的文件名要相同
  • 如何在网站上做用工登记百度电话人工服务
  • 烟台做网站联系电话创意设计说明范文
  • 天津市建设工程信息网站一起做网店17广州沙河
  • 荣成信用建设官方网站做网站需要硬件设施
  • 网站设计应该怎么做网站建设建站流程方案
  • 博客是哪个软件合肥网站推广优化
  • 绍兴网站建设方案报价以前老网站
  • 重庆教育建设有限公司网站小米路由器3做网站