Skip to content
This repository has been archived by the owner on Jan 22, 2020. It is now read-only.

Tuna history #107

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions LFS171x/fabric-material/chaincode/tuna-app/tuna-chaincode.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"encoding/json"
"fmt"
"strconv"
"time"

"github.com/hyperledger/fabric/core/chaincode/shim"
sc "github.com/hyperledger/fabric/protos/peer"
Expand Down Expand Up @@ -68,6 +69,8 @@ func (s *SmartContract) Invoke(APIstub shim.ChaincodeStubInterface) sc.Response
return s.queryAllTuna(APIstub)
} else if function == "changeTunaHolder" {
return s.changeTunaHolder(APIstub, args)
} else if function == "queryTunaHistory" {
return s.queryTunaHistory(APIstub, args)
}

return shim.Error("Invalid Smart Contract function name.")
Expand Down Expand Up @@ -222,6 +225,73 @@ func (s *SmartContract) changeTunaHolder(APIstub shim.ChaincodeStubInterface, ar
return shim.Success(nil)
}

/*
* The queryTunaHistory method *
Used to view the transcation history of one particular tuna
It takes one argument -- the key for the tuna in question
*/
func (s *SmartContract) queryTunaHistory(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {

if len(args) != 1 {
return shim.Error("Incorrect number of arguments. Expecting 1")
}

resultsIterator, err := APIstub.GetHistoryForKey(args[0])
if err != nil {
return shim.Error(err.Error())
}
defer resultsIterator.Close()

// buffer is a JSON array containing QueryResults
var buffer bytes.Buffer
buffer.WriteString("[")

bArrayMemberAlreadyWritten := false
for resultsIterator.HasNext() {
queryResponse, err := resultsIterator.Next()
if err != nil {
return shim.Error(err.Error())
}
// Add comma before array members,suppress it for the first array member
if bArrayMemberAlreadyWritten == true {
buffer.WriteString(",")
}

buffer.WriteString("{\"TxId\":")
buffer.WriteString("\"")
buffer.WriteString(queryResponse.TxId)
buffer.WriteString("\"")

buffer.WriteString(", \"Value\":")
// if it was a delete operation on given key, then we need to set the
//corresponding value null. Else, we will write the response.Value
//as-is (as the Value itself a JSON marble)
if queryResponse.IsDelete {
buffer.WriteString("null")
} else {
buffer.WriteString(string(queryResponse.Value))
}

buffer.WriteString(", \"Timestamp\":")
buffer.WriteString("\"")
buffer.WriteString(time.Unix(queryResponse.Timestamp.Seconds, 0).String())
buffer.WriteString("\"")

buffer.WriteString(", \"IsDelete\":")
buffer.WriteString("\"")
buffer.WriteString(strconv.FormatBool(queryResponse.IsDelete))
buffer.WriteString("\"")

buffer.WriteString("}")
bArrayMemberAlreadyWritten = true
}
buffer.WriteString("]")

fmt.Printf("- queryTunaHistory:\n%s\n", buffer.String())

return shim.Success(buffer.Bytes())
}

/*
* main function *
calls the Start function
Expand Down
19 changes: 19 additions & 0 deletions LFS171x/fabric-material/tuna-app/client/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,19 @@ app.controller('appController', function($scope, appFactory){
});
}

$scope.queryTunaHistory = function () {

var id = $scope.tuna_id_history;

appFactory.queryTunaHistory(id, function (data) {

var array = [];
for (var i = 0; i < data.length; i++) {
array.push(data[i]);
}
$scope.query_tuna_history = array;
});
}
});

// Angular Factory
Expand Down Expand Up @@ -106,6 +119,12 @@ app.factory('appFactory', function($http){
});
}

factory.queryTunaHistory = function (id, callback) {
$http.get('/get_tuna_history/' + id).success(function (output) {
callback(output)
});
}

return factory;
});

Expand Down
26 changes: 26 additions & 0 deletions LFS171x/fabric-material/tuna-app/client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,32 @@ <h5 style="color:red;margin-bottom:2%" id="error_query">Error: Please enter a va
</tr>
</table>

<div class="form-group">
<label>History of a Specific Tuna Catch</label><br>

Enter a catch number: <input id="createName" class="form-control" type="text" placeholder="Ex: 3" ng-model="tuna_id_history">
<input id="querySubmit" type="submit" value="Query" class="btn btn-primary" ng-click="queryTunaHistory()">
</div>

<table id="query_tuna_history" class="table" align="center">

<tr>
<th>TxID</th>
<th>Vessel</th>
<th>Location</th>
<th>Holder</th>
<th>Timestamp</th>
</tr>

<tr ng-repeat="tuna in query_tuna_history">
<td>{{tuna.TxId}}</td>
<td>{{tuna.Value.vessel}}</td>
<td>{{tuna.Value.location}}</td>
<td>{{tuna.Value.holder}}</td>
<td>{{tuna.Timestamp}}</td>
</tr>
</table>

<div class="form-group">
<label>Create Tuna Record</label>
<h5 style="color:green;margin-bottom:2%" id="success_create">Success! Tx ID: {{create_tuna}}</h5>
Expand Down
73 changes: 73 additions & 0 deletions LFS171x/fabric-material/tuna-app/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,79 @@ return{
res.send("Error: no tuna catch found");
});

},
get_tuna_history: function (req, res) {

var fabric_client = new Fabric_Client();
var key = req.params.id

// setup the fabric network
var channel = fabric_client.newChannel('mychannel');
var peer = fabric_client.newPeer('grpc://localhost:7051');
channel.addPeer(peer);

//
var member_user = null;
var store_path = path.join(os.homedir(), '.hfc-key-store');
console.log('Store path:' + store_path);
var tx_id = null;

// create the key value store as defined in the fabric-client/config/default.json 'key-value-store' setting
Fabric_Client.newDefaultKeyValueStore({
path: store_path
}).then((state_store) => {
// assign the store to the fabric client
fabric_client.setStateStore(state_store);
var crypto_suite = Fabric_Client.newCryptoSuite();
// use the same location for the state store (where the users' certificate are kept)
// and the crypto store (where the users' keys are kept)
var crypto_store = Fabric_Client.newCryptoKeyStore({
path: store_path
});
crypto_suite.setCryptoKeyStore(crypto_store);
fabric_client.setCryptoSuite(crypto_suite);

// get the enrolled user from persistence, this user will sign all requests
return fabric_client.getUserContext('user1', true);
}).then((user_from_store) => {
if (user_from_store && user_from_store.isEnrolled()) {
console.log('Successfully loaded user1 from persistence');
member_user = user_from_store;
} else {
throw new Error('Failed to get user1.... run registerUser.js');
}

// queryTuna - requires 1 argument, ex: args: ['4'],
const request = {
chaincodeId: 'tuna-app',
txId: tx_id,
fcn: 'queryTunaHistory',
args: [key]
};

// send the query proposal to the peer
return channel.queryByChaincode(request);
}).then((query_responses) => {
console.log("Query has completed, checking results");
console.log("Full result" + query_responses);
// query_responses could have more than one results if there multiple peers were used as targets
if (query_responses && query_responses.length == 1) {
if (query_responses[0] instanceof Error) {
console.error("error from query = ", query_responses[0]);
res.send("Could not locate tuna")

} else {
console.log("Response is ", query_responses[0].toString());
res.send(query_responses[0].toString())
}
} else {
console.log("No payloads were returned from query");
res.send("Could not locate tuna")
}
}).catch((err) => {
console.error('Failed to query successfully :: ' + err);
res.send("Could not locate tuna")
});
}

}
Expand Down
3 changes: 3 additions & 0 deletions LFS171x/fabric-material/tuna-app/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ module.exports = function(app){
app.get('/change_holder/:holder', function(req, res){
tuna.change_holder(req, res);
});
app.get('/get_tuna_history/:id', function (req, res) {
tuna.get_tuna_history(req, res);
});
}
85 changes: 85 additions & 0 deletions LFS171x/fabric-material/tuna-app/src/queryTunaHistory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
'use strict';
/*
* SPDX-License-Identifier: Apache-2.0

Hyperledger Fabric Sample Query Program for tuna-app: Chaincode Invoke

This code is based on code written by the Hyperledger Fabric community.
Original code can be found here: https://github.com/hyperledger/fabric-samples/blob/release/fabcar/query.js
*/

var Fabric_Client = require('fabric-client');
var path = require('path');
var util = require('util');
var os = require('os');

var fabric_client = new Fabric_Client();
var key = req.params.id

// setup the fabric network
var channel = fabric_client.newChannel('mychannel');
var peer = fabric_client.newPeer('grpc://localhost:7051');
channel.addPeer(peer);

//
var member_user = null;
var store_path = path.join(os.homedir(), '.hfc-key-store');
console.log('Store path:' + store_path);
var tx_id = null;

// create the key value store as defined in the fabric-client/config/default.json 'key-value-store' setting
Fabric_Client.newDefaultKeyValueStore({
path: store_path
}).then((state_store) => {
// assign the store to the fabric client
fabric_client.setStateStore(state_store);
var crypto_suite = Fabric_Client.newCryptoSuite();
// use the same location for the state store (where the users' certificate are kept)
// and the crypto store (where the users' keys are kept)
var crypto_store = Fabric_Client.newCryptoKeyStore({
path: store_path
});
crypto_suite.setCryptoKeyStore(crypto_store);
fabric_client.setCryptoSuite(crypto_suite);

// get the enrolled user from persistence, this user will sign all requests
return fabric_client.getUserContext('user1', true);
}).then((user_from_store) => {
if (user_from_store && user_from_store.isEnrolled()) {
console.log('Successfully loaded user1 from persistence');
member_user = user_from_store;
} else {
throw new Error('Failed to get user1.... run registerUser.js');
}

// queryTuna - requires 1 argument, ex: args: ['4'],
const request = {
chaincodeId: 'tuna-app',
txId: tx_id,
fcn: 'queryTunaHistory',
args: [key]
};

// send the query proposal to the peer
return channel.queryByChaincode(request);
}).then((query_responses) => {
console.log("Query has completed, checking results");
console.log("Full result" + query_responses);
// query_responses could have more than one results if there multiple peers were used as targets
if (query_responses && query_responses.length == 1) {
if (query_responses[0] instanceof Error) {
console.error("error from query = ", query_responses[0]);
res.send("Could not locate tuna")

} else {
console.log("Response is ", query_responses[0].toString());
res.send(query_responses[0].toString())
}
} else {
console.log("No payloads were returned from query");
res.send("Could not locate tuna")
}
}).catch((err) => {
console.error('Failed to query successfully :: ' + err);
res.send("Could not locate tuna")
});