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

文章目录

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

内容简介

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

设计逻辑

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

ERC20TokenLoanPlatform 合约

事件

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

// SPDX-License-Identifier: MITpragma 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."); // 取款代币数不能为0uint 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.");// 贷款不能小于0require(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() publicreturns (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 代币合约,初始化代币合约信息。
图片[1] - 基于ERC20代币协议实现的去中心化应用平台 - MaxSSL
部署 ERC20TokenLoanPlatform 合约,初始化代币实现地址、贷款年利率5和存款年利率2。
图片[2] - 基于ERC20代币协议实现的去中心化应用平台 - MaxSSL
首先需要给自己的账户铸造 200 个代币用于功能测试,
图片[3] - 基于ERC20代币协议实现的去中心化应用平台 - MaxSSL
再给 ERC20TokenLoanPlatform 合约地址铸造一定数量的代币和授权代币转账权限,保证平台功能的正常运行。
图片[4] - 基于ERC20代币协议实现的去中心化应用平台 - MaxSSL
图片[5] - 基于ERC20代币协议实现的去中心化应用平台 - MaxSSL

存款和取款

调用 deposit 函数存款 100 个代币,
图片[6] - 基于ERC20代币协议实现的去中心化应用平台 - MaxSSL
balanceInquiry 函数查看余额变化,这里已经显示自己的余额为刚才存入的100。
图片[7] - 基于ERC20代币协议实现的去中心化应用平台 - MaxSSL
调用 withdrawal 函数取出指定数量的代币,不能超出自己的余额。平台会自动进行存款利息计算。
图片[8] - 基于ERC20代币协议实现的去中心化应用平台 - MaxSSL
balanceInquiry 函数查看余额变化,这里已经显示自己的余额还剩下50。
图片[9] - 基于ERC20代币协议实现的去中心化应用平台 - MaxSSL

贷款和还款

调用 createLoan 函数输入自己需要贷多少代币。在这里注意账户的资产需要有贷款数的20%才有资格贷款。成功后拿到此次贷款的id值 1703236890。
图片[10] - 基于ERC20代币协议实现的去中心化应用平台 - MaxSSL
调用 payLoan 函数输入贷款的 id 值进行还款,可以先还一部分也可以一次性还完,平台会自动进行贷款利息计算。

图片[11] - 基于ERC20代币协议实现的去中心化应用平台 - MaxSSL
调用 loanInquiry 函数输入贷款的 id 值进行待还款的查询。
图片[12] - 基于ERC20代币协议实现的去中心化应用平台 - MaxSSL

源码地址

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


© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享