使用时间戳替换区块号,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[account];
- return nCheckpoints > 0 ? checkpoint.checkpoints[account][nCheckpoints - 1].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[account];
- if (nCheckpoints == 0) {
- return 0;
- }
- // First check most recent balance
- if (checkpoint.checkpoints[account][nCheckpoints - 1].fromTime <= blockTimestamp) {
- return checkpoint.checkpoints[account][nCheckpoints - 1].quantity;
- }
- // Next check implicit zero balance
- if (checkpoint.checkpoints[account][0].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[account][center];
- if (cp.fromTime == blockTimestamp) {
- return cp.quantity;
- } else if (cp.fromTime < blockTimestamp) {
- lower = center;
- } else {
- upper = center - 1;
- }
- }
- return checkpoint.checkpoints[account][lower].quantity;
- }
- function _writeCheckpoint(Checkpoint storage checkpoint,address account, uint256 newQuantity) internal {
- uint32 blockTimestamp = uint32(block.timestamp);
- uint32 nCheckpoints = checkpoint.numCheckpoints[msg.sender];
- if (nCheckpoints > 0 && checkpoint.checkpoints[account][nCheckpoints - 1].fromTime == blockTimestamp) {
- checkpoint.checkpoints[account][nCheckpoints - 1].quantity = newQuantity;
- } else {
- checkpoint.checkpoints[account][nCheckpoints] = data(blockTimestamp, newQuantity);
- checkpoint.numCheckpoints[account] = 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);
- }
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |