How does ChaincodeStub.delState impact the ledger? - hyperledger-fabric

I have a specific question on how org.hyperledger.fabric.shim.ChaincodeStub.delState(String key) impacts the ledger.
I understand that data on a blockchain can almost never be deleted, but then there is this delState method which according to the documentation here,
Records the specified key to be deleted in the writeset of the transaction proposal.
The key and its value will be deleted from the ledger when the transaction is validated and successfully committed.
The ledger as I understand it has two components - the blockchain and the world state. What effect does this operation have on the two components?

In Hyperledger Fabric, Ledger is divided into two components:
Blockchain/Transaction Log (LevelDB)
World state (LevelDB/CouchDB)
Blockchain Ledger stores the data in the LevelDB and that is append-only, which means you can only add data to it but cannot delete data from it. Since the blockchain ledger works in append-only mode, it maintains the history of the data. While the World state stores the current state only. With world state, you have a choice between LevelDB and CouchDB.
And when you use getHistoryForKey() in the chaincode you get the data from the blockchain ledger not from the world state. But when you use getState() in the chaincode, you get the data from the world state.
So even if you delete the data using delState() the data will be deleted from the world state but it will be present in the Blockchain Ledger, you can retrieve the data from the blockchain using the getHistoryForKey() provided that you know the key using which stored the data.
You will get data like this when you will use getHistoryForKey()
[
{
"TxId" :"1121212d...."
"Timestamp" :"" ,
"IsDelete": true
"Record" : {
.......
}
},
{
"TxId" :"2221212d...."
"Timestamp" :"" ,
"IsDelete": false
"Record" : {
.......
}
},
]

Related

How to delete asset from hyperledger fab test-network?

I am trying to run test_network on hyperledger fabric node release 2.4. See here: https://hyperledger-fabric.readthedocs.io/en/latest/test_network.html#interacting-with-the-network.
I can query the network using ReadAsset and UpdateAsset function.
However, the DeleteAsset function using below query doesn't work.
peer chaincode query -C mychannel -n basic -c '{"Args":["DeleteAsset","idOfasset"]}'
where, idOfasset is the ID or key of asset I am trying to delete from ledger.
Second, if the command would execute, would I be deleting the asset from the world database or the state database?
Or let's put it the other way when I execute ReadAsset where does it read from i.e from the world state or the channel state database?
Help would be great, thanks.
Deleting an asset changes the state of the asset. For any kind of operations which involve modification of the state of the variables, the invoke command is used. Each "Invoke" transaction will be added to the "block" in the ledger. query is used when you just want to query the chaincode for reading the current value of an asset. So use, invoke in lieu of query in your command.
Coming on to your second question
Second, if the command would execute, would I be deleting the asset from the world database or the state database? Or let's put it the other way when I execute ReadAsset where does it read from i.e from the world state or the channel state database?
World and state databases are the same things which are your CouchDB/LevelDB.
From Hyperledger Fabric's documentation:
there’s a world state – a database that holds current values of a set of ledger states. The world state makes it easy for a program to directly access the current value of a state rather than having to calculate it by traversing the entire transaction log
You can read more about it here.
Hyperledger Fabric doesn't actually "remove" the asset when a delete operation is performed. Blockchain is immutable and no data on a blockchain will ever be deleted. A deletion is just another transaction saying certain data is deleted so that the world state database can remove that data.
You can refer to this for more info.

What kind of transactions we can find in Hyperledger Fabric blocks?

In Bitcoin blockchain, transactions are only of the type "transferring some amount from X to Y", so we always have an actual change the blockchain.
In Hyperledger Fabric transaction are like:
Instatiate some chaincode in a channel
Invoke some chaincode (that may be just a query to show a certain
asset in the ledger / world state)
I'm sure that instantiating chaincode in some channel or running something that changes the world state are transaction that qualify to fit in a block.
What I don't understand is exactly which transactions can enter in the next block. If some chaincode does not write or update the world state (in RW sets, the Read set is the same of the Write one) can still be included in the next block? Or can be safely "discarded"?
All endorsing peer must have instantiated chaincode so that they can simulate transactions and create Read/Write(RW) set. Installing and instantiating chaincode are different transaction than regular invoke.
Invoking some transaction meansa it can be one of
Query
Adding Asset, Updating Asset, Deleting Asset
HF maintains versioning of each unique key and it increases chronologically when we update same asset. This versioning (MVCC - Multiversion concurrency control) avoid double-spending problem as well.
HF dont care about whatever value we puts for key(Value could be anything).
Lets assume we have to add car asset with key car1 and value is {"name":"Audi", "owner":"ABC"}.
When we send the transaction to all endorsing peer, they create RW set as below
Read Set: NA
Write set: Key-car1, version-1, value-{"name":"Audi", "owner":"ABC"}
When the tx gets committed to blockchain, one of the block will have this transaction and the current state database (Couch db or level db) will heve this latest value for that key : Key-car1, version-1, value-{ "name": "Audi", "owner": "ABC"}
Let's assume if we updating this same asset(car1)
car1 - { "name": "Audi", "owner": "PQR"}
Here we are changing owner from ABC to PQR
This time Endorsing peer create the following RW set
Read Set: Key-car1, version-1
Write set: Key-car1, version-2, value-{"name":"Audi", "owner":"PQR"}
Once the tx gets committed to the blockchain. again this transaction gets added into one block and most importantly, the current state database will get updated with this latest value and old value will be updated and the version also get changed to 2.

The algorithm to get transaction history in Hyperledger Fabric?

I am looking for the details of how Hyperledger Fabric get transaction history for a specific asset, including what data structures and algorothms are used. In theory, the transactions of a specific asset should be stored in different blocks not in a sequence. That is, a linear search on all blocks in blockchain may be required to get all transactions of the specific asset. Is that right? Is there any document and code about this issue recommended to read? Thank you.
History is not fetched from the ledger.
1.Unlike state data which can be stored in leveldb or couchdb History data is stored in a separate datastore and it is leveldb.
2.History data store should be enabled for each peer.
3.That can be done by enabling it in the core.yaml file in
ledger->enableHistoryDatabase set to true
or else pass the env variable
CORE_LEDGER_HISTORY_ENABLEHISTORYDATABASE=true
to the container for which you want to enable history database.
How History for the same key is stored in history database.
1.Now as it is a nosql database it cannot store a duplicate key.So some unique data is appended to the key and then the data is stored in the leveldb.
2.Querying the history database the gethistoryforkey API uses a query something like this
leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
for (it->Seek("theKey");
it->Valid() && it->key().ToString() < "theKey~";
it->Next()) {
...
}
As you can see the key is split from the unique data and then we get all the data related to it from the db.
Hope this helps.

Definition of ledger

I was reading the documentation of hyperledger fabric. In the transaction flow page I found this line
The chaincode (containing a set of key value pairs representing
the initial state of the radish market) is installed on the peers and
instantiated on the channel.
This line confused me. I think it is the definition of ledger .But here it is written as chaincode.
Is my perception correct ?
Can anyone explain me ?
Chaincode (or the more commonly-known term smart-contract) defines a set of business models, transaction definitions and logics which the application (SDK) could utilize to create transactions.
For the sentence you show above, this does not refer to the definition of the chaincode. I believe it merely conveys the idea that a list of radishes (in key and value pair) has been defined in the chaincode already, so once it is instantiated (or a initRadish function, if it exists in the chaincode is being called), that list of radishes will become part of the world state in the ledger.
How ledger and chaincode relate in Fabric?
Ledger consists of two components, namely world state and blockchain. World state stores the latest values of the key, whereas the blockchain stores all the transaction log that leads to the world state.
As I said above, chaincode defines the transaction logics in terms of functions such that the application could call to create transaction, which triggers state transition or state retrieval.
For example, you have a function called buyRadish(radishID, newOwner) defined in the chaincode. Suppose there is a radish with key R1001 with value {"owner": FarmerA, "status": OnSale}. This is the key-value pair before any transaction occurs. Once the function in the chaincode is invoked with the argument radishID = R1001, newOwner = Ken, a transaction is created and the state of radish with key R1001 will become {"owner": Ken, "status": Sold}. Note that this latest state of the radish will be seen at the world state.
With the example above, you can think in this way:
The ledger stores the latest key-value pairs (or to be precise latest value of the key). The chaincode may have some key-value pairs for initialization purpose; however, the point is that we are passing a new set of key-value pairs (radishID = R1001, newOwner = Ken) as argument to the function in chaincode, so as to update the values of the same key (radishID = R1001) in the world state of the ledger.
Hope it helps.
A chaincode is programmatic code deployed on the network, where it is executed and validated by chain validators together during the consensus process. Developers can use chaincodes to develop business contracts, asset definitions, and collectively-managed decentralized applications.
more about chaincode click here
How ledger and chaincode relate in Fabric?
Chaincode is a program (smart contract) that is written to read and update the ledger state.

Where is the 'real' ledger and How is it maintained?

In a Hyperledger Fabric network, ledgers which all peers(endorsing peers and committing peers) have are replicated ledgers.
It seems to imply there is a unique 'real/original/genuine' ledger per channel.
I'd like to ask these:
Is there a real ledger? If so, where is it(or where is it defined?) and who owns it?
Those replicated ledgers are updated by each peer, after VSCC, MVCC validation. Then who updates the 'real' ledger?
Does 'World State' only refers to the 'real' ledger?
I'd really appreciate if you answer my questions.
Please tell me if these questions are clarified to you. Thank you!
I don't understand what exactly you mean by 'real' ledger. There is one & only ledger per channel, replicated across all participants per channel. When I say participants, I mean all peers (both endorsing & committing) of an organization's MSP belonging to a given channel.
State DB (a.k.a World state) refers to the database that maintains the current value of a given key. Let me give you an example. You know that a blockchain is a liked list on steroids (with added security, immutability, etc). Say, you have a key A with value 100 in Block 1. You transact in the following manner.
Block 2 -- A := A-10
Block 15 -- A := A-12
.
.
.
Block 10,000 -- A := A-3
So, after Block 10,000, if you need the current value of key A, you have to calculate the value from Block 1. So to manage this efficiently, Fabric folks implemented a state database that updates the value of a key in the state after every transaction. It's sole responsibility is to improve efficiency. If your state gets corrupted, Fabric will automatically rebuild it from Block 0.

Resources