How to Retrieve or Query Data Stored in the Blockchain

go-ethereumsolidity

I want to store and retrieve data in the blockchain.

I mate a blockchain expert yesterday and I want to quote his premise :

It is not possible to query data stored in the blockchain. One can store data and it will be there in the blocks of the blockchain but one cannot retrieve data stored in the blockchain.

I know using data structures like an array of structures or mappings it is very much possible to retrieve data stored in the blockchain.

Is storing data in an array of structures or mappings is not the right way of storing data in the blockchain?

If one does not use data structures like an array of structures and mapping and just update values of data stored in structure then one cannot retrieve data stored in the blockchain.

To be more precise consider the following example from this tutorial-

pragma solidity ^0.4.18;
// written for Solidity version 0.4.18 and above that doesnt break functionality

contract Voting {
    // an event that is called whenever a Candidate is added so the frontend could
    // appropriately display the candidate with the right element id (it is used
    // to vote for the candidate, since it is one of arguments for the function "vote")
    event AddedCandidate(uint candidateID);

    // describes a Voter, which has an id and the ID of the candidate they voted for
    struct Voter {
        bytes32 uid; // bytes32 type are basically strings
        uint candidateIDVote;
    }
    // describes a Candidate
    struct Candidate {
        bytes32 name;
        bytes32 party; 
        // "bool doesExist" is to check if this Struct exists
        // This is so we can keep track of the candidates 
        bool doesExist; 
    }

    // These state variables are used keep track of the number of Candidates/Voters 
    // and used to as a way to index them     
    uint numCandidates; // declares a state variable - number Of Candidates
    uint numVoters;

    
    // Think of these as a hash table, with the key as a uint and value of 
    // the struct Candidate/Voter. These mappings will be used in the majority
    // of our transactions/calls
    // These mappings will hold all the candidates and Voters respectively
    mapping (uint => Candidate) candidates;
    mapping (uint => Voter) voters;
    
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *  These functions perform transactions, editing the mappings *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    function addCandidate(bytes32 name, bytes32 party) public {
        // candidateID is the return variable
        uint candidateID = numCandidates++;
        // Create new Candidate Struct with name and saves it to storage.
        candidates[candidateID] = Candidate(name,party,true);
        AddedCandidate(candidateID);
    }

    function vote(bytes32 uid, uint candidateID) public {
        // checks if the struct exists for that candidate
        if (candidates[candidateID].doesExist == true) {
            uint voterID = numVoters++; //voterID is the return variable
            voters[voterID] = Voter(uid,candidateID);
        }
    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * 
     *  Getter Functions, marked by the key word "view" *
     * * * * * * * * * * * * * * * * * * * * * * * * * */
    

    // finds the total amount of votes for a specific candidate by looping
    // through voters 
    function totalVotes(uint candidateID) view public returns (uint) {
        uint numOfVotes = 0; // we will return this
        for (uint i = 0; i < numVoters; i++) {
            // if the voter votes for this specific candidate, we increment the number
            if (voters[i].candidateIDVote == candidateID) {
                numOfVotes++;
            }
        }
        return numOfVotes; 
    }

    function getNumOfCandidates() public view returns(uint) {
        return numCandidates;
    }

    function getNumOfVoters() public view returns(uint) {
        return numVoters;
    }
    // returns candidate information, including its ID, name, and party
    function getCandidate(uint candidateID) public view returns (uint,bytes32, bytes32) {
        return (candidateID,candidates[candidateID].name,candidates[candidateID].party);
    }
}

In the above example data of Voter and Candidate is stored in mapping voters and candidates respectively. It is possible to retrieve voter and candidate data by using vaterID and candidateID respectively.

Is the above example demonstrates the right way to store data in the blockchain?

Best Answer

It is not possible to query data stored in the blockchain. One can store data and it will be there in the blocks of the blockchain but one cannot retrieve data stored in the blockchain.

This is simply incorrect. You can absolutely store and retrieve data from a blockchain.

The sample code you share is a common approach to storing related data, and reading it back out. Future versions of solidity will support returning structs as a unit, eliminating the need for multiple return types as in the getCanditate function too.

Moreover, even data marked as private can be ready by directly accessing the storage using the eth_getStorageAt function, although it is not visible to other smart contracts.

Related Topic