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;        
   }
}
 
相关推荐
2301_7760452313 小时前
理解Layer 1区块链协议
区块链
幻智星科技1 天前
零知识证明三大核心特性解析
区块链·零知识证明
木西1 天前
AI 驱动的去中心化资产管理:QuantixAI 核心金库与智能风控架构解析
web3·智能合约·solidity
2301_776045232 天前
山寨币与比特币之间的关系
大数据·人工智能·区块链
JF_Ma2 天前
1000个量化策略第29例:经典红利低波策略
区块链
AlanAshley2 天前
实时湖仓与区块链:数据架构的信任革命
架构·区块链
代码方舟3 天前
零信任架构实战:基于天远企业法人四要素高级版构建自动化电子印章授权与签约准入网关
人工智能·架构·自动化·区块链
AIFQuant4 天前
Python期货行情API接入:股指、黄金、原油多品种数据管道实战
开发语言·python·金融·区块链·量化开发
北冥you鱼4 天前
区块链供应链金融如何降低中小企业融资成本
网络·金融·区块链
2601_962885725 天前
2026 Python 股票数据接口选型指南(横评 + 决策树)
开发语言·python·区块链