solidity的高阶语法4

1.提款模式

提款模式确保不会造成安全威胁的直接转接呼叫。 以下合约显示了使用转账调用发送以太币的不安全方式。

复制代码
pragma solidity ^0.5.0;

contract Test {
   address payable public richest;
   uint public mostSent;

   constructor() public payable {
      richest = msg.sender;
      mostSent = msg.value;
   }
   function becomeRichest() public payable returns (bool) {
      if (msg.value > mostSent) {
         // Insecure practice
         richest.transfer(msg.value);
         richest = msg.sender;
         mostSent = msg.value;
         return true;
      } else {
         return false;
      }
   }
}
 

通过使最富有的合约成为后备功能失败的合约,可以使上述合约处于不可用状态。 当后备函数失败时,becomeRichest()函数也会失败,合约将永远卡住。 为了缓解这个问题,我们可以使用 Withdrawal Pattern。

在提款模式中,我们会在每次转账前重置待处理金额。 它将确保只有调用者合约失败。

复制代码
pragma solidity ^0.5.0;

contract Test {
   address public richest;
   uint public mostSent;

   mapping (address => uint) pendingWithdrawals;

   constructor() public payable {
      richest = msg.sender;
      mostSent = msg.value;
   }
   function becomeRichest() public payable returns (bool) {
      if (msg.value > mostSent) {
         pendingWithdrawals[richest] += msg.value;
         richest = msg.sender;
         mostSent = msg.value;
         return true;
      } else {
         return false;
      }
   }
   function withdraw() public {
      uint amount = pendingWithdrawals[msg.sender];
      pendingWithdrawals[msg.sender] = 0;
      msg.sender.transfer(amount);
   }
}
 

2.限制访问

限制访问合同是一种常见做法。 默认情况下,合约状态是只读的,除非将其指定为公共状态。

我们可以限制谁可以修改合约的状态或使用修饰符调用合约的函数。 我们将创建并使用多个修饰符,如下所述 −

  • onlyBy − 一旦用于函数,则只有提到的调用者可以调用该函数。

  • onlyAfter − 一旦用于函数,则可以在一定时间段后调用该函数。

  • costs − 一旦用于函数,则仅当提供特定值时调用者才能调用该函数。

示例

复制代码
pragma solidity ^0.5.0;

contract Test {
   address public owner = msg.sender;
   uint public creationTime = now;

   modifier onlyBy(address _account) {
      require(
         msg.sender == _account,
         "Sender not authorized."
      );
      _;
   }
   function changeOwner(address _newOwner) public onlyBy(owner) {
      owner = _newOwner;
   }
   modifier onlyAfter(uint _time) {
      require(
         now >= _time,
         "Function called too early."
      );
      _;
   }
   function disown() public onlyBy(owner) onlyAfter(creationTime + 6 weeks) {
      delete owner;
   }
   modifier costs(uint _amount) {
      require(
         msg.value >= _amount,
         "Not enough Ether provided."
      );
      _;
      if (msg.value > _amount)
         msg.sender.transfer(msg.value - _amount);
   }
   function forceOwnerChange(address _newOwner) public payable costs(200 ether) {
      owner = _newOwner;
      if (uint(owner) & 0 == 1) return;        
   }
}
 
相关推荐
小码闭眼ctrv5 小时前
ENS 问题
区块链
Web3_Daisy7 小时前
克隆代币 + 捆绑开盘:多链环境下的低成本发币玩法
人工智能·web3·区块链·比特币
11年老程序猿在线搬砖7 小时前
DAPP智能合约系统:技术解析与实现指南
区块链·智能合约·dapp
大白猴7 小时前
【GMX v1实战】时序风险结算与资本成本:深度解析 GMX 永续合约的资金费率机制
区块链·智能合约·solidity·永续合约·gmx·资金费率·去中心化交易所
openHiTLS密码开源社区10 小时前
LMS 算法:抗量子时代的「安全签名工具」
物联网·区块链·量子计算·加密货币·lms·xmss·后量子密码
清 晨13 小时前
Web3:去中心化网络指南
web3·去中心化·区块链·facebook·tiktok·instagram·clonbrowser
Sui_Network15 小时前
GraphQL RPC 与通用索引器公测介绍:为 Sui 带来更强大的数据层
javascript·人工智能·后端·rpc·去中心化·区块链·graphql
moz与京1 天前
【面试向】热门技术话题(上)
人工智能·物联网·机器学习·面试·web3·区块链·元宇宙
熊文豪2 天前
【华为OD】区块链文件转储系统
算法·华为od·区块链