OpenZeppelin bitmaps.sol is an OpenZeppelin solidity library providing a data structure for managing boolean values, designed to store and manipulate large arrays of booleans, thus dramatically reducing gas cost.
Instead of writing “bool[] array” that occupies 1 storage slot per boolean,
we write “uint256[]” which is 1 storage slot per 256 booleans.
Real-world use cases Link to heading
- Tracking user claims for an airdrop (hasAddressClaimed: true/false)
- Voting systems to track voter participation (hasVoted: true/false).
Storage cost comparison Link to heading
- Without BitMaps.sol library :
mapping(address => bool) voted;
// in such case , if we have 20,000 users = 20,000 storage slots.
- With BitMaps.sol library:
BitMaps.BitMap voted;
// in this scenario, 20,000 users = 20,000/256 = ~78 storage slots (massive gas savings !!)
Let’s apply this in a Voting function :
import "@openzeppelin/contracts/utils/struct/BitMaps.sol";
// Use BitMaps for gas optimization
using BitMaps for BitMaps.BitMap;
BitMaps.BitMap private hasVoted;
event VoterStatusUpdated(address indexed voter, bool hasVoted);
function vote(uint256 _candidateIndex) external onlyEligible {
uint256 voterIndex = uint256(uint160(msg.sender));
require(!hasVoted.get(voterIndex), "Already voted");
if (_candidateIndex == 0) {
numVotesForCandidate1++;
} else {
numVotesForCandidate2++;
}
// Mark as voted using BitMaps
hasVoted.set(voterIndex);
voterUSDCBalance[msg.sender] = requiredToken.balanceOf(msg.sender);
emit VoterStatusUpdated(msg.sender, true);
}