Get transaction details by TxID in hyperledger farbic - hyperledger-fabric

I am currently running hyperledger fabric v2.2. I have developed the chaincode using the contractapi and developing the application using fabric-sdk-go/pkg/gateway
How can i get the transaction status and the transaction payload? I am aware of the GetHistoryByKey() which is available in the contractapi but that doesn't works out for my application.
I know there is hyperledger-explorer which can be used to search transactions by TxID but my use-case is my application will be querying by TxID and then it will verify the status of that particular transaction (TxID).
Also, i have tried to achieve this using the fabsdk but i am getting an error when i try to create instantiate the fabsdk using the fabsdk.New(). There seems to be some compatibility issue with the connection-profile.json which i am using the fabric-sample project.
The error which i am getting is:
failed to create identity manager provider: failed to initialize identity manager for organization: MyOrgName: Either a cryptopath or an embedded list of users is required
The same connection-profile has been used in getting the network up and running, and everything seems to be working all good. I am able to submit and evaluate transactions.
SOLUTION
The system chaincodes are embedded in the peer itself. so we need to set the target otherwise it would just give the discovery error since the contract QSCC is not explicitly deployed on the channel.
Make sure to check the core.yaml file channel.system - the system chaincode should be enabled channel.system.qscc: enable
qsccContract := network.GetContract("qscc")
txn, err := qsccContract.CreateTransaction("GetTransactionByID", gateway.WithEndorsingPeers("peer0.org1.com:8051"))
if err != nil {
fmt.Printf("Failed to create transaction: %s\n", err)
return
}
result, err := txn.Evaluate("mychannel", "4b1175335bdfe074d516a69df180ed6bc14591543eb26c10e21df2c67602b2dc")
if err != nil {
fmt.Printf("Failed to submit transaction: %s\n", err)
return
}
fmt.Println(string(result))
Note: The result needs to decoded to be human readable

Your client application can use the client SDK appropriate to your pogramming language to evaluate the GetTransactionByID transaction function on the qscc system chaincode, which is available on all peers. This transaction function takes a transaction ID as its only argument and returns a peer.ProcessedTransaction protobuf, which contains the transaction envelope and a validation code.

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.

TRANSIENT_FAILURE occurs when a transaction is sent using Gateway that is configured using `WithSDK` in fabric-go-sdk

I'm building a client server to connect with Hyperledger Fabric network using fabric-go-sdk. To use a custom logging system, I get an FabricSDK object using fabsdk.New() then inject it to a Gateway object using gateway.WithSDK function. Check the code below:
ccpPath := getPath("connection-profile.json", staticPath)
sdk, err := fabsdk.New(config.FromFile(ccpPath),
fabsdk.WithLoggerPkg(&FabSDKLoggerProvider{}), // using my custom logging system
)
if err != nil {
return nil, errors.Wrap(err, "failed to create a new fabsdk")
}
gw, err := gateway.Connect(
gateway.WithSDK(sdk),
gateway.WithIdentity(wallet, "admin"),
)
if err != nil {
return nil, errors.Wrap(err, "failed to connect the network via a fabric gateway")
}
When I run a test, I get an error:
Failed to submit: error registering for TxStatus event: could not create client conn: could not connect to peer0.test.bpl:7051: dialing connection on target [peer0.test.bpl:7051]: connection is in TRANSIENT_FAILURE
The test that I ran is a test to send a transaction using the Gateway object and its Submit method.
When I defined a Gateway object without FabricSDK, it works fine. That is, if I use the code below, the test passes well. However, in this case, I cannot use my custom logging system. (I just want to disable Fabric SDK's logging system.)
ccpPath := getPath("connection-profile.json", staticPath)
gw, err := gateway.Connect(
gateway.WithConfig(config.FromFile(ccpPath)),
gateway.WithIdentity(wallet, "admin"),
)
if err != nil {
return nil, errors.Wrap(err, "failed to connect the network via a fabric gateway")
}
According to my investigation, difference between FabricSDK objects initialized by fabsdk.New() and gateway.Connect(gateway.WithConfig()) is that the FabricSDK object that is created by gateway.Connect(gateway.WithConfig()) has the option fabsdk.WithMSPPkg(gw.mspfactory) but the other does not. I try to give the same option to my fabsdk.New() code, I could not find how to do it.
So, my question is:
How can I deal with "TRANSIENT_FAILURE" error, or
How can I disable the Fabric SDK's default logging system?
Thanks.
I just had exactly the same two questions while writing a little sample CLI to get chaincode metadata
How can I deal with "TRANSIENT_FAILURE" error
In my case, the dialing connection on target [peer0.org1.example.com:7051]: connection is in TRANSIENT_FAILURE error was because I was using the Fabric test network docker environment but I had not set the DISCOVERY_AS_LOCALHOST environment variable. DISCOVERY_AS_LOCALHOST determines whether IP addresses found during service discovery are translated from the docker network to the local host, which is described in the Connection Options documentation for developing applications.
How can I disable the Fabric SDK's default logging system?
I still wanted to see error messages but I was able to change the logging level to get rid of unwanted info messages using logging.SetLevel("", logging.ERROR)
The ccmetadata sample is on GitHub if that's any help

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.

Timeout expired while querying large data on Hyperledger Fabric 1.4.1

I am using Hyperledger Fabric 1.4.1, with Kafka ordering service, Couch DB as stateDB, Java chaincode and Java SDK.
I experience timeout expired when I try to send large data to the channel and then query it back.
The data size of the transaction I sent is 512KB, and I can query it from peers.
I tried sending it 7 times with the same id, and I can get all 7 histories with shim function getHistoryForKey. But when I sent it 8 times with the same id, getHistoryForKey failed.
The error message is shown below (from peers):
Error: endorsement failure during query. response: status:500 message:"failed to execute transaction fdfbc5b72efd688136c777f5b114a3cedc62339e42f6c39a27e86ca11b8e3d14: error sending: timeout expired while executing transaction"
I have tried to expand the timeout with following options and their combinations in peer and client:
CORE_CHAINCODE_EXECUTETIMEOUT="120s"
CORE_LEDGER_STATE_COUCHDBCONFIG_REQUESTTIMEOUT="120s"
# (seems this setting is not for Hyperledger Fabric)
CORE_PEER_GRPCOPTIONS_REQUESET_TIMEOUT="120s"
But they didn't help in my case.
I also noticed that the 7 copies of testing data are about 3.5MB, and I tried to query 4MB data (which is about 8 copies) from a peer but failed.
When we check the chaincode runtime docker, we see the following error message:
SEVERE: An error occured on the chaincode stream. Shutting down the chaincode stream.
io.grpc.StatusRuntimeException: RESOURCE_EXHAUSTED:
io.grpc.netty.NettyClientTransport$3: Frame size 6294852 exceeds maximum: 4194304.
It seems like there is a grpc limitation on running the java chaincode docker.
We tested with go chaincode, we do not experience the same issue.
We managed to fix that by overriding the ChaincodeBase class
ManagedChannelBuilder<?> newChannelBuilder() throws IOException {
final NettyChannelBuilder builder = NettyChannelBuilder.forAddress(host, port);
logger.info("Configuring channel connection to peer.");
builder.maxInboundMessageSize(104857600);
logger.info("maxInboundMessageSize is 104857600.");
if (tlsEnabled) {
builder.negotiationType(NegotiationType.TLS);
builder.sslContext(createSSLContext());
} else {
builder.usePlaintext(true);
}
return builder;
}
I have submitted a ticket on fabric Jira to support changing the variable without overriding.

Chaincode events are bugged in hyperledger fabric

Currently chaincode events in hyperledger will only raise duplicate events n number of times, where n is the number of chaincode events in a block and the event raised is the first event in the block.
const profileRegId = this.event_hub.registerChaincodeEvent(request.chaincodeId, "Profile Added", event => {
this.event_hub.unregisterChaincodeEvent(profileRegId);
em.emit(event.payload);
});
Above is how we are calling the registerChaincodeEvent function in our node application.
createEvent(APIstub, "Profile Added", profile)
Above is how we implement in the chaincode.
Is there a way to raise this as a bug with hyperledger myself?
The procedure of opening a new bugs or submitting issues into Hyperledger Fabric is fairly simple, you need to register your linux foundation id (read here the details) and login into https://jira.hyperledger.org/, once done you can open an issue.
While from your description it's not really clear/obvious there is an issue, if you have n valid transactions each has created an event not sure whenever it was expected to have only single notification. Also please note, since release of v1.1.0 of Fabric there is a new event delivery service: FAB-7069 and here some docs about it.
However, if you still think there is a bug or possible improvement, please submit JIRA.

Resources