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.
Related
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.
Just a general question, if I'm building a blockchain for a business I want to store 3 years of transactions but anything older than that I won't need and don't want actively in the working database. Is there a way to backup and purge a blockchain or delete items older than some time frame? I'm more interested in the event logic than the forever memory aspect.
I'm not aware of any blockchain technology capable of this yet, but Hyperledger Fabric in particular is planning to support data archiving (checkpointing). Simply put, participants need to agree on a block height, so that older blocks can be discarded. This new block then becomes the source of trust, similar to original genesis block. Also, snapshot needs to be taken and consented, which captures current state.
From serviceability point of view, it's slightly more complicated, i.e. you may have nodes that are down while snapshotting, etc.
If you just want to purge the data after a while, Fabric Private Data has an option which could satisfy your desire.
blockToLive Represents how long the data should live on the private database in
terms of blocks. The data will live for this specified number of
blocks on the private database and after that it will get purged,
making this data obsolete from the network so that it cannot be
queried from chaincode, and cannot be made available to requesting
peers
You can read more here.
Personally, I don't think there is a way to remove a block from the chain. It might destroy the Immutable property of blockchain.
There are 2 concepts which help you achieve your goals.
The one thing is already mentioned. It is about Private Data. Private data gives you the possibility to 'label' data with a time to live. Then only the private data hashes are stored on the chain (to be able to verify this transaction) but the data itself is stored in so called SideDBs and gets fully pruned (except the hashes on the chain of course). This is kind of the basis for using Fabric without workarounds and achieving GDPR.
The other thing, which was not mentioned yet and kind of is very helpful to this question
Is there a way to backup and purge a blockchain or delete items older than some time frame?
Every peer only stores the 'current state' of the ledger in his StateDB. The current state could be described as the data which is labeled 'active' and probably soon to be used again. You can think of the StateDB being like a Cache. Every Data is comes into this Cache by creating or updating a new key (invoking). To remove a key from the Cache you can use 'DelState'. So it is labeled 'deleted' and not in the Cache anymore. BUT it is still on the ledger! and you can retrieve the history and data to that key.
Conclusion: For 'real' deleting of data you have to use the concept of Private Data and for managing data in your StateDB (think of the 'Cache' analogy) you can simply use built in functions.
I have a scenario where i have to update multiple transactions in ledger at the same time.
In simple case, two transactions has to executed at the same time in order to make the use case valid. if anyone of them fails the other one should revert back.
err = stub.PutState(key, tradeJSONasBytes)
using hyperledger 1.1 and golang smart contract.
If you want to save multiple transaction you can call multiple PutState() but there is nothing like reverting the transaction, even if the transaction fails it is still stored as a block, as it is the part of immutability condition.
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.
I believe the answer is no but I'd like confirmation.
With Fabric, endorsers simulate the transaction upon latest state and prepare the proposal adding the read and write set of keys.
At the commit phase, the peer will receive a block from the ordering service and the write set update is only applied if the read set has not been updated (versioning check).
So for the same block, the same key cannot be updated by 2 different transactions of the same block.
If it is the case, aggregating value and maintaining balance on-chain might be problematic for frequent transactions use-case. Such operation should be left for off-chain application layer.
So for the same block, the same key can not be updated by 2 different transactions of the same block.
The above is correct. Hyperledger Fabric uses an MVCC-like model in order to prevent collisions (or "double spend"). You'll want to wait for the previous state change transaction to commit before attempting to update the state again.