十念 发表于 2022-8-9 14:45:05

library Checkpoints:Transform openzeppelin

使用时间戳替换区块号,check数字支持uint256。
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

library Checkpoints {
        struct data{
      uint32 fromTime;
      uint256 quantity;
        }

    struct Checkpoint {
                mapping (address => mapping (uint32 => data)) checkpoints;
                mapping (address => uint32) numCheckpoints;
    }

    // --------------checkpoint-----------
        function _getCurrentQuantity(Checkpoint storage checkpoint,address account) internal view returns (uint256) {
      uint32 nCheckpoints = checkpoint.numCheckpoints;
      return nCheckpoints > 0 ? checkpoint.checkpoints.quantity : 0;
    }

        function getCurrentQuantity(Checkpoint storage checkpoint,address account) external view returns (uint256) {
      return _getCurrentQuantity(checkpoint,account);
    }

    function getPriorQuantity(Checkpoint storage checkpoint,address account, uint blockTimestamp) external view returns (uint256) {
      return _getPriorQuantity(checkpoint,account,blockTimestamp);
    }

    function _getPriorQuantity(Checkpoint storage checkpoint,address account, uint blockTimestamp) internal view returns (uint256) {
      require(blockTimestamp < block.timestamp, "ShipSell::getPriorQuantity: not yet determined");

      uint32 nCheckpoints = checkpoint.numCheckpoints;
      if (nCheckpoints == 0) {
            return 0;
      }

      // First check most recent balance
      if (checkpoint.checkpoints.fromTime <= blockTimestamp) {
            return checkpoint.checkpoints.quantity;
      }

      // Next check implicit zero balance
      if (checkpoint.checkpoints.fromTime > blockTimestamp) {
            return 0;
      }

      uint32 lower = 0;
      uint32 upper = nCheckpoints - 1;
      while (upper > lower) {
            uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
            data memory cp = checkpoint.checkpoints;
            if (cp.fromTime == blockTimestamp) {
                return cp.quantity;
            } else if (cp.fromTime < blockTimestamp) {
                lower = center;
            } else {
                upper = center - 1;
            }
      }
      return checkpoint.checkpoints.quantity;
    }

    function _writeCheckpoint(Checkpoint storage checkpoint,address account, uint256 newQuantity) internal {
      uint32 blockTimestamp = uint32(block.timestamp);
      uint32 nCheckpoints = checkpoint.numCheckpoints;

      if (nCheckpoints > 0 && checkpoint.checkpoints.fromTime == blockTimestamp) {
          checkpoint.checkpoints.quantity = newQuantity;
      } else {
          checkpoint.checkpoints = data(blockTimestamp, newQuantity);
          checkpoint.numCheckpoints = nCheckpoints + 1;
      }
    }

    function WriteCheckpoint(Checkpoint storage checkpoint,address account, uint256 newQuantity) external {
      _writeCheckpoint(checkpoint,account,newQuantity);
    }
}mock:
// SPDX-License-Identifier: MIT

pragma solidity 0.8.7;

import "./Checkpoints.sol";

contract CheckpointsMock{
    using Checkpoints for Checkpoints.Checkpoint;
    Checkpoints.Checkpoint example;

    function write(uint256 amount)external{
      uint256 current = Checkpoints.getCurrentQuantity(example,msg.sender);
      Checkpoints.WriteCheckpoint(example,msg.sender,current+amount);
    }

    function readCurrent()public view returns (uint256){
      return Checkpoints.getCurrentQuantity(example,msg.sender);
    }

    function readPrior(uint256 fromTime)public view returns (uint256){
      return Checkpoints.getPriorQuantity(example,msg.sender,fromTime);
    }
}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: library Checkpoints:Transform openzeppelin