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

【Solidity】代币

ERC20

ERC-20 全称 “Ethereum Request for Comment 20”,是一种标准接口,用于实现代币合约。ERC20 标准定义了一组函数和事件,使得代币可以在不同的应用和平台之间互操作。

ERC20 标准接口定义了一组必须实现的函数和事件:

interface IERC20 {// 返回代币的总供应量function totalSupply() external view returns (uint);// 返回指定地址的代币余额function balanceOf(address account) external view returns (uint);// 返回授权给 spender 的代币数量function allowance(address owner, address spender) external view returns (uint);// 将指定数量 amount 的代币从调用者的账户转移到另一个地址 recipientfunction transfer(address recipient, uint amount) external returns (bool);// 授权 spender 可以从调用者账户转移的代币数量 amountfunction approve(address spender, uint amount) external returns (bool);// 从 sender 账户转移指定数量的代币到 recipient, 需要预先通过 approve 授权function transferFrom(address sender,address recipient,uint amount) external returns (bool);
}
interface IERC20 {// 在代币转移时触发, 包括零值转移event Transfer(address indexed from, address indexed to, uint value);// 在调用 approve 时触发event Approval(address indexed owner, address indexed spender, uint value);
}

以下是一个简单的 ERC20 代币合约示例:

contract ERC20 is IERC20 {// 存储代币的名称、符号和小数位数string public name = "TestToken";string public symbol = "TTK";uint8 public decimals = 18;// 存储代币的总供应量uint public totalSupply;// 存储每个地址的代币余额; owner => balancemapping(address => uint) public balanceOf;// 存储每个地址对其他地址的授权额度; owner => spender => amountmapping(address => mapping(address => uint)) public allowance;// 定义两个事件, 用于记录代币转移和授权操作event Transfer(address indexed from, address indexed to, uint value);event Approval(address indexed owner,address indexed spender,uint value);// 将指定数量 amount 的代币从调用者的账户转移到另一个地址 recipientfunction transfer(address recipient,uint amount) external override returns (bool) {require(balanceOf[msg.sender] >= amount,"ERC20: transfer amount exceeds balance");balanceOf[msg.sender] -= amount;balanceOf[recipient] += amount;emit Transfer(msg.sender, recipient, amount);return true;}// 授权 spender 可以从调用者账户转移的代币数量 amountfunction approve(address spender,uint amount) external override returns (bool) {allowance[msg.sender][spender] = amount;emit Approval(msg.sender, spender, amount);return true;}// 从 sender 账户转移指定数量的代币到 recipient, 需要预先通过 approve 授权function transferFrom(address sender,address recipient,uint amount) external override returns (bool) {require(balanceOf[sender] >= amount,"ERC20: transfer amount exceeds balance");require(allowance[sender][msg.sender] >= amount,"ERC20: transfer amount exceeds allowance");balanceOf[sender] -= amount;balanceOf[recipient] += amount;allowance[sender][msg.sender] -= amount;emit Transfer(sender, recipient, amount);return true;}
}

使用 OpenZeppelin 库可以简化 ERC20 代币的实现。OpenZeppelin 提供了安全且经过审计的 ERC20 实现。

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";contract MyToken is ERC20 {constructor(string memory name,string memory symbol,uint256 initialSupply) ERC20(name, symbol) {_mint(msg.sender, initialSupply * 10 ** uint256(decimals()));}
}

除了上述核心方法,你可能还听过 mint & burn。它们通常用于 ERC20 代币合约中,以增加或减少代币的总供应量。

contract ERC20 is IERC20 {// ...// 创建 amount 数量的代币, 并将其分配给指定的地址function mint(uint amount) external {totalSupply += amount;balanceOf[msg.sender] += amount;emit Transfer(address(0), msg.sender, amount);}// 销毁 amount 数量的代币function burn(uint amount) external {require(balanceOf[msg.sender] >= amount,"ERC20: burn amount exceeds balance");totalSupply -= amount;balanceOf[msg.sender] -= amount;emit Transfer(msg.sender, address(0), amount);}
}



ERC721

ERC721 是以太坊上用于创建不可替代代币(NFT)的标准。与 ERC20 不同,ERC721 代币是独一无二的,每个代币都有自己的唯一标识符。

ERC721 标准定义了一组必须实现的函数和事件,使得代币可以在不同的应用和平台之间互操作。

interface IERC721 {// 返回某个地址拥有的代币数量function balanceOf(address owner) external view returns (uint256 balance);// 返回某个代币的所有者地址function ownerOf(uint256 tokenId) external view returns (address owner);// 安全地将代币从一个地址转移到另一个地址function safeTransferFrom(address from,address to,uint256 tokenId) external;// 将代币从一个地址转移到另一个地址function transferFrom(address from, address to, uint256 tokenId) external;// 批准某个地址可以转移指定的代币function approve(address to, uint256 tokenId) external;// 返回被批准可以转移指定代币的地址function getApproved(uint256 tokenId) external view returns (address operator);// 批准或撤销某个地址可以管理调用者所有的代币function setApprovalForAll(address operator, bool _approved) external;// 查询某个地址是否被批准可以管理另一个地址的所有代币function isApprovedForAll(address owner,address operator) external view returns (bool);
}
interface IERC721 {// 在代币转移时触发event Transfer(address indexed from,address indexed to,uint256 indexed tokenId);// 在调用 approve 时触发event Approval(address indexed owner,address indexed approved,uint256 indexed tokenId);// 在调用 setApprovalForAll 时触发event ApprovalForAll(address indexed owner,address indexed operator,bool approved);
}



WETH

WETH(Wrapped Ether)是以太坊(ETH)的包装版本,它遵循 ERC-20 代币标准。由于 ETH 本身并不符合 ERC-20 标准,因此在某些去中心化应用(DApp)和去中心化金融(DeFi)平台上使用时会有一些限制。WETH 的出现解决了这个问题,使 ETH 可以在这些平台上无缝使用。

contract WETH {// 代币名称、符号、小数位数string public name = "Wrapped Ether";string public symbol = "WETH";uint8 public decimals = 18;// 记录每个地址的 WETH 余额mapping(address => uint) public balanceOf;// 记录存入 ETH 的事件event Deposit(address indexed account, uint amount);// 记录提取 ETH 的事件event Withdrawal(address indexed account, uint amount);// 使合约可以接受 ETHreceive() external payable {deposit();}// 接受 ETH 并将其转换为 WETHfunction deposit() public payable {balanceOf[msg.sender] += msg.value;emit Deposit(msg.sender, msg.value);}// 将 WETH 转换回 ETH 并提取到调用者的地址function withdraw(uint amount) public {require(balanceOf[msg.sender] >= amount, "Insufficient balance");balanceOf[msg.sender] -= amount;payable(msg.sender).transfer(amount);emit Withdrawal(msg.sender, amount);}// 返回合约中存储的 ETH 总量function totalSupply() public view returns (uint) {return address(this).balance;}
}

我们可以直接使用 OpenZeppelin 的 ERC20 合约库来实现 WETH 合约:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;import "@openzeppelin/contracts/token/ERC20/ERC20.sol";contract WETH is ERC20 {// 记录存入 ETH 的事件event Deposit(address indexed account, uint amount);// 记录提取 ETH 的事件event Withdrawal(address indexed account, uint amount);// 初始化 WETH 合约constructor() ERC20("Wrapped Ether", "WETH") {}// 使合约可以接受 ETHreceive() external payable {deposit();}// 接受 ETH 并将其转换为 WETHfunction deposit() public payable {_mint(msg.sender, msg.value);emit Deposit(msg.sender, msg.value);}// 将 WETH 转换回 ETH 并提取到调用者的地址function withdraw(uint amount) public {_burn(msg.sender, amount);payable(msg.sender).transfer(amount);emit Withdrawal(msg.sender, amount);}
}
  1. 部署 WETH 合约

  2. 调用 WETH 合约的 deposit 函数,设置传入的 ETH 数量,这里以 1 ETH 为例

  3. 调用 WETH 合约继承的 balanceOf 函数,传入部署 WETH 合约的地址,查看 WETH 余额

  4. 调用 WETH 合约继承的 totalSupply 函数,查看合约中存储的 ETH 总量

  5. 调用 WETH 合约的 withdraw 函数,传入提取的 WETH 数量,提取 ETH

  6. 调用 WETH 合约继承的 balanceOf 函数,查看 WETH 余额

  7. 调用 WETH 合约继承的 totalSupply 函数,查看合约中存储的 ETH 总量



相关文章:

【Solidity】代币

ERC20 ERC-20 全称 “Ethereum Request for Comment 20”,是一种标准接口,用于实现代币合约。ERC20 标准定义了一组函数和事件,使得代币可以在不同的应用和平台之间互操作。 ERC20 标准接口定义了一组必须实现的函数和事件: in…...

5 - Linux YUM仓库及NFS共享服务

目录 一、YUM概述 1.YUM简介 2.软件仓库的提供方式 3.RPM软件包的来源 4. yum 命令的运用 二、搭建ftp YUM仓库 三、NFS共享服务 1.NFS简述 2.模拟NFS 一、YUM概述 1.YUM简介 YUM(Yellow dog Updater Modified)是一个专门为了解决包的依赖关系…...

上传文件,文件类型限制语法,各种媒体视频文件的Content-Type

各种媒体视频文件的Content-Type “application/x-apple-diskimage”: “DMG”, “application/epubzip”: “EPUB”, “application/java-archive”: “JAR”, “video/x-matroska”: “MKV”, “text/html”: “HTML|HTM”, “text/css”: “CSS”, “text/javascript…...

类和对象(下)(2)

类和对象(下)(2) static成员 • ⽤static修饰的成员变量,称之为静态成员变量,静态成员变量⼀定要在类外进⾏初始化。 • 静态成员变量为当前类的所有对象所共享,不属于某个具体的对象,不存在对象中&#…...

软件测试 - 自动化测试(概念)(Java)(自动化测试分类、web自动化测试、驱动、selenium自动化测试工具的安装)

一、自动化的概念 ⾃动洒⽔机,主要通上⽔就可以⾃动化洒⽔并且可以⾃动的旋转。 ⾃动洗⼿液,免去了⼿动挤压可以⾃动感应出洗⼿液 超市⾃动闸⻔,不需要⼿动的开⻔关⻔ ⽣活中的⾃动化案例有效的减少了⼈⼒的消耗,同时也提⾼了⽣…...

wpf datagrid 实现双向绑定

前台 <DataGridAutoGenerateColumns"False"Background"White"CanUserAddRows"True"Grid.Row"1"RowEditEnding"DataGrid_OnRowEditEnding"RowHeight"60"SelectionUnit"CellOrRowHeader"x:Name"…...

使用循环在el-select下拉框中循环出-3至50

问: 使用循环在el-select下拉框中循环出-3至50 回答: <el-form-itemprop"adPosition"label"广告位置":rules"{required: true, message: 广告位置不能为空, trigger: change}" ><el-select v-model"addDataForm.adPosition"…...

全球海事航行通告解析辅助决策系统

“全球海事航行通告解析辅助决策系统”是一个针对海事行业设计的智能系统&#xff0c;旨在帮助海上导航和航运操作人员解析和应对全球发布的海事航行通告。 要做这样的系统我们必须要了解海事签派员的日常工作。 海事签派员&#xff0c;也称为船舶操作员或船运调度员&#xff0…...

Spring 解决bean的循环依赖

Spring循环依赖-博客园 1. 什么是循环依赖 2. 循环依赖能引发什么问题 循环依赖可能引发以下问题&#xff1a; 初始化顺序不确定&#xff1a;循环依赖导致无法确定哪个对象应该先被创建和初始化&#xff0c;从而造成初始化顺序的混乱。这可能导致错误的结果或意外的行为。死…...

鸿蒙内核源码分析(ELF格式篇) | 应用程序入口并不是main

阅读之前的说明 先说明&#xff0c;本篇很长&#xff0c;也很枯燥&#xff0c;若不是绝对的技术偏执狂是看不下去的.将通过一段简单代码去跟踪编译成ELF格式后的内容.看看ELF究竟长了怎样的一副花花肠子&#xff0c;用readelf命令去窥视ELF的全貌&#xff0c;最后用objdump命令…...

seq2seq编码器encoder和解码器decoder详解

编码器 在序列到序列模型中&#xff0c;编码器将输入序列&#xff08;如一个句子&#xff09;转换为一个隐藏状态序列&#xff0c;供解码器生成输出。编码层通常由嵌入层和RNN&#xff08;如GRU/LSTM)等组成 Token:是模型处理文本时的基本单元&#xff0c;可以是词,子词,字符…...

前端使用 Konva 实现可视化设计器(21)- 绘制图形(椭圆)

本章开始补充一些基础的图形绘制&#xff0c;比如绘制&#xff1a;直线、曲线、圆/椭形、矩形。这一章主要分享一下本示例是如何开始绘制一个图形的&#xff0c;并以绘制圆/椭形为实现目标。 请大家动动小手&#xff0c;给我一个免费的 Star 吧~ 大家如果发现了 Bug&#xff0c…...

Python 将单词拆分为单个字母组成的列表对象

Python 将单词拆分为单个字母组成的列表对象 正文 正文 这里介绍一个简单算法&#xff0c;将英文单词拆分为其对应字母组成的列表。 str1 ACG lst1 [i for i in str1] lst2 list(str1)# Method 1 print(lst1) # Method 2 print(lst2) """ result: [A, C, G…...

欧洲 摩纳哥税务知识

摩纳哥是一个位于法国南部的城邦国家&#xff0c;以其豪华的生活环境和宽松的税收政策而闻名。自1869年以来&#xff0c;摩纳哥取消了个人所得税的征收&#xff0c;这使得它成为富裕人士和外籍人士的理想居住地。然而&#xff0c;这并不意味着摩纳哥的税收制度完全不存在。以下…...

域控制器的四大支柱分别是车载以太网、自适应Autosar

域控制器的四大支柱分别是车载以太网、自适应Autosar、高性能处理器和集中式E/E架构。 百度安全验证 。自适应Autosar采用Proxy/Skeleton的通信架构&#xff0c;同时采用中间件SOME/IP...

写给大数据开发:如何优化临时数据查询流程

你是否曾因为频繁的临时数据查询请求而感到烦恼&#xff1f;这些看似简单的任务是否正在蚕食你的宝贵时间&#xff0c;影响你的主要工作&#xff1f;如果是&#xff0c;那么这篇文章正是为你而写。 目录 引言&#xff1a;数据开发者的困境问题剖析&#xff1a;临时数据查询的…...

【MongoDB】Java连接MongoDB

连接URI 连接 URI提供驱动程序用于连接到 MongoDB 部署的指令集。该指令集指示驱动程序应如何连接到 MongoDB&#xff0c;以及在连接时应如何运行。下图解释了示例连接 URI 的各个部分&#xff1a; 连接的URI 主要分为 以下四个部分 第一部分 连接协议 示例中使用的 连接到具有…...

nginx支持的不同事件驱动模型

Nginx 支持的不同事件驱动模型 Nginx 是一款高性能的 Web 和反向代理服务器&#xff0c;它支持多种事件驱动模型来处理网络 I/O 操作。不同的操作系统及其版本支持不同的事件驱动模型&#xff0c;这些模型对于 Nginx 的并发处理能力和性能至关重要。下面详细介绍 Nginx 支持的…...

C++ TinyWebServer项目总结(7. Linux服务器程序规范)

进程 PID 进程的PID&#xff08;Process ID&#xff09;是操作系统中用于唯一标识一个进程的整数值。每个进程在创建时&#xff0c;操作系统都会分配一个唯一的PID&#xff0c;用来区分不同的进程。 PID的特点 唯一性&#xff1a; 在操作系统运行的某一时刻&#xff0c;每个…...

基于STM32单片机设计的秒表时钟计时器仿真系统——程序源码proteus仿真图设计文档演示视频等(文末工程资料下载)

基于STM32单片机设计的秒表时钟计时器仿真系统 演示视频 基于STM32单片机设计的秒表时钟计时器仿真系统 摘要 本设计基于STM32单片机&#xff0c;设计并实现了一个秒表时钟计时器仿真系统。系统通过显示器实时显示当前时间&#xff0c;并通过定时器实现秒表计时功能。显示小时…...

人才流失预测项目

在本项目中&#xff0c;通过数据科学和AI的方法&#xff0c;分析挖掘人力资源流失问题&#xff0c;并基于机器学习构建解决问题的方法&#xff0c;并且&#xff0c;我们通过对AI模型的反向解释&#xff0c;可以深入理解导致人员流失的主要因素&#xff0c;HR部门也可以根据分析…...

BUG——imx6u开发_结构体导致的死机问题(未解决)

简介&#xff1a; 最近在做imx6u的linux下裸机驱动开发&#xff0c;由于是学习的初级阶段&#xff0c;既没有现成的IDE可以使用&#xff0c;也没有GDB等在线调试工具&#xff0c;只能把代码烧写在SD卡上再反复插拔&#xff0c;仅靠卑微的亮灯来判断程序死在哪一步。 至于没有使…...

问答:什么是对称密钥、非对称密钥,http怎样变成https的?

文章目录 对称密钥 vs 非对称密钥HTTP 变成 HTTPS 的过程 对称密钥 vs 非对称密钥 1. 对称密钥加密 定义: 对称密钥加密是一种加密算法&#xff0c;其中加密和解密使用的是同一个密钥。特点: 速度快: 因为只使用一个密钥&#xff0c;所以加密和解密速度较快。密钥分发问题: 双…...

虚拟滚动列表组件ReVirtualList

虚拟滚动列表组件ReVirtualList 组件实现基于 Vue3 Element Plus Typescript&#xff0c;同时引用 vueUse lodash-es tailwindCss (不影响功能&#xff0c;可忽略) 在 ReList 的基础上&#xff0c;增加虚拟列表功能&#xff0c;在固定高度的基础上&#xff0c;可以优化大数…...

稳定、耐用、美观 一探究竟六角头螺钉螺栓如何选择

在机器与技术未被发现的过去&#xff0c;紧固件设计和品质并不稳定。但是&#xff0c;他们已成为当今许多行业无处不在的构成部分。六角头标准件或六角头标准件是紧固件中持续的头部设计之一&#xff0c;它有六个面&#xff0c;对广泛工业应用大有益处。六角头标准件或常分成六…...

数据库Mybatis基础操作

目录 基础操作 删除 预编译SQL 增、改、查 自动封装 基础操作 环境准备 删除 根据主键动态删除数据&#xff1a;使用了mybatis中的参数占位符#{ }&#xff0c;里面是传进去的参数。 单元测试&#xff1a; 另外&#xff0c;这个方法是有返回值的&#xff0c;返回这次操作…...

人物形象设计:塑造独特角色的指南

引言 人物形象设计是一种创意过程&#xff0c;它利用强大的设计工具&#xff0c;通过视觉和叙述元素塑造角色的外在特征和内在性格。这种设计不仅赋予角色以生命&#xff0c;还帮助观众或读者在心理层面上与角色建立联系。人物形象设计的重要性在于它能够增强故事的吸引力和说…...

网络安全-安全策略初认识

文章目录 前言理论介绍1. 安全策略1.1 定义&#xff1a;1.2 关键术语&#xff1a; 2. 防火墙状态监测 实战步骤1&#xff1a;实验环境搭建步骤2&#xff1a;配置实现 总结1. 默认安全策略2. 自定义安全策略3. 防火墙状态会话表 前言 who&#xff1a;本文主要写给入门防火墙的技…...

python import相对导入与绝对导入

文章目录 相对导入与绝对导入绝对导入相对导入何时使用相对导入何时使用绝对导入示例 相对导入与绝对导入 在Python中&#xff0c;from .file_manager import SomeFunction 和 from file_manager import SomeFunction 两种导入方式看似相似&#xff0c;但在模块寻找机制上存在…...

深入理解 Go 语言原子内存操作

原子内存操作提供了实现其他同步原语所需的低级基础。一般来说,你可以用互斥体和通道替换并发算法的所有原子操作。然而,它们是有趣且有时令人困惑的结构,应该深入了解它们是如何工作的。如果你能够谨慎地使用它们,那么它们完全可以成为代码优化的好工具,而不会增加复杂性…...

同一个ip的网站做链接有用/一个平台怎么推广

随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,校园跑腿系统被用户普遍使用,为方便用户能够可以随时进行校园跑腿系统的数据信息管理,特开发了基于校园跑腿系统的管理系统。…...

专做童车批发的网站/互联网销售怎么做

利用 curl 和 pycurl 需要 curl 和 libcurl 的版本高于 7.18.0&#xff0c;并且事先建立好可的代理&#xff0c;例如用 SSH 建立 SOCKS5 代理&#xff1a; [ nobody www ~] $ sshusername omehost.com -CN-f-D127.0.0.1:1080curl 使用方法 [ nobody www ~] $ curl http:// tw…...

做国外网站用什么颜色/潍坊网站seo

网上各种的说法&#xff0c;不外乎这么几种 第一种简单的说呢就是这样的&#xff1a; 第一步&#xff1a;客户机提出域名解析请求,并将该请求发送给本地的域名服务器。 第二步&#xff1a;当本地的域名服务器收到请求后,就先查询本地的缓存,如果有该纪录项,则本地的域名服务器…...

宁海县建设局网站下属单位/公司网站怎么建立

这是我2021年的第13篇原创文章&#xff0c;原汁原味的技术之路尽在Jerrycodes什么是内存泄漏Key 的泄漏Value 的泄漏如何避免内存泄露什么是内存泄漏内存泄漏指的是&#xff0c;当某一个对象不再有用的时候&#xff0c;占用的内存却不能被回收&#xff0c;这就叫作内存泄漏。因…...

域名空间商界面/做网络优化的公司排名

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 电工&#xff08;高级&#xff09;考试技巧参考答案及电工&#xff08;高级&#xff09;考试试题解析是安全生产模拟考试一点通题库老师及电工&#xff08;高级&#xff09;操作证已考过的学员汇总&#xff0c;相对有…...

网站建设与维护 电子版/产品运营方案

转自&#xff1a;blog.leanote.com/post/afanti.denggmail.com/b5f4f526490b ROI Align 是在Mask-RCNN这篇论文里提出的一种区域特征聚集方式, 很好地解决了ROI Pooling操作中两次量化造成的区域不匹配(mis-alignment)的问题。实验显示&#xff0c;在检测测任务中将 ROI Poolin…...