# Storing Hashes on the Blockchain

By [Bitcoinu](https://paragraph.com/@bitcoinu) · 2025-03-07

---

In **Bitcoinu**, to ensure the transparency of data and algorithms, they are publicly disclosed and their hashes(SHA-256) are stored on the blockchain (smart contract).

This guarantees that the data has not been arbitrarily modified after publication.

The following two main types of hashes are stored:

### **① Applicant List Hashes (applicantHashes)**

A hashed, ordered list of all applicants for each 4-day block is stored in an array format.

### **② Other Hashes (otherHashes)**

Hashes of various program codes are stored in a Key-Value format. The stored hashes include:

*   **code\_number\_of\_winners** → Hash of the program code that determines the number of winners for both authenticated and unauthenticated users.
    
*   **code\_lottery\_algorithm** → Hash of the program code that selects winners based on the block hash and applicant list.
    

**Smart Contract Code**
-----------------------

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.20;
    
    /**
     * @title HashStorage
     * @dev Hash storage contract on Base Layer 2
     * Stores each hash element using a common structure.
     */
    contract HashStorage {
        // Variables for access control
        address public admin;         // Administrator address (has permission to store and edit)
        address public superAdmin;    // Super administrator address (can change the administrator address)
    
        // Common structure definition for hash entries
        struct HashEntry {
            bytes32 hash;        // Hash value
            uint256 updated;     // Block number when updated
        }
    
        // Hashes of the applicant list (stored as an array of structures)
        HashEntry[] public applicantHashes;
    
        // Other hashes (stored in key-value format with values held in structures)
        mapping(bytes32 => HashEntry) public otherHashes;
    
        // Events
        event ApplicantHashAdded(bytes32 hash, uint256 index, uint256 blockNumber);
        event ApplicantHashUpdated(uint256 index, bytes32 oldHash, bytes32 newHash, uint256 blockNumber);
        event OtherHashUpdated(bytes32 indexed key, bytes32 hash, uint256 blockNumber);
        event AdminChanged(address oldAdmin, address newAdmin);
        event SuperAdminChanged(address oldSuperAdmin, address newSuperAdmin);
    
        /**
         * @dev Constructor
         * @param _admin Initial administrator address
         */
        constructor(address _admin) {
            require(_admin != address(0), "Invalid admin address");
            admin = _admin;
            superAdmin = msg.sender;  // The deployer becomes the super administrator
        }
    
        /**
         * @dev Modifier for functions that can only be executed by the administrator
         */
        modifier onlyAdmin() {
            require(msg.sender == admin, "Only admin can call this function");
            _;
        }
    
        /**
         * @dev Modifier for functions that can only be executed by the super administrator
         */
        modifier onlySuperAdmin() {
            require(msg.sender == superAdmin, "Only super admin can call this function");
            _;
        }
    
        // =========== Functions related to applicant hashes ===========
    
        /**
         * @dev Adds a new hash to the applicant hash list
         * @param _hash Hash to be added
         * @return The index of the added element
         */
        function addApplicantHash(bytes32 _hash) external onlyAdmin returns (uint256) {
            applicantHashes.push(HashEntry({
                hash: _hash,
                updated: block.number
            }));
            
            uint256 newIndex = applicantHashes.length - 1;
            
            emit ApplicantHashAdded(_hash, newIndex, block.number);
            
            return newIndex;
        }
    
        /**
         * @dev Updates the hash at a specific index in the applicant hash list
         * @param _index Index to be updated
         * @param _hash New hash value
         */
        function updateApplicantHash(uint256 _index, bytes32 _hash) external onlyAdmin {
            require(_index < applicantHashes.length, "Index out of bounds");
            
            bytes32 oldHash = applicantHashes[_index].hash;
            applicantHashes[_index].hash = _hash;
            applicantHashes[_index].updated = block.number;
            
            emit ApplicantHashUpdated(_index, oldHash, _hash, block.number);
        }
    
        /**
         * @dev Retrieves the hash at a specific index in the applicant hash list
         * @param _index Index to be retrieved
         * @return hash The hash value
         * @return updated The block number when it was last updated
         */
        function getApplicantHash(uint256 _index) external view returns (bytes32 hash, uint256 updated) {
            require(_index < applicantHashes.length, "Index out of bounds");
            
            HashEntry storage entry = applicantHashes[_index];
            return (entry.hash, entry.updated);
        }
    
        // =========== Functions related to other hashes ===========
    
        /**
         * @dev Sets other hashes (key-value format)
         * @param _key Key for the hash
         * @param _hash Hash value
         */
        function setOtherHash(bytes32 _key, bytes32 _hash) external onlyAdmin {
            otherHashes[_key] = HashEntry({
                hash: _hash,
                updated: block.number
            });
            
            emit OtherHashUpdated(_key, _hash, block.number);
        }
    
        /**
         * @dev Retrieves other hashes
         * @param _key Key for the hash
         * @return hash The hash value
         * @return updated The block number when it was last updated
         */
        function getOtherHash(bytes32 _key) external view returns (bytes32 hash

---

*Originally published on [Bitcoinu](https://paragraph.com/@bitcoinu/storing-hashes-on-the-blockchain)*
