How to access same ledger from different chaincodes? - hyperledger-fabric

Suppose I have 2 peers(peer0 and peer1) and 2 chaincodes(1. full rights 2.only query).
I want peer0 to have full rights of invoking but peer1 to only have query available but installing and instantiating different chaincodes is creating different ledgers hence the query from peer1 is always empty.
So How can I access same ledger from different chaincodes?

The scope of key-value data is actually channel/chaincode (meaning it is not scoped to the channel and each chaincode instance in a channel manages its own state).
So, if you want to "share" key/value state between chaincode, the only way to do this is to either always have one chaincode invoke another or you can extend this a bit and create a third chaincode which simply manages the get/put operations and have the other chaincodes always call it when dealing with the "shared" state.

Related

consensus among peers in hyperledger fabric after transaction is committed

Suppose I have started fabric with two peers in a single organization. After running my application/rest-server through composer and submitting transactions. I was able to make changes in the values of Couchdb instance of peer1 by going on the address http://localhost:6984/_utils/#/_all_dbs. Now, the two peers are not in sync with each other - application should throw some error but it isn't. Mostly, because it is getting data just from the first peer i.e. peer1.
So, firstly how can I get data from multiple peers - if I want to get data from peer2 aswell?
Secondly, why it is getting data from state database not from ledger?
Thirdly, data should remain in sync even after committed how can I configure this? if some peer tampered its database it should be notified. I have read consensus part and got that it is for the correct order of transactions and blocks but what if someone tampered with the state database?
If you're able to change the entries in state database for 1 peer, with a strong endorsement policy such as AND, your transactions will fail validation because of difference in the data for the two peers. This is one of the most important pros of decentralized network.
State database and the Ledger are not same thing. this should help you in understanding the differences between the both.
Every participating member of a Hyperledger Fabric network is a known entity per se (since Fabric being a permissioned blockchain). Said that, a change in state database of a single peer will again lead to scenario #1 above, where the Read/Write sets in a transaction won't match for multiple peers (as their state databases contain different values of an asset). This will lead to invalidation of the transactions. Now it just becomes a question of how can the network know about the corrupted peer(and subsequent state db). There can be multiple solutions for the same.
But most importantly, Fabric being a permissioned blockchain network, the state databases must be very strictly access protected and authorized outside of the network too.
the fact that you modified the world db doesn't mean anything. any changes you make to that database are not a representation of the ledger.
The ledger itself, the blocks and the transactions they contain are stored in a physical file. The world state db is simply a collection of the current state for each asset. This is a good design because an application will not care about every state change an item went through, it will only care about the current state. The world state db can easily be recreated whenever there is a need for it.
Now, you should not make any changes directly to to the world state db, because that's useless. Any change needs to go through the proper process, via a proposal submitted by a peer which then goes through the orderer. Only when everything is followed, does a change go onto the ledger and get synced with every peer and the world state db will reflect that.
In terms of where you should get the data, the answer is that it doesn't matter. Each peer will have an exact copy of the ledger so if you get data from peer 1 or 2 is irrelevant, it will be the same thing.
Again, just because you changed the world state, that doesn't mean anything, the ledger is untouched, but your application reports the current state from the world state db, which is now incorrect because of your change.

Best Practices to follow while writing Hyperledger Fabric Chaincode

What should be some of the best practices to follow to avoid bugs and write efficient Hyperledger Fabric Chaincode?
General Guidelines for writing Hyperledger Fabric Chaincodes.
Refer to the below link for a detailed description on the same:
https://gist.github.com/arnabkaycee/d4c10a7f5c01f349632b42b67cee46db
Some steps are concisely mentioned below:
Use Chaincode DevMode
Use Chaincode Logging
Using logging is simple and easy. Use Fabric's inbuilt logger. Fabric provides logging mechanism as follows:
For Golang: https://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim#ChaincodeLogger
For NodeJS: https://fabric-shim.github.io/Shim.html#.newLogger__anchor
For Java: You can use any standard logging framework like Log4J
Avoid using Global Keys - Hyperledger Fabric uses an Optimistic Locking Model while committing transactions. In the two-stage process of endorsement & committment, if some versions of the keys that you had read in the Endorsement has changed till your transactions reach the committing stage, you get an MVCC_READ_CONFLICT error. This often is a probability when one or more concurrent transactions are updating the same key.
Use Couch DB Queries wisely
Couch DB Queries DO NOT alter the READ SET of a transaction -
Mongo Queries are for querying the Key Value store aka StateDB only. It does not alter the read set of a transaction. This might lead to phantom reads in the transaction.
Only the DATA that you have stored in the couchDB is searchable - Do not be tempted to search for a key by its name using the MangoQuery. Although you can access the Fauxton console of the CouchDB, you cannot access a key by querying a key by which it is stored in the database. Example : Querying by channelName\0000KeyName is not allowed. It is better to store your key as a property in your data itself.
Write Deterministic Chaincode - Never write chaincode that is not deterministic. It means that if I execute the chaincode in 2 or more different environments at different times, result should always be the same, like setting the value as the current time or setting a random number. For example: Avoid statements like calling rand.New(...) , t := time.Now() or even relying on a global variable (check ) that is not persisted to the ledger.
This is because, that if the read write sets generated are not the same, the Validation System chaincode might reject it and throw an ENDORSEMENT_POLICY_FAILURE.
Be cautions when calling Other Chaincodes from your chaincode. - Invoking a chaincode from another is okay when both chaincodes are on the same channel. But be aware that if it is on the other channel then you get only what the chaincode function returns (only if the current invoker has rights to access data on that channel). NO data will be committed in the other channel, even if it attempts to write some. Currently, cross channel chaincode chaincode invocation does not alter data (change writesets) on the other channel. So, it is only possible to write to one channel at a time per transaction.
Remember to Set Chaincode Execution Timeout - Often it might so happen that during high load your chaincode might not complete its execution under 30s. It is a good practice to custom set your timeout as per your needs. This is goverened by the parameter in the core.yaml of the peer. You can override it by setting the environment variable in your docker compose file :
Example: CORE_CHAINCODE_EXECUTETIMEOUT=60s
Refrain from Accessing External Resources - Accessing external resources (http) might expose vulnerability and security threats to your chaincode. You do not want malicous code from external sources to influence your chaincode logic in any way. So keep away from external calls as much as possible.

How your data is safe in Hyperledger Fabric when one can make changes to couchdb data directly

I am wondering that how your data is safe when an admin can change the latest state in Couchdb using Fauxton or cURL provided by Couchdb directly.
According to my understanding Hyperledger Fabric provides immutable data feature and is best for fraud prevention(Blockchain feature).
The issue is :- I can easily change the data in couchdb and when I query from my chaincode it shows the changed data. But when I query ledger by using GetHistoryForKey() it does not shows that change I made to couchdb. Is there any way I can prevent such fraud? Because user will see the latest state always i.e data from couchdb not from ledger
Any answer would be appreciated.
Thanks
You should not expose the CouchDB port beyond the peer's network to avoid the data getting tampered. Only the peer's administrator should be able to access CouchDB, and the administrator has no incentive to tamper their own data. Let me explain further...
The Hyperledger Fabric state database is similar to the bitcoin unspent transaction database, in that if a peer administrator tampers with their own peer’s database, the peer will not be able to convince other peers that transactions coming from it are valid. In both cases, the database can be viewed as a cache of current blockchain state. And in both cases, if the database becomes corrupt or tampered, it can be rebuilt on the peer from the blockchain. In the case of bitcoin, this is done with the -reindex flag. In the case of Fabric, this is done by dropping the state database and restarting the peer.
In Fabric, peers from different orgs as specified in the endorsement policy must return the same chaincode execution results for transactions to be validated. If ledger state data had been altered or corrupted (in CouchDB or LevelDB file system) on a peer, then the chaincode execution results would be inconsistent across endorsing peers, the 'bad’ peer/org will be found out, and the application client should throw out the results from the bad peer/org before submitting the transaction for ordering/commit. If a client application tries to submit a transaction with inconsistent endorsement results regardless, this will be detected on all the peers at validation time and the transaction will be invalidated.
You must secure your couchdb from modification by processes other than the peer, just as you must generally protect your filesystem or memory.
If you make your filesystem world writable, other users could overwrite ledger contents. Similarly, if you do not put access control on couchdb writes, then you lose the immutability properties.
In Hyperledger Fabric v1.2, each peer has its own CouchDB. So even if you change the data directly from CouchDB of one peer. The endorsement would fail. If the endorsement fails, your data will not be written neither in world state nor in the current state.
That's the beauty of a decentralized distributed system. Even if you or someone else changes the state of your database/ledger it will not match with the state of others in the network, neither will it match the transaction block hash rendering any transactions invalid by the endorsers unless you can restore the actual agreed upon state of the ledger from the network participants or the orderer.
To take advantage of the immutability of ledger you must query the ledger. Querying the database does not utilize the power of blockchain and hence must be protected in fashion similar to how access to any other database is protected.
You need to understand 2 things here
Although the data of a couchdb of a peer maybe tampered, you should setup your endorsement policy in such a way that it must be endorsed by all the peers.
You cannot expose your couchdb to be altered, I recommend to see Cilium
As explained by others - endorsements/consensus is the key. Despite the fact that ledger state of an endorsing peer can be modified externally - in that event all transactions endorsed by that peer would get discarded, because other endorsing peers would be sending correct transactions (assuming other's world state was also not tampered with) and consensus would play the key role here to help select the correct transaction.
Worst case scenario all transactions would fail.
Hyperledger fabric's world state (Ledger state) can be regenerated from the blockchain (Transactions Log) anytime. And, in the event of peer failure this regeneration happens automatically. With some careful configuration, one can build a self-healing network where a peer at fault would automatically rise from ashes (pun intended).
The key point to consider here is the Gossip Data dissemination protocol which can be considered as the mystical healer. All peers within the network continuously connect, and exchange data with other peers within the network.
To quote the documentation -
Peers affected by delays, network partitions, or other causes resulting in missed blocks will eventually be synced up to the current ledger state by contacting peers in possession of these missing blocks.
and ...
Any peer with data that is out of sync with the rest of the channel identifies the missing blocks and syncs itself by copying the correct data.
That's why it is always recommended to have more and more of endorsing peers within the network and organizations. The bigger the network - harder it would be beat with malicious intent.
I hope, I could be of some help. Ref Link: https://hyperledger-fabric.readthedocs.io/en/release-1.4/gossip.html
Even though this is plausible, the endorsement policy is the general means by which you protect yourself (the system) from the effects of such an act.
"a state reconciliation process synchronizes world state across peers on each channel. Each peer continually pulls blocks from other peers on the channel, in order to repair its own state if discrepancies are identified."

Hyperledger Fabric. Is it possible to deploy more than one chaincode to the same channel?

Is it possible to deploy two different chaincodes to the same channel in Hyperledger fabric
Yes. And its possible to deploy the same chaincode to 2 or more channels. You can even deploy the same chaincode to the same channel if you use a different name.
when inspect into the block structure, I find a 'Chaincode Name' field in block, and I suppose that:
One channel has one ledger(offcial doc)
One channel can have two or more chaincodes
The block generated by different chaincode(we can simplely think so) will be stored in the same one ledger
The field 'Chaincode Name' in block will distinguish it's generated from which chaincode
jworthington answer is correct but i want to clear some things from comments.
One channel means one ledger. (official doc)
Every chaincode have separated "view" on ledger (I visualize it as every key in db has chaincode name prefix and chaincode can access
only specific keys with same prefix as its name).
You can invoke read/write of second chaincode from first one and that will make only one blockchain transaction (at condition that chaincodes are on same channel/ledger, if they are not, write operation will be ignored)
I do not know how much is changed over the years, but I share information based on version 2.x.
Ledger is associated with the channel, not with the Chaincode. Even a peer can have a ledger without any Chaincode installed. https://hyperledger-fabric.readthedocs.io/en/latest/peers/peers.html#multiple-ledgers
P1 is Peer
L1 & L2 are ledgers
S1, S2, and S3 are Chaincodes
There isn’t a fixed relationship between the number of ledgers a peer has and the number of Chaincodes that can access that ledger. A peer might have many Chaincodes and many ledgers available to it.
https://hyperledger-fabric.readthedocs.io/en/latest/peers/peers.html#multiple-chaincodes
P1 is Peer
L1 & L2 are ledgers
S1, S2, and S3 are Chaincodes
Yes, we can deploy multiple chaincodes to the same channel with different chaincode ID.
Each chaincode will have separate ledger in channel, we can consider this as namespace.
One chaincode can not read/update other channel ledger directly.
However, fabric shim package provides "InvokeChaincode" functionality to call another chaincode to read/update it's ledger.
stub.InvokeChaincode("anotherCCName", chainCodeArgs, "channelName")

Where is the blockchain physically

just playing with Hyperledger Composer, and I'm wondering ,Where is the blockchain physically
I'mean is it binary file , text file ....?
is it portable ?
thank you all
There are two place which "store" data in Hyperledger Fabric (the underlying blockchain infrastructure used by Composer which is a runtime abstraction layer above it):
the ledger
the state database ('World state')
The ledger is the actual "blockchain". It is a file-based ledger which stores serialized blocks. Each block has one or more transactions. Each transaction contains a 'read-write set' which modifies one or more key/value pairs. The ledger is the definitive source of data and is immutable.
The state database (or 'World State') holds the last known committed value for any given key - an indexed view into the chain’s transaction log. It is populated when each peer validates and commits a transaction. The state database can always be rebuilt from re-processing the ledger (ie replaying the transactions that led to that state). There are currently two options for the state database: an embedded LevelDB or an external CouchDB.
As an aside, if you are familiar with Hyperledger Fabric 'channels', there is a separate ledger for each channel.
The chain is a transaction log, structured as hash-linked blocks, where each block contains a sequence of N transactions. The block header includes a hash of the block’s transactions, as well as a hash of the prior block’s header. In this way, all transactions on the ledger are sequenced and cryptographically linked together.
The state database is simply an indexed view into the chain’s transaction log, it can therefore be regenerated from the chain at any time.
Source: http://hyperledger-fabric.readthedocs.io/en/release/ledger.html
Suffice to say, Hyperledger Composer uses Fabric (as the blockchain infrastructure) to endorse/order/commit transactions to blocks on the ledger.
To see the physical location of these data you can go to /var/hyperledger/production in each peer container in your fabric network
Actually, the blockchain is a shared database, which is read-only and append-only. And it is distributed in every peers. So every peer has a copy of the shared database. Normally, LevelDB or CouchDB is used in HyperLedger Fabric.
The ledger is comprised of a blockchain (‘chain’) to store the immutable, sequenced record in blocks, as well as a state database to maintain current fabric state.
Here is more information about HyperLedger Fabric Ledger (the blockchain)
Blockchain is shared among all the peer to peer networks hosting it. So basically blockchain is stored in many HDD all around the world.

Resources