Identify the Peer/Org executing the chaincode from within the chaincode [Fabric 1.2 or 1.3] - hyperledger-fabric

I am working with private data collections (PDC) and trying to set up a separate PDC for each org with only 1 member (i.e the org itself).
For example, in a 3 org network, I am looking to create 3 private data collections:
1) "org1-private" with only Org1 as member,
2) "org2-private" with only Org2 as member,
3) "org3-private" with only Org3 as member
When a transaction is invoked by the client, the data needs to be shared only between 2 orgs. The client app will send the transaction to the 2 relevant Org peers, but in the chaincode, to write to the correct PDC on a given org the chaincode needs to know which Org/Peer it is executing on.
What is the best way to find the current peer/org from inside the chaincode in Fabric 1.2?
Note: I understand PDCs with all possible pairs of Orgs can be created to solve this issue. In my experiment, there is a strict requirement NOT to create private data collections per pair.
tried calling GetLocalMSP from the package: "github.com/hyperledger/fabric/msp/mgmt" but it returns a memory address
GetLocalMSP().GetIdentifier() returns nil
import (
mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
)
fmt.Println(mspmgmt.GetLocalMSP()) // prints mem-address
id, _ := mspmgmt.GetLocalMSP().GetIdentifier()
fmt.Println(id) // prints nil

You can use the Client Identity Chaincode Library.
https://github.com/hyperledger/fabric/tree/master/core/chaincode/lib/cid
This will return the MSPID from the certificate invoking the chaincode:
mspid, err := cid.GetMSPID(stub)

Related

How to get block hash inside chaincode hyperledger fabric

Currently I'm working with Hyperledger Fabric chaincode and trying to get the hash of last block but I haven't found any way to get it. I need my chaincode to access this hash to do a security check.
I have tried to invoke qscc from my chaincode, which from a client does return blockchain and hash block information, but in this way access is restricted.
Code
#Transaction()
public String getBlockHash(final Context ctx) {
ChaincodeStub stub = ctx.getStub();
String[] argsQscc = {"GetChainInfo","mychannel"};
Response response = stub.invokeChaincodeWithStringArgs("qscc", argsQscc);
System.out.println("Result"+response.getMessage());
return response.getMessage();
}
Error
Rejecting invoke of QSCC from another chaincode because of potential for deadlocks, original invocation for 'mychaincode'.
It is not possible to get from within chaincode. I'm not sure you would want to anyways, because different peers may be at different heights and you would get different endorsement results leading to an invalidation of your transaction.
I'd suggest to have client query this information and pass it into the invoked chaincode as an input.

fabric-sdk-go Execute Not always updating ledger

I am using client.channel.Execute API in fabric-sdk-go to invoke the ledger update Txs in chaincode.
I know my chaincode for ledger update is correct because invoke Tx when run from cli container command line is working perfectly all the times.
Few times, randomly, ledger updates are not reflecting when executed as REST API call from POSTMAN like below. In those cases, response code is 200 with correct response payload suggestive of successful chaincode running.
`
chaincodeID := "hcc"
fcn := "GiftToken"
args := [][]byte{
[]byte(reqBody.TokenID),
[]byte(reqBody.GiftToUserID),
[]byte(GiftTokenCountAsString),
}
setup := lib.GetFabricSetup()
transientDataMap := make(map[string][]byte)
transientDataMap["result"] = []byte("Transient data in GiftToken invoke")
response, err := setup.Client.Execute(channel.Request{ChaincodeID: chaincodeID, Fcn: fcn, Args: args, TransientMap: transientDataMap})
I am running Fabric 1.4.4 images in docker containers. My network has 1 org with 4 peer nodes.
Surely missing some aspect which is leading to this sort of behaviour.
Thanks in advance.
It takes time for all peers to sync their blocks. Once peers receive these blocks they update their world state, so you can see your change via querying.
When you query for the "just executed" transaction, you may hit one of other peers. If you want immediate result, ensure that you're querying the same peer(s) where you actually executed your transaction. You may try putting some delay to see other peers as well get the block.
The reason why you see the change immediately on CLI, is about the way of the client implementation. On CLI command execution, you specify the peer explicitly. So transaction is executed on one peer and queried on the same peer (no issues). You may prove this behavior by immediately querying (via CLI) another organization's peer just after you execute the transaction (via CLI).
However with your client, probably since you don't explicitly specify the peer, your client SDK uses peers' discovery service and find a peer in the network for you and use it.
Due to this reason, when endorsement policy is formed like "AND(org1, org2)", client SDK actually queries 2 peers (one each org) and compare results.

How to query a chaincode from outside an organization

I have 4 Orgs:
Org1 -- 2 peer
Org2 -- 2 peer
OrgCam -- 0 peer, 1 client
OrgView -- 0 peer, 1 client
Org1's peers have a chaincode installed on them that access some private data only available to Org1.
As a client of OrgCam, I want to access the chaincode installed on Org1's peers.
When I try to do that:
const result = await contract.evaluateTransaction('getPoints','ID1');
This error occurs
2019-05-19T15:20:20.084Z - error: [SingleQueryHandler]: evaluate: message=No peers available to query. Errors: [], stack=FabricError: No peers available to query. Errors: []
at SingleQueryHandler.evaluate (/home/zanna/fabric-samples/first-network/clientCode/node_modules/fabric-network/lib/impl/query/singlequeryhandler.js:39:17)
at Transaction.evaluate (/home/zanna/fabric-samples/first-network/clientCode/node_modules/fabric-network/lib/transaction.js:246:29)
at Contract.evaluateTransaction (/home/zanna/fabric-samples/first-network/clientCode/node_modules/fabric-network/lib/contract.js:172:39)
at main (/home/zanna/fabric-samples/first-network/clientCode/camera.js:41:39)
at <anonymous>, name=FabricError
Failed to evaluate transaction: FabricError: No peers available to query. Errors: []
My question is: How can I query the Org1's chaincode even if I'm not a client from Org1?
I am a bit confused by your configuration, but I'll try to answer as best as I can.
Lets make it clear
A chaincode does not "belong" to an organization. A chaincode belongs to a channel and has particular endorsement policies.
Considering that, you could say a chaincode belongs to the peers that are member of the channel.
An organization can only interact with a chaincode if it possesses a peer that is member of the channel that has the chaincode.
Answer
You did not provide any information about your channel. Considering you error, I suppose you did not join the OrgCam peer to the channel in which Org1 peer(s) deployed the chaincode.
You OrgCam peer is not part of the channel, you cannot query the chaincode of the channel.
Moreover, you cannot use a OrgCam client certificate to interact with a Org1 peer, because the certificate is not known/accepted by the Org1 peers. Only Org1 explicitly defined clients can interact with org1 peers.
I finally managed to do that.
1.
const result = await contract.evaluateTransaction('getPoints','ID1');
must be changed to:
const result = await contract.submitTransaction('getPoints','ID1');
in order to get the information from peers in an external organization.
2.
If private data are in use, it's important that the fields "memberOnlyRead" and "memberOnlyWrite" (1) must be removed or set to false in the collections_config.json file.
example:
[
{
"name": "collectionFacepoints",
"policy": "OR('Org1MSP.member')",
"requiredPeerCount": 2,
"maxPeerCount": 2,
"blockToLive": 0,
"memberOnlyRead": false
}
]
3.
In the gateway.connect(connectionProfile, connectionOptions) it is important to add discovery.enable=true to the connectionOptions.
example:
await gateway.connect(
connectionProfile,
{
wallet,
identity: identityConfig.identityLabel,
discovery: {
enabled: true,
asLocalhost: true
},
eventHandlerOptions: {
strategy: DefaultEventHandlerStrategies.NETWORK_SCOPE_ALLFORTX
}
}
);
4.
Unfortunately it seems that a client from OrgCam cannot directly query a chaincode installed in org1's peers, but It can be done adding an empty (2) OrgCam's peer that act as an anchor peer.
(1): "memberOnlyWrite" is not available yet. See here.
(2): With "empty" I mean without any chaincode installed on it.

Admin identity error when joining new peers to a channel

I'm really tired with this issue.
Please and Please explain how I can solve this problem to me if you know. I'm begging
I'm working on "Fabcar" sample which has 1 peer / 1 orderer / 1 ca server in the fabric-samples folder.
I wanted to add 2 more peers to the network and join them to the channel(which is called my channel)
So I've modified 3 files: crypto-config.yaml, docker-compose.yml, start.sh (in the basic-network folder) appropriately.
I'm also done producing crypto materials for the new 2 peers with the cryptogen tool.
But the thing is that when I executed "peer channel join -b myblock.block" in peer0.org1.example.com container in order to join those new peers to the channel, this error message is shown:
This error message
It says "JoinChain" request failed authorization check for channel [mychannel]: [Failed verifying that proposal's creator satisfies local MSP principal during channelless check policy with policy [Admins]: [This identity is not an admin]]))
I've also tried that command both inside and outside peer0.org1.example with docker exec command, and did with sudo and nothing works well.
It seems that I need to initiate the transaction with the admin's cert, but I really have no idea how to make it and how to resolve this authorization issue.
Please anyone who knows how to deal with this issue explain this to me in detail.
I've suffered from this problem for a very long time. I'm really desperate.
I'd really appreciate if you tell me how. Looking forward to your response. Thank you.
The error message is the tell: [This identity is not an admin]. You need to be using the identity of the admin for a given peer/org in order to execute the peer channel join command.
The way that cryptogen creates the crypto material is to populate a directory tree of a specific structure. For the admin certificate, you need to be using this identity:
fabric-samples/basic-network/crypto-config/peerOrganizations/org1.example.com/users/Admin#org1.example.com/msp
in order to be the admin for Org1. The script that creates the channel and joins the one peer in the default sample is done with the command here:
https://github.com/hyperledger/fabric-samples/blob/f05a132586ae9ca7ce86b9e56ae4bd3b084bc959/basic-network/start.sh#L26
This issue is due to the access level of the credentials you are using.
You need to be an admin to add a peer to a channel, so you have access to to the system chaincode cscc.
Another possible issue is that in the network configuration (usually the configtx.yaml file) there is some policy resticting your access to join the peer to the channel, if you'd like I can take a look in your configtx file and see if I can help.
As you are using the Fabcar example and it's called with Node SDK you can add the peer also using SDK.
Please try it:
Instantiate a Fabric Client object and enroll an admin user. You can do it in your script based in Fabcar's enrollAdmin.js, as I will explain
In Fabcar's enrollAdmin.js line 72 you can see this line:
console.log('Assigned the admin user to the fabric client ::' + admin_user.toString());
Start from here, inside the "then" that starts in line 71.
You have to enroll the identity as an admin usng the method
fabric_client.setAdminSigningIdentity(pk, cert, MSPID);
The pk parameter is the admin private key, cert is his certificate and the MSPID is the one you specified for his organization in the configtx.yaml file.
you can get the pk and cert using the file system module from Node addins the following:
let fs = require('fs');
let cert = fs.readFileSync(path.join(__dirname, 'PATH_TO_CERT/CERT_NAME.pem'))
let pk = fs.readFileSync(path.join(__dirname, 'PATH_TO_PK','PK_NAME'))
The usual path to the admin certificate is
/fabric-samples/basic-network/crypto-config/peerOrganizations/org1.example.com/users/Admin#org1.example.com/msp/admincerts
And to the private key is:
/fabric-samples/basic-network/crypto-config/peerOrganizations/org1.example.com/users/Admin#org1.example.com/msp/keystore
Now you just added the admin identity to your clients's instance, if everything is ok you need to create a peer instance with your peer's address as the following example:
peer=fabric_client.newPeer(grpc://localhost:7051);
Don't forget to use the grpc protocol, and if tls is enabled you have to use grpcs.
Now create a channel instance of your channel using the channel id as parameter:
let channel_i=fabric_client.newChannel('mychannel')
Then create a request to the channel genesis (config) block:
let orderer = fabric_client.newOrderer(ORDERER_URL);//the urlalso with grpc protocol
let tx_id=fabric.client.newTransactionID(true); //true means it's an administrative request
let g_request={
txId: tx_id,
orderer : orderer
}
Finally, make the block request, then use it to join the channel:
channel_i.getGenesisBlock(g_request).then((block) =>{
tx_id = fabric.client.newTransactionID(true);
let j_request = {
targets : peer,
block : block,
txId : tx_id,
};
// send genesis block to the peer
return channel_i.joinChannel(j_request, 10000).then((results) =>{
if(results[0].response.status == 200) {
// join successful
console.log("Join successful!!!");
} else {
// not good
console.log("Error:: "+ results);
throw results;
}
})
For the admin identity error, copy that identity signedcert into Org MSP admincerts folder and then generate the channel tx file.
This issue could be occurred due to wrong config of CORE_PEER_MSPCONFIGPATH
Please check yaml file. The CORE_PEER_MSPCONFIGPATH should be
/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto-config/peerOrganizations/org1.example.com/users/Admin#org1.example.com/msp
The above org1 is for sample, you can check with your org name.

failed deserializing event creator: [Expected MSP ID Org2MSP, received Org1MSP] while starting rest server in hyperledger

I have setup multichannel in fabric. I am using composer to execute transaction in fabric.
I have 4 Channel in my network.Each channel contains 3 orgnization. When i am running network_setup.sh, it starts fabric network with all organization. However when i am running composer-rest-server, it gives me following error:
2018-01-06 09:32:32.278 UTC [eventhub_producer] Chat -> ERRO 14e1
error during Chat, stopping handler: rpc error: code = Canceled desc =
context canceled 2018-01-06 09:33:09.703 UTC [eventhub_producer]
validateEventMessage -> DEBU 14e2 ValidateEventMessage starts for
signed event 0xc4218f2a80 2018-01-06 09:33:09.703 UTC
[eventhub_producer] Chat -> ERRO 14e3 Error handling message: event
message must be properly signed by an identity from the same
organization as the peer: [failed deserializing event creator:
[Expected MSP ID Org2MSP, received Org1MSP]]
Can someone please help to overcome this?
Firstly, I think the clue is in the error you posted. It says 'Expected MSP ID Org2MSP, received Org1MSP] ' - I suspect therefore that your connection profile information you created as part of your business network cards needs updating to reflect the right MSP - (you have built the appropriate card files and imported them, such as a PeerAdmin card ?)
As shown in the multi-org tutorial https://hyperledger.github.io/composer/tutorials/deploy-to-fabric-multi-org.html you will need a profile for Org1 and a separate Org1 profile to include info from the 'other Orgs'(so will include info about their peers) on that channel / using the business network on that channel (ie whatever channel you've defined - 1 of 4 in our case) - then, further down the line, the same applies for each of the Orgs 1, 2 and 3). So your first port of call is to check your connection profile information in detail (the multi-org tutorial is a good starting point, showing how you connect up the peer information from the other org, 'org2' in org 1's profile - particular for the connection-org1.json sample profile (ie the 2nd profile shown in 'Step 3' of that tutorial). which shows what's required for 'this Orgs' peer and the 'other member's peers' in your multi-org profile.. Other than that, it could be that Fabric crypto (cryptogen) configuration is not set up correctly for your custom multi-org setup. See also the answer here for more information;
Hyperledger Composer BNA deployment results in 'TCP write failed'

Resources