I'm using the fabcar project: https://github.com/IBM/blockchain-application-using-fabric-java-sdk
I would like to know if there is a way to get the transaction history with a certain key (Not just querying a simple car o listing all of them.
Thank you.
Yes, you have an API called GetHistoryForKey()
You can read more here : How to fetch asset modification history in hyperledger fabric
Here is the process which I have tried and got the result. I have implemented below code in my chaincode.
private Response getQueryHistory(ChaincodeStub chaincodeStub, List<String> args) {
// method for getting the history for key
QueryResultsIterator<KeyModification> queryResults = chaincodeStub.getHistoryForKey(args.get(0));
return newSuccessResponse(prepareJsonFromQueryResult(queryResults));
}
private String prepareJsonFromQueryResult(QueryResultsIterator<KeyModification> queryResults) {
// here build your json object from query result
return "your json object";
}
There are several already implemented method of ChaincodeStub
For more information of method, have look https://hyperledger.github.io/fabric-chaincode-java/release-1.4/api/org/hyperledger/fabric/shim/ChaincodeStub.html
Related
I am trying to join a new organization in a channel of an existing network.
I understood the flow to join an org to a channel from fabric documentation but they did use docker.
I want to accomplish the same using node-sdk.
To get the latest config block of a channel I am using these methods:
<async> getChannelConfig(target, timeout)
<async> getChannelConfigFromOrderer()
https://fabric-sdk-node.github.io/release-1.4/Channel.html#getChannelConfig__anchor
Both are returning the same result. And its type is common.ConfigEnvelope.
It is not common.Block.
It is returning an object according to documentation and I am saving it as a json file.
When I went through it, It doesn't have the below fields which are required for the purpose.
{"channel_group":{"groups":{"Application":{"groups": {
I am attaching the latest block file which I got.
Please tell where I am making the mistake and if there is any reference for this please mention.
Actually, the latest config blocks are protobuf object.
So, when I am trying to save it as json, it was not properly formatted for json.
To do that, first, it has to convert into buffer and save.
// return latest config block as protobuf object
const latestConfig = await getChannelConfigFromOrderer();
const latestConfigBuffer = latestConfig.toBuffer();
// save it in .pb format
fs.writeFileSync("latest-config.pb", latestConfigBuffer);
Then using configtxlator convert it to json and made changes accordingly.
As you know there is chance to have multiple transaction in one block , depend on the batch size and orderer configuration.
I need to make only one call to return all transaction inside the block not one by one.
I could retrieve one transaction with queryTransaction by using fabric SDK.
like
let response_payload = await channel.queryTransaction(trxnID, peer);
First Approach: implement a chanincode function and pass the block number which comes from eventHub along the method then inside the chaincode retrieve all transaction Ids and then make a query to find all transaction then stitch all together as result.
Second Approach:
retrieve the block inside with fabric sdk then parse all signed proposal in the payload of the block content.
Third Approach:
retrieve the block inside with fabric sdk then retrieve the transaction ids or keys in the payload and then make a couch db query to retrieve all content .
Which approach do you think is more reasonable if not what is your suggestion?
If you have a your client set up correctly, there should be a
LedgerClient which has a function like
QueryBlock(blockNumber uint64, options ...ledger.RequestOption) (*common.Block, error)
Once you have the block, you can pull the data out of it
block, _ := QueryBlock(37)
data := block.GetData().GetData()
data is a [][]byte, and each entry is one transaction.
This is more of a call for help with an exception when calling insertEntity().
I'm using Nodejs on Azure and editing in Monaco, and I've NPM-installed the latest version of azure storage.
The exception I encounter is: (full stack trace at the bottom)
Unaught exception: Error: Parameter entityDescriptor.PartitionKey for function entityOperation should be an object at ArgumentValidator._.extend.object
I'm basically taking my object to save, and creating 2 new properties: PartitionKey and RowKey. I give them string values. I'm following the examples. I'm not using entityGenerator, as the samples here don't, whereas the examples on the Azure Node developers portal do. I wouldn't mind using entityGenerator on the storage-specific properties if required, but the samples in the node azure github repo seem to suggest that you can use simple strings. The entityGenerator looks a bit ugly and cumbersome, honestly, as you'd have to code extra around the entity when you bring it back.
How can I adjust my code to solve this problem and call insertEntity() with success?
exports.saveTally = function(tally, callback) {
var tableSvc = getAzureTableService();
tableSvc.createTableIfNotExists("tally", function(error, result, response) {
if (!error) {
tally.PartitionKey="tally";
tally.RowKey = tally.id;
tableSvc.insertEntity("tally", tally, function(error, result, response) {
if (error) {
console.log("*Error saving tally " + error.toString());
}
else {
callback(tally.id);
}
});
}
});}
The location of the Azure storage client library has changed to https://github.com/Azure/azure-storage-node. The samples you’re using are from the old location and from an older version of the library which is why they’re not working. You’ll find updated samples and code at the new location.
In the newer version, an Edm type must be specified for each table entity. This is because type is stored in the storage service and we want to make sure that we are storing what you intend. Each table entity is an object with the form {_:value, $:Edm.Type}.
Entity generator is a convenience feature which makes it simpler to construct table entity objects. We return entities in the form just mentioned and using this convenience feature will not change that in any way.
I am trying to write a plugin that will trigger when an account is created. If there is a originating lead I want to fetch the company name in the lead and put it in the account name field. What I'm not sure how to do is to obtain the information out of the lead entity.
I have the following code (I'll keep updating this)...
Entity member = service.Retrieve("lead",
((EntityReference)account["originatingleadid"]).Id, new ColumnSet(true));
if (member.Attributes.Contains("companyname"))
{
companyName = member.Attributes["companyname"].ToString();
}
if (context.PostEntityImages.Contains("AccountPostImage") &&
context.PostEntityImages["AccountPostImage"] is Entity)
{
accountPostImage = (Entity)context.PostEntityImages["AccountPostImage"];
companyName = "This is a test";
if (companyName != String.Empty)
{
accountPostImage.Attributes["name"] = companyName;
service.Update(account);
}
}
I'm not going to spoil the fun for you just yet but the general idea is to:
Catch the message of Create.
Extract the guid from your Entity (that's your created account).
Obtain the guid from its EntityReference (that's your lead).
Read the appropriate field from it.
Update the name field in your account.
Store the information.
Which of the steps is giving you issues? :)
As always, I recommend using query expressions before fetchXML. YMMV
Is lead connected to the account? Just use the IOrganizationService.Retrieve Method
To retrieve the correct lead (assuming you have the lead id from the account entity)..
Create the organizationService in the execute method of your plugin.
http://msdn.microsoft.com/en-us/library/gg334504.aspx
Also here is a nice example to write the plugin:
http://mscrmkb.blogspot.co.il/2010/11/develop-your-first-plugin-in-crm-2011.html?m=1
Please can someone give me a small sample of how to use the Storage class in LWUIT? I have tried implementing by emulating the system used in the Recipe Hands-on-Lab, but my application does not need to have multiple objects, as it is within the sample.
Recipe sample allows user to add more and more samples, but all I want to do is add ONE entry of information.
Also how do I retrieve the info stored?
com.sun.lwuit.io.Storage.init("MobileApplication1");
if(com.sun.lwuit.io.Storage.isInitialized()) {
com.sun.lwuit.io.Storage.getInstance().writeObject("MobileApplication1","My first string");
String myStr = (String)com.sun.lwuit.io.Storage.getInstance().readObject("MobileApplication1");
System.out.println(myStr);
} else {
System.out.println("Storage not initialized");
}
The above code will create a storage of name 'MobileApplication1', add an object 'My first string' and reads the string.
You can use J2ME record store as well and your record store will always have only 1 record.