基于ERC20代币协议实现的去中心化应用平台

2023-12-22 18:44

本文主要是介绍基于ERC20代币协议实现的去中心化应用平台,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 内容简介
  • 设计逻辑
  • ERC20TokenLoanPlatform 合约
    • 事件
    • 结构体
    • 状态变量
    • 函数
  • Remix 运行实现
    • 部署相关智能合约
    • 存款和取款
    • 贷款和还款
  • 源码地址

内容简介

使用 solidity 实现的基于 ERC20 代币协议的借贷款去中心化应用平台(极简版)。实现存款、取款、贷款、还款以及利息计算的功能。

设计逻辑

  • 平台提供ERC20协议代币的相关存取和利息计算工作。部署智能合约时初始化贷款和存款的年利率、代币实现地址。
  • 用户可以将手中的代币存入平台,等到一定的期限再次拿出获得本金加利息。也可以向平台申请代币,在一定的期限之后自主还款即可。

ERC20TokenLoanPlatform 合约

事件

合约包含4个事件,包括 Deposit 存款、Withdrawal 取款、CreateLoan 贷款、PayLoan 还款。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;import "erc-token-standard/ERC/IERC20.sol"; // 基于ERC20代币协议的借贷款平台 
contract ERC20TokenLoanPlatform {event Deposit(address depositor, uint amount ,uint DepositTime); event Withdrawal(address payee, uint amount, uint WithdrawalTime); event CreateLoan(address loanAddress, uint amount, uint interest, uint CreateLoanTime); event PayLoan(address loanAddress, uint amount, bool total, uint PayLoanTime); 

结构体

合约包含2个结构体, 包括 Client 客户信息、Loan 贷款信息。

	// 客户信息 struct Client {uint amount;uint depositTime; uint withdrawalTime;}// 贷款信息struct Loan {address loanAddress; uint amount;uint interest; }

状态变量

本合约使用了6个状态变量,其中有 clients 客户信息映射、loans 贷款信息映射、annualInterestRate 贷款年利率、annualDepositRate 存款年利率、tokenAddress 代币实现地址、erc20Token 代币对象。

	mapping(address => Client) private clients; mapping (uint => Loan) private loans;uint public annualInterestRate;        // 贷款年利率,如5%uint public annualDepositRate;         // 存款年利率,如2%address public tokenAddress;           // ERC20代币地址 IERC20 erc20Token; 

函数

本合约包含了8个基本函数,其中包括构造函数、deposit 存款、withdrawal 取款、createLoan 贷款、payLoan 还款、loanInquiry 待还款查询、depositInquiry 账户余额查询、balanceInquiry 客户信息查询 。

	// 构造函数constructor(address _tokenAddress, uint _initLoanInterest, uint _initDepositInterest) {tokenAddress = _tokenAddress;           // 初始化代币地址 erc20Token = IERC20(tokenAddress);      // 声明IERC20接口合约变量annualInterestRate = _initLoanInterest; annualDepositRate = _initDepositInterest;   }// 存款 function deposit(uint _amount) public {require(_amount > 0, "Amount is less than or equal to 0.");      // 存款代币数不能为0     require(erc20Token.balanceOf(msg.sender) >= _amount, "Number of tokens is insufficient.");            // 检查持有代币数是否大于等于存款代币数require(erc20Token.allowances(msg.sender, address(this)) >= _amount, "Not enough approvals.");        // 检查是否有足够的授权 erc20Token.transferFrom(msg.sender, address(this), _amount);             clients[msg.sender].amount += _amount;                      // 增加存款if (clients[msg.sender].depositTime == 0){clients[msg.sender].depositTime = block.timestamp;      // 当前的存款时间 }emit Deposit(msg.sender,_amount ,block.timestamp); }// 取款 function withdrawal(uint _amount) public {require(_amount > 0, "Amount is less than or equal to 0.");               // 取款代币数不能为0  uint timestamp = block.timestamp;   depositInquiry();                 // 计算本金 + 利息2% require(clients[msg.sender].amount >= _amount, "Insufficient balance.");         // 检查存款代币数是否大于等于取款代币数 require(erc20Token.balanceOf(address(this)) >= _amount, "Platform bankruptcy."); // 检查平台的代币数是否满足取款 erc20Token.transfer(msg.sender, _amount);            clients[msg.sender].amount -= _amount; clients[msg.sender].withdrawalTime = timestamp; emit Withdrawal(msg.sender, _amount, timestamp);}// 贷款function createLoan(uint _amount) public returns (uint){require(_amount > 0, "Amount is less than or equal to 0.");            // 贷款不能小于0        require(erc20Token.balanceOf(address(this))*10/100 >= _amount, "Exceeding the platform loan limit.");        // 超过平台总存款的10%require(erc20Token.balanceOf(msg.sender) + clients[msg.sender].amount >= _amount*20/100, "Invalid loan.");   // 账户资产数需有贷款的20%erc20Token.transfer(msg.sender, _amount); uint timestamp = block.timestamp;           // 以当前块的时间戳为贷款id值 uint interest = _amount * annualInterestRate / 100;     // 计算利率 loans[timestamp].loanAddress = msg.sender; loans[timestamp].amount = _amount; loans[timestamp].interest = interest;     // 计算利率 emit CreateLoan(msg.sender, _amount, interest, timestamp);return timestamp; }// 还款function payLoan(uint _amount, uint _loanId) public {require(_amount > 0, "Amount is less than or equal to 0.");        // 还款需大于0require(erc20Token.balanceOf(msg.sender) >= _amount, "Number of tokens is insufficient.");            // 检查持有代币数是否大于等于存款代币数require(erc20Token.allowances(msg.sender, address(this)) >= _amount, "Not enough approvals.");        // 检查是否有足够的授权 uint total = loanInquiry(_loanId);        // 计算代还款 bool fullPayment = false; // 还一部分或一次性还 if (total <= _amount) {     erc20Token.transferFrom(msg.sender, address(this), total);       // 一次性还完delete loans[_loanId];                                           // 删除贷款记录  fullPayment = true; } else {    erc20Token.transferFrom(msg.sender, address(this), _amount);        // 还了一部分 _amount loans[_loanId].amount -= _amount;                                   // 重写贷款记录 }emit PayLoan(msg.sender, _amount, fullPayment, block.timestamp);}// 待还款查询function loanInquiry(uint _loanId) public returns (uint) {require(loans[_loanId].amount != 0, "Invalid loan id.");require(loans[_loanId].loanAddress == msg.sender, "Non-personal enquiry.");// 计算需要还款的代币数: 本金 + 利息uint timestamp = block.timestamp; uint diffDays = ( timestamp - _loanId) / 86400;                 // 时间戳转换为天数 uint total = loans[_loanId].amount + loans[_loanId].interest*diffDays/365;      // 总计还款数 loans[_loanId].amount = total;            //重写用户贷款数 return total; }// 余额+利息的计算function depositInquiry() public  returns (uint){uint principal = clients[msg.sender].amount;    // 本金uint diffDays = (block.timestamp - clients[msg.sender].depositTime) / 86400;                 // 时间戳转换为天数 uint interest = principal * annualDepositRate / 100 * diffDays / 365;uint total = principal + interest;clients[msg.sender].amount = total;return total;}// 客户信息查询 function balanceInquiry() public returns (address, uint, uint, uint){depositInquiry();                 // 计算本金 + 利息2% uint balance = clients[msg.sender].amount;uint depositTime = clients[msg.sender].depositTime;uint withdrawalTime = clients[msg.sender].withdrawalTime;return (msg.sender, balance, depositTime, withdrawalTime);}
}

Remix 运行实现

部署相关智能合约

solidity实现ERC20代币标准。
先部署 ERC20 代币合约,初始化代币合约信息。
在这里插入图片描述
部署 ERC20TokenLoanPlatform 合约,初始化代币实现地址、贷款年利率5和存款年利率2。
在这里插入图片描述
首先需要给自己的账户铸造 200 个代币用于功能测试,
在这里插入图片描述
再给 ERC20TokenLoanPlatform 合约地址铸造一定数量的代币和授权代币转账权限,保证平台功能的正常运行。
在这里插入图片描述
在这里插入图片描述

存款和取款

调用 deposit 函数存款 100 个代币,
在这里插入图片描述
balanceInquiry 函数查看余额变化,这里已经显示自己的余额为刚才存入的100。
在这里插入图片描述
调用 withdrawal 函数取出指定数量的代币,不能超出自己的余额。平台会自动进行存款利息计算。
在这里插入图片描述
balanceInquiry 函数查看余额变化,这里已经显示自己的余额还剩下50。
在这里插入图片描述

贷款和还款

调用 createLoan 函数输入自己需要贷多少代币。在这里注意账户的资产需要有贷款数的20%才有资格贷款。成功后拿到此次贷款的id值 1703236890。
在这里插入图片描述
调用 payLoan 函数输入贷款的 id 值进行还款,可以先还一部分也可以一次性还完,平台会自动进行贷款利息计算。

在这里插入图片描述
调用 loanInquiry 函数输入贷款的 id 值进行待还款的查询。
在这里插入图片描述

源码地址

本文只是简单介绍,具体实现看代码。gitee 开源地址。


这篇关于基于ERC20代币协议实现的去中心化应用平台的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/525047

相关文章

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

通过SSH隧道实现通过远程服务器上外网

搭建隧道 autossh -M 0 -f -D 1080 -C -N user1@remotehost##验证隧道是否生效,查看1080端口是否启动netstat -tuln | grep 1080## 测试ssh 隧道是否生效curl -x socks5h://127.0.0.1:1080 -I http://www.github.com 将autossh 设置为服务,隧道开机启动

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测 目录 时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测基本介绍程序设计参考资料 基本介绍 MATLAB实现LSTM时间序列未来多步预测-递归预测。LSTM是一种含有LSTM区块(blocks)或其他的一种类神经网络,文献或其他资料中LSTM区块可能被描述成智能网络单元,因为

亮相WOT全球技术创新大会,揭秘火山引擎边缘容器技术在泛CDN场景的应用与实践

2024年6月21日-22日,51CTO“WOT全球技术创新大会2024”在北京举办。火山引擎边缘计算架构师李志明受邀参与,以“边缘容器技术在泛CDN场景的应用和实践”为主题,与多位行业资深专家,共同探讨泛CDN行业技术架构以及云原生与边缘计算的发展和展望。 火山引擎边缘计算架构师李志明表示:为更好地解决传统泛CDN类业务运行中的问题,火山引擎边缘容器团队参考行业做法,结合实践经验,打造火山

vue项目集成CanvasEditor实现Word在线编辑器

CanvasEditor实现Word在线编辑器 官网文档:https://hufe.club/canvas-editor-docs/guide/schema.html 源码地址:https://github.com/Hufe921/canvas-editor 前提声明: 由于CanvasEditor目前不支持vue、react 等框架开箱即用版,所以需要我们去Git下载源码,拿到其中两个主

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

springboot家政服务管理平台 LW +PPT+源码+讲解

3系统的可行性研究及需求分析 3.1可行性研究 3.1.1技术可行性分析 经过大学四年的学习,已经掌握了JAVA、Mysql数据库等方面的编程技巧和方法,对于这些技术该有的软硬件配置也是齐全的,能够满足开发的需要。 本家政服务管理平台采用的是Mysql作为数据库,可以绝对地保证用户数据的安全;可以与Mysql数据库进行无缝连接。 所以,家政服务管理平台在技术上是可以实施的。 3.1

基于Springboot + vue 的抗疫物质管理系统的设计与实现

目录 📚 前言 📑摘要 📑系统流程 📚 系统架构设计 📚 数据库设计 📚 系统功能的具体实现    💬 系统登录注册 系统登录 登录界面   用户添加  💬 抗疫列表展示模块     区域信息管理 添加物资详情 抗疫物资列表展示 抗疫物资申请 抗疫物资审核 ✒️ 源码实现 💖 源码获取 😁 联系方式 📚 前言 📑博客主页:

自制的浏览器主页,可以是最简单的桌面应用,可以把它当成备忘录桌面应用

自制的浏览器主页,可以是最简单的桌面应用,可以把它当成备忘录桌面应用。如果你看不懂,请留言。 完整代码: <!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><ti

探索蓝牙协议的奥秘:用ESP32实现高质量蓝牙音频传输

蓝牙(Bluetooth)是一种短距离无线通信技术,广泛应用于各种电子设备之间的数据传输。自1994年由爱立信公司首次提出以来,蓝牙技术已经经历了多个版本的更新和改进。本文将详细介绍蓝牙协议,并通过一个具体的项目——使用ESP32实现蓝牙音频传输,来展示蓝牙协议的实际应用及其优点。 蓝牙协议概述 蓝牙协议栈 蓝牙协议栈是蓝牙技术的核心,定义了蓝牙设备之间如何进行通信。蓝牙协议