How to keep a digital asset in Hyperledger Fabric? - hyperledger-fabric

I'm working with the BYFN example using 3 organizations, 2 channels. One channel(c12) between Org1 and Org2, another channel (c23) between Org2 and Org3. The first chaincode is an example where I'm able to transfer value between "A" and "B". When I run the code over c12, I can see I'm able to transfer an amount from A to B. But when I query the same chaincode over c23, the initialization is kept. I understand why (different ledgers) and etc.
Now I would like to introduce the following requirement. I, as an organization, need to transfer this value only if I have the amount available.
The sequence would be:
1. I'm on org2, I have 100, and I wanna transfer 60 to org1. And everything works as expected.
2. I'm on org2, I have 40 and I'll try to transfer 50 to org3 (another ledger - channel). This should fail because I have only 40.
How can I achieve this?
Where will the "shared state" be stored? MSP?
The same approach would work for a complex asset?
Extra information:
- I already have read the documentation, about the assets, account model, the examples, but usually, they are focused only one channel only. Maybe I'm losing something.
- I'm not using hyperledger composer

In fabric you have a chaincode and a ledger different for each channel. so if you want to have the business logic descripted you need to use only one channel (with 3 orgs).
You can probably use private data to make the separation you are now doing with the two channels

Related

Hyperledger join one org from one consortium to a channel in another consortium with already existing name. Best ways to do this

Hyperledger Fabric 2.2
Current situation. We have two separate consortiums. Both have, however, channels with the same names. If I add Org from one consortium to the channel of another consortium I get error:
Error: proposal failed (err: bad proposal response 500: cannot create ledger from genesis block: ledger [data-channel] already exists with state [ACTIVE])
What's the best way to solve this situation? Do we have to rename a channel (is it possible?) in one of the consortiums? If I make a name-update config transaction, will the Couch DB databases follow this update?
A Fabric node cannot participate in two channels with the same name. You can simply have different nodes that each participates in one of the channels.

desiging better private data collections in Hyperledger Fabric

I have a very case-specific query related to the implementation of private data collection and I am seeking recommendations/suggestions from the experts here. We have a product running on Hyperledger Fabric 2.3.3 and the platform can have any number of organizations. For instance, initially, there will be 4 organizations, next week 10 more organizations can join the network. The problem arises when these organizations start transactions with each other. These transactions can have a number of objects that need to be private between these organizations only. 

For this, we can create private data collections with names:
collection_org1
collection_org2
collection_org3
collection_org1_org2
collection_org1_org3
collection_org1_org2_org3
collection_org2_org3
Assume if the network has 20 organizations as participants, how many private data collection combinations will be there.
This is because, at a given time, any organization can begin a transaction with another organization or a series of organizations in the network. The problem here is that we have to create a large number of private data collections using the pattern and maintain it.
Because of this problem, we removed this implementation and used the implicit private data collection for each organization. Now if there is an object that should be shared only with org1, org2 & org3, the object is pushed to collection_org1, collection_org2, collection_org3. We did this using setting memberOnlyRead: false and memberOnlyWrite: false and added the validations at the chaincode level.

This implementation solved the above problem but has created a new problem. Now, we wanted to implement key-level endorsement policy such that if org1 changes a private object that is shared among org2 & org3, the org1 has to obtain the endorsements from org2 & org3 peers. This means that the peers will read the object from their own private data collection resulting in a different read-set in endorsement proposal response which further leads to an error saying read/write sets do not match.
For example, org1 during the endorsement proposal will read object key: key1 from its own private data collection collection_org1. In a similar way, org2 will read the same key during endorsement from its own collection collection_org2, and likewise for org3. This leads to a different read-set in the endorsement proposal.

I am seeking suggestions to implement this whole functionality in a better way. 

Please let me know your suggestions/recommendations.
GetPrivateDataHash() is your answer. You can use this function to verify that each of the endorsers have the same value, and ensure that your read sets are consistent.
See the secured transfer tutorial and sample for an example of using it for this purpose.

How can I use two chaincodes installed in the same Fabric channel?

I have two chaincodes deployed in the same channel of 5 peers. The first chaincode is installed on 3 peers, the second one is installed on other 2 peers. The first chaincode inits the ledger with some data, while the second one should query the ledger to take one of the elements stored in the ledger during the initialization. It seems that the ledger associated to the second smart contract is empty. From theory, I know that there is one ledger associated with the channel, but here it seems one ledger associated with the chaincode. Where am I wrong?
Thank you in advance!
I figured out by studying the concept of namespaces and world states.

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")

does channel maintains separate ledger?

If there one ledger per channel. does that mean all the peer nodes arose different organisation have to be one channel.
Suppose, A sells 10 chicken shawarma to B in 80$ and A sells 10 chicken shawarma to C in 90$ and A wants to hide price details.
How would admin party now if A total amount in sales if A maintaining a separate ledger for sales to different peers if they are on separate channel.
You define channels for the organizations which are interested to trade with each other. Each organization would have their own set of peers. Some would be endorser, committer or anchor peer. Each peer would have a copy of the ledger.
Now, you would be instantiating the chaincode to a particular endorser peer for a given organization. For an instance, suppose there are 4 organizations A,B,C and D. All these are connected with one specific channel(channel1) where everyone can see all the transaction details. Now, A and B do have a special requirement where they don't want to share their buying a specific product transaction details with other organizations.
Therefore, A and B would have a new channel(channel2) having an endorser peer(could be the same one which is there for channel1 having 2 chaincode installed) which would take care of their specific contract. The data will be replicated to all the peers of only A and B.
Since C and D isn't the part of this special channel, this specific transaction will not be logged on their peers. They can just see whatever is logged by channel 1.
How an admin would know about these? Well, a network admin would always knows this as he would be the one who is defining this network. He would be defining the channel and instanciating the chaincode over it. So, as per the design, an admin would always have an insight of who can see what and what data could be stored over different ledgers.
Hope this helps.

Resources