mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-22 17:45:10 +00:00
Add missing apps and chaincodes to CI
Adds the apps and chaincodes to linting and testing CI that weren't added before. Linting issues were corrected where necessary to make CI pass. The Basic-Go application and Private-Javascript application are currently disabled pending fixes currently being worked on. Signed-off-by: Brett Logan <brett.t.logan@ibm.com>
This commit is contained in:
parent
8f180cd5a3
commit
11c05fa612
12 changed files with 525 additions and 385 deletions
|
|
@ -7,9 +7,9 @@ SPDX-License-Identifier: Apache-2.0
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
|
@ -18,20 +18,22 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println("============ application-golang starts ============")
|
log.Println("============ application-golang starts ============")
|
||||||
|
|
||||||
|
err := os.Setenv("DISCOVERY_AS_LOCALHOST", "true")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error setting DISCOVERY_AS_LOCALHOST environemnt variable: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
os.Setenv("DISCOVERY_AS_LOCALHOST", "true")
|
|
||||||
wallet, err := gateway.NewFileSystemWallet("wallet")
|
wallet, err := gateway.NewFileSystemWallet("wallet")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to create wallet: %v\n", err)
|
log.Fatalf("Failed to create wallet: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !wallet.Exists("appUser") {
|
if !wallet.Exists("appUser") {
|
||||||
err = populateWallet(wallet)
|
err = populateWallet(wallet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to populate wallet contents: %v\n", err)
|
log.Fatalf("Failed to populate wallet contents: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,57 +52,56 @@ func main() {
|
||||||
gateway.WithIdentity(wallet, "appUser"),
|
gateway.WithIdentity(wallet, "appUser"),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to connect to gateway: %v\n", err)
|
log.Fatalf("Failed to connect to gateway: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
defer gw.Close()
|
defer gw.Close()
|
||||||
|
|
||||||
network, err := gw.GetNetwork("mychannel")
|
network, err := gw.GetNetwork("mychannel")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to get network: %v\n", err)
|
log.Fatalf("Failed to get network: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
contract := network.GetContract("basic")
|
contract := network.GetContract("basic")
|
||||||
|
|
||||||
result, err := contract.EvaluateTransaction("GetAllAssets")
|
result, err := contract.SubmitTransaction("InitLedger")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to evaluate transaction: %v\n", err)
|
log.Fatalf("failed to evaluate transaction: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
fmt.Println(string(result))
|
log.Println(string(result))
|
||||||
|
|
||||||
result, err = contract.SubmitTransaction("CreateAsset", "asset13", "yellow", "Tom", "5", "1300")
|
result, err = contract.EvaluateTransaction("GetAllAssets")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to submit transaction: %v\n", err)
|
log.Fatalf("Failed to evaluate transaction: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
fmt.Println(string(result))
|
log.Println(string(result))
|
||||||
|
|
||||||
|
result, err = contract.SubmitTransaction("CreateAsset", "asset13", "yellow", "5", "Tom", "1300")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to submit transaction: %v", err)
|
||||||
|
}
|
||||||
|
log.Println(string(result))
|
||||||
|
|
||||||
result, err = contract.EvaluateTransaction("ReadAsset", "asset4")
|
result, err = contract.EvaluateTransaction("ReadAsset", "asset4")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to evaluate transaction: %v\n", err)
|
log.Fatalf("Failed to evaluate transaction: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
fmt.Println(string(result))
|
log.Println(string(result))
|
||||||
|
|
||||||
_, err = contract.SubmitTransaction("TransferAsset", "asset1", "Tom")
|
_, err = contract.SubmitTransaction("TransferAsset", "asset1", "Tom")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Failed to submit transaction: %v\n", err)
|
log.Fatalf("Failed to submit transaction: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err = contract.EvaluateTransaction("ReadAsset", "asset1")
|
result, err = contract.EvaluateTransaction("ReadAsset", "asset1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to evaluate transaction: %v\n", err)
|
log.Fatalf("Failed to evaluate transaction: %v", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
fmt.Println(string(result))
|
log.Println(string(result))
|
||||||
fmt.Println("============ application-golang ends ============")
|
log.Println("============ application-golang ends ============")
|
||||||
}
|
}
|
||||||
|
|
||||||
func populateWallet(wallet *gateway.Wallet) error {
|
func populateWallet(wallet *gateway.Wallet) error {
|
||||||
fmt.Println("============ populate wallet starts ============")
|
log.Println("============ Populating wallet ============")
|
||||||
credPath := filepath.Join(
|
credPath := filepath.Join(
|
||||||
"..",
|
"..",
|
||||||
"..",
|
"..",
|
||||||
|
|
@ -127,7 +128,7 @@ func populateWallet(wallet *gateway.Wallet) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(files) != 1 {
|
if len(files) != 1 {
|
||||||
return errors.New("keystore folder should have contain one file")
|
return fmt.Errorf("keystore folder should have contain one file")
|
||||||
}
|
}
|
||||||
keyPath := filepath.Join(keyDir, files[0].Name())
|
keyPath := filepath.Join(keyDir, files[0].Name())
|
||||||
key, err := ioutil.ReadFile(filepath.Clean(keyPath))
|
key, err := ioutil.ReadFile(filepath.Clean(keyPath))
|
||||||
|
|
@ -137,10 +138,5 @@ func populateWallet(wallet *gateway.Wallet) error {
|
||||||
|
|
||||||
identity := gateway.NewX509Identity("Org1MSP", string(cert), string(key))
|
identity := gateway.NewX509Identity("Org1MSP", string(cert), string(key))
|
||||||
|
|
||||||
err = wallet.Put("appUser", identity)
|
return wallet.Put("appUser", identity)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Println("============ populate wallet ends ============")
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
coverage
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
env: {
|
||||||
|
node: true,
|
||||||
|
mocha: true
|
||||||
|
},
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 8,
|
||||||
|
sourceType: 'script'
|
||||||
|
},
|
||||||
|
extends: 'eslint:recommended',
|
||||||
|
rules: {
|
||||||
|
indent: ['error', 'tab'],
|
||||||
|
'linebreak-style': ['error', 'unix'],
|
||||||
|
quotes: ['error', 'single'],
|
||||||
|
semi: ['error', 'always'],
|
||||||
|
'no-unused-vars': ['error', { args: 'none' }],
|
||||||
|
'no-console': 'off',
|
||||||
|
curly: 'error',
|
||||||
|
eqeqeq: 'error',
|
||||||
|
'no-throw-literal': 'error',
|
||||||
|
strict: 'error',
|
||||||
|
'no-var': 'error',
|
||||||
|
'dot-notation': 'error',
|
||||||
|
'no-trailing-spaces': 'error',
|
||||||
|
'no-use-before-define': 'error',
|
||||||
|
'no-useless-call': 'error',
|
||||||
|
'no-with': 'error',
|
||||||
|
'operator-linebreak': 'error',
|
||||||
|
yoda: 'error',
|
||||||
|
'quote-props': ['error', 'as-needed']
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -73,24 +73,26 @@ class Chaincode extends Contract{
|
||||||
|
|
||||||
// CreateAsset - create a new asset, store into chaincode state
|
// CreateAsset - create a new asset, store into chaincode state
|
||||||
async CreateAsset(ctx, assetID, color, size, owner, appraisedValue) {
|
async CreateAsset(ctx, assetID, color, size, owner, appraisedValue) {
|
||||||
const exists = await this.AssetExists(ctx, assetID)
|
const exists = await this.AssetExists(ctx, assetID);
|
||||||
if (exists) {
|
if (exists) {
|
||||||
throw new Error(`The asset ${assetID} already exists`)
|
throw new Error(`The asset ${assetID} already exists`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==== Create asset object and marshal to JSON ====
|
// ==== Create asset object and marshal to JSON ====
|
||||||
let asset = {};
|
let asset = {
|
||||||
asset.docType = 'asset';
|
docType: 'asset',
|
||||||
asset.ID = assetID;
|
assetID: assetID,
|
||||||
asset.color = color;
|
color: color,
|
||||||
asset.size = size;
|
size: size,
|
||||||
asset.owner = owner;
|
owner: owner,
|
||||||
asset.appraisedValue = appraisedValue;
|
appraisedValue: appraisedValue
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// === Save asset to state ===
|
// === Save asset to state ===
|
||||||
await ctx.stub.putState(assetID, Buffer.from(JSON.stringify(asset)));
|
await ctx.stub.putState(assetID, Buffer.from(JSON.stringify(asset)));
|
||||||
let indexName = 'color~name'
|
let indexName = 'color~name';
|
||||||
let colorNameIndexKey = await ctx.stub.createCompositeKey(indexName, [asset.color, asset.ID]);
|
let colorNameIndexKey = await ctx.stub.createCompositeKey(indexName, [asset.color, asset.assetID]);
|
||||||
|
|
||||||
// Save index entry to state. Only the key name is needed, no need to store a duplicate copy of the marble.
|
// Save index entry to state. Only the key name is needed, no need to store a duplicate copy of the marble.
|
||||||
// Note - passing a 'nil' value will effectively delete the key from state, therefore we pass null character as value
|
// Note - passing a 'nil' value will effectively delete the key from state, therefore we pass null character as value
|
||||||
|
|
@ -113,31 +115,31 @@ class Chaincode extends Contract{
|
||||||
throw new Error('Asset name must not be empty');
|
throw new Error('Asset name must not be empty');
|
||||||
}
|
}
|
||||||
|
|
||||||
var exists = await this.AssetExists(ctx, id)
|
let exists = await this.AssetExists(ctx, id);
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
throw new Error(`Asset ${id} does not exist`)
|
throw new Error(`Asset ${id} does not exist`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// to maintain the color~name index, we need to read the asset first and get its color
|
// to maintain the color~name index, we need to read the asset first and get its color
|
||||||
let valAsbytes = await ctx.stub.getState(id); // get the asset from chaincode state
|
let valAsbytes = await ctx.stub.getState(id); // get the asset from chaincode state
|
||||||
let jsonResp = {};
|
let jsonResp = {};
|
||||||
if (!valAsbytes) {
|
if (!valAsbytes) {
|
||||||
jsonResp.error = 'Asset does not exist: ' + name;
|
jsonResp.error = `Asset does not exist: ${id}`;
|
||||||
throw new Error(jsonResp);
|
throw new Error(jsonResp);
|
||||||
}
|
}
|
||||||
let assetJSON = {};
|
let assetJSON;
|
||||||
try {
|
try {
|
||||||
assetJSON = JSON.parse(valAsbytes.toString());
|
assetJSON = JSON.parse(valAsbytes.toString());
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
jsonResp = {};
|
jsonResp = {};
|
||||||
jsonResp.error = 'Failed to decode JSON of: ' + id;
|
jsonResp.error = `Failed to decode JSON of: ${id}`;
|
||||||
throw new Error(jsonResp);
|
throw new Error(jsonResp);
|
||||||
}
|
}
|
||||||
await ctx.stub.deleteState(id); //remove the asset from chaincode state
|
await ctx.stub.deleteState(id); //remove the asset from chaincode state
|
||||||
|
|
||||||
// delete the index
|
// delete the index
|
||||||
let indexName = 'color~name';
|
let indexName = 'color~name';
|
||||||
let colorNameIndexKey = ctx.stub.createCompositeKey(indexName, [assetJSON.color, assetJSON.ID]);
|
let colorNameIndexKey = ctx.stub.createCompositeKey(indexName, [assetJSON.color, assetJSON.assetID]);
|
||||||
if (!colorNameIndexKey) {
|
if (!colorNameIndexKey) {
|
||||||
throw new Error(' Failed to create the createCompositeKey');
|
throw new Error(' Failed to create the createCompositeKey');
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +147,7 @@ class Chaincode extends Contract{
|
||||||
await ctx.stub.deleteState(colorNameIndexKey);
|
await ctx.stub.deleteState(colorNameIndexKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransferAsset transfers an asset by setting a new owner name on the asset
|
// TransferAsset transfers a asset by setting a new owner name on the asset
|
||||||
async TransferAsset(ctx, assetName, newOwner) {
|
async TransferAsset(ctx, assetName, newOwner) {
|
||||||
|
|
||||||
let assetAsBytes = await ctx.stub.getState(assetName);
|
let assetAsBytes = await ctx.stub.getState(assetName);
|
||||||
|
|
@ -195,25 +197,25 @@ class Chaincode extends Contract{
|
||||||
let coloredAssetResultsIterator = await ctx.stub.getStateByPartialCompositeKey('color~name', [color]);
|
let coloredAssetResultsIterator = await ctx.stub.getStateByPartialCompositeKey('color~name', [color]);
|
||||||
|
|
||||||
// Iterate through result set and for each asset found, transfer to newOwner
|
// Iterate through result set and for each asset found, transfer to newOwner
|
||||||
while (true) {
|
|
||||||
let responseRange = await coloredAssetResultsIterator.next();
|
let responseRange = await coloredAssetResultsIterator.next();
|
||||||
|
while (!responseRange.done) {
|
||||||
if (!responseRange || !responseRange.value || !responseRange.value.key) {
|
if (!responseRange || !responseRange.value || !responseRange.value.key) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let objectType;
|
let objectType;
|
||||||
let attributes;
|
let attributes;
|
||||||
({
|
(
|
||||||
objectType,
|
{objectType, attributes} = await ctx.stub.splitCompositeKey(responseRange.value.key)
|
||||||
attributes
|
);
|
||||||
} = await ctx.stub.splitCompositeKey(responseRange.value.key));
|
|
||||||
|
|
||||||
console.log(objectType)
|
console.log(objectType);
|
||||||
let returnedAssetName = attributes[1];
|
let returnedAssetName = attributes[1];
|
||||||
|
|
||||||
// Now call the transfer function for the found asset.
|
// Now call the transfer function for the found asset.
|
||||||
// Re-use the same function that is used to transfer individual assets
|
// Re-use the same function that is used to transfer individual assets
|
||||||
await this.TransferAsset(ctx, returnedAssetName, newOwner);
|
await this.TransferAsset(ctx, returnedAssetName, newOwner);
|
||||||
|
responseRange = await coloredAssetResultsIterator.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -227,8 +229,7 @@ class Chaincode extends Contract{
|
||||||
queryString.selector = {};
|
queryString.selector = {};
|
||||||
queryString.selector.docType = 'asset';
|
queryString.selector.docType = 'asset';
|
||||||
queryString.selector.owner = owner;
|
queryString.selector.owner = owner;
|
||||||
let queryResults = await this.GetQueryResultForQueryString(ctx, JSON.stringify(queryString));
|
return await this.GetQueryResultForQueryString(ctx, JSON.stringify(queryString)); //shim.success(queryResults);
|
||||||
return queryResults; //shim.success(queryResults);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Example: Ad hoc rich query
|
// Example: Ad hoc rich query
|
||||||
|
|
@ -238,8 +239,7 @@ class Chaincode extends Contract{
|
||||||
// If this is not desired, follow the QueryAssetsForOwner example for parameterized queries.
|
// If this is not desired, follow the QueryAssetsForOwner example for parameterized queries.
|
||||||
// Only available on state databases that support rich query (e.g. CouchDB)
|
// Only available on state databases that support rich query (e.g. CouchDB)
|
||||||
async QueryAssets(ctx, queryString) {
|
async QueryAssets(ctx, queryString) {
|
||||||
let queryResults = await this.GetQueryResultForQueryString(ctx, queryString);
|
return await this.GetQueryResultForQueryString(ctx, queryString);
|
||||||
return queryResults;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetQueryResultForQueryString executes the passed in query string.
|
// GetQueryResultForQueryString executes the passed in query string.
|
||||||
|
|
@ -293,8 +293,8 @@ class Chaincode extends Contract{
|
||||||
// GetAssetHistory returns the chain of custody for an asset since issuance.
|
// GetAssetHistory returns the chain of custody for an asset since issuance.
|
||||||
async GetAssetHistory(ctx, assetName) {
|
async GetAssetHistory(ctx, assetName) {
|
||||||
|
|
||||||
const resultsIterator = await ctx.stub.getHistoryForKey(assetName);
|
let resultsIterator = await ctx.stub.getHistoryForKey(assetName);
|
||||||
const results = await this.GetAllResults(resultsIterator, true);
|
let results = await this.GetAllResults(resultsIterator, true);
|
||||||
|
|
||||||
return JSON.stringify(results);
|
return JSON.stringify(results);
|
||||||
}
|
}
|
||||||
|
|
@ -302,39 +302,40 @@ class Chaincode extends Contract{
|
||||||
// AssetExists returns true when asset with given ID exists in world state
|
// AssetExists returns true when asset with given ID exists in world state
|
||||||
async AssetExists(ctx, assetName) {
|
async AssetExists(ctx, assetName) {
|
||||||
// ==== Check if asset already exists ====
|
// ==== Check if asset already exists ====
|
||||||
const assetState = await ctx.stub.getState(assetName);
|
let assetState = await ctx.stub.getState(assetName);
|
||||||
if ( !assetState || assetState.length === 0 ) {
|
return assetState && assetState.length > 0;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async GetAllResults(iterator, isHistory) {
|
async GetAllResults(iterator, isHistory) {
|
||||||
const allResults = [];
|
let allResults = [];
|
||||||
let res = await iterator.next();
|
let res = await iterator.next();
|
||||||
while (!res.done) {
|
while (!res.done) {
|
||||||
const jsonRes = {};
|
if (res.value && res.value.value.toString()) {
|
||||||
|
let jsonRes = {};
|
||||||
if (isHistory) {
|
console.log(res.value.value.toString('utf8'));
|
||||||
jsonRes.TxId = res.value.txId;
|
if (isHistory && isHistory === true) {
|
||||||
|
jsonRes.TxId = res.value.tx_id;
|
||||||
jsonRes.Timestamp = res.value.timestamp;
|
jsonRes.Timestamp = res.value.timestamp;
|
||||||
jsonRes.IsDelete = res.value.isDelete;
|
try {
|
||||||
|
jsonRes.Value = JSON.parse(res.value.value.toString('utf8'));
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
jsonRes.Value = res.value.value.toString('utf8');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.value.value.length > 0) {
|
|
||||||
jsonRes.Record = JSON.parse(res.value.value.toString('utf8'));
|
|
||||||
} else {
|
} else {
|
||||||
jsonRes.Record = {ID: res.value.key};
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonRes.Key = res.value.key;
|
jsonRes.Key = res.value.key;
|
||||||
|
try {
|
||||||
console.log('Result: ' + JSON.stringify(jsonRes));
|
jsonRes.Record = JSON.parse(res.value.value.toString('utf8'));
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
jsonRes.Record = res.value.value.toString('utf8');
|
||||||
|
}
|
||||||
|
}
|
||||||
allResults.push(jsonRes);
|
allResults.push(jsonRes);
|
||||||
|
}
|
||||||
res = await iterator.next();
|
res = await iterator.next();
|
||||||
}
|
}
|
||||||
|
iterator.close();
|
||||||
await iterator.close();
|
|
||||||
return allResults;
|
return allResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -342,42 +343,42 @@ class Chaincode extends Contract{
|
||||||
async InitLedger(ctx) {
|
async InitLedger(ctx) {
|
||||||
const assets = [
|
const assets = [
|
||||||
{
|
{
|
||||||
ID: 'asset1',
|
assetID: 'asset1',
|
||||||
color: 'blue',
|
color: 'blue',
|
||||||
size: 5,
|
size: 5,
|
||||||
owner: 'Tom',
|
owner: 'Tom',
|
||||||
appraisedValue: 100
|
appraisedValue: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: 'asset2',
|
assetID: 'asset2',
|
||||||
color: 'red',
|
color: 'red',
|
||||||
size: 5,
|
size: 5,
|
||||||
owner: 'Brad',
|
owner: 'Brad',
|
||||||
appraisedValue: 100
|
appraisedValue: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: 'asset3',
|
assetID: 'asset3',
|
||||||
color: 'green',
|
color: 'green',
|
||||||
size: 10,
|
size: 10,
|
||||||
owner: 'Jin Soo',
|
owner: 'Jin Soo',
|
||||||
appraisedValue: 200
|
appraisedValue: 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: 'asset4',
|
assetID: 'asset4',
|
||||||
color: 'yellow',
|
color: 'yellow',
|
||||||
size: 10,
|
size: 10,
|
||||||
owner: 'Max',
|
owner: 'Max',
|
||||||
appraisedValue: 200
|
appraisedValue: 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: 'asset5',
|
assetID: 'asset5',
|
||||||
color: 'black',
|
color: 'black',
|
||||||
size: 15,
|
size: 15,
|
||||||
owner: 'Adriana',
|
owner: 'Adriana',
|
||||||
appraisedValue: 250
|
appraisedValue: 250
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: 'asset6',
|
assetID: 'asset6',
|
||||||
color: 'white',
|
color: 'white',
|
||||||
size: 15,
|
size: 15,
|
||||||
owner: 'Michel',
|
owner: 'Michel',
|
||||||
|
|
@ -385,14 +386,14 @@ class Chaincode extends Contract{
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i = 0; i < assets.length; i++) {
|
for (let asset in assets) {
|
||||||
await this.CreateAsset(
|
await this.CreateAsset(
|
||||||
ctx,
|
ctx,
|
||||||
assets[i].ID,
|
asset.assetID,
|
||||||
assets[i].color,
|
asset.color,
|
||||||
assets[i].size,
|
asset.size,
|
||||||
assets[i].owner,
|
asset.owner,
|
||||||
assets[i].appraisedValue
|
asset.appraisedValue
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import { Object, Property } from 'fabric-contract-api';
|
||||||
|
|
||||||
@Object()
|
@Object()
|
||||||
export class Asset {
|
export class Asset {
|
||||||
|
|
||||||
@Property()
|
@Property()
|
||||||
public ID: string;
|
public ID: string;
|
||||||
|
|
||||||
|
|
@ -18,5 +17,4 @@ export class Asset {
|
||||||
|
|
||||||
@Property()
|
@Property()
|
||||||
public OwnerOrg: string;
|
public OwnerOrg: string;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ export class AssetContract extends Contract {
|
||||||
if (exists) {
|
if (exists) {
|
||||||
throw new Error(`The asset ${assetId} already exists`);
|
throw new Error(`The asset ${assetId} already exists`);
|
||||||
}
|
}
|
||||||
const ownerOrg = this.getClientOrgId(ctx);
|
const ownerOrg = AssetContract.getClientOrgId(ctx);
|
||||||
const asset = new Asset();
|
const asset = new Asset();
|
||||||
asset.ID = assetId;
|
asset.ID = assetId;
|
||||||
asset.Value = value;
|
asset.Value = value;
|
||||||
|
|
@ -27,7 +27,7 @@ export class AssetContract extends Contract {
|
||||||
// Create the asset
|
// Create the asset
|
||||||
await ctx.stub.putState(assetId, buffer);
|
await ctx.stub.putState(assetId, buffer);
|
||||||
// Set the endorsement policy of the assetId Key, such that current owner Org Peer is required to endorse future updates
|
// Set the endorsement policy of the assetId Key, such that current owner Org Peer is required to endorse future updates
|
||||||
await this.setAssetStateBasedEndorsement(ctx, asset.ID, [ownerOrg]);
|
await AssetContract.setAssetStateBasedEndorsement(ctx, asset.ID, [ownerOrg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadAsset returns asset with given assetId
|
// ReadAsset returns asset with given assetId
|
||||||
|
|
@ -78,7 +78,7 @@ export class AssetContract extends Contract {
|
||||||
// Update the asset
|
// Update the asset
|
||||||
await ctx.stub.putState(assetId, Buffer.from(JSON.stringify(asset)));
|
await ctx.stub.putState(assetId, Buffer.from(JSON.stringify(asset)));
|
||||||
// Re-Set the endorsement policy of the assetId Key, such that a new owner Org Peer is required to endorse future updates
|
// Re-Set the endorsement policy of the assetId Key, such that a new owner Org Peer is required to endorse future updates
|
||||||
await this.setAssetStateBasedEndorsement(ctx, asset.ID, [newOwnerOrg]);
|
await AssetContract.setAssetStateBasedEndorsement(ctx, asset.ID, [newOwnerOrg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssetExists returns true when asset with given ID exists
|
// AssetExists returns true when asset with given ID exists
|
||||||
|
|
@ -89,14 +89,14 @@ export class AssetContract extends Contract {
|
||||||
|
|
||||||
// setAssetStateBasedEndorsement sets an endorsement policy to the assetId Key
|
// setAssetStateBasedEndorsement sets an endorsement policy to the assetId Key
|
||||||
// setAssetStateBasedEndorsement enforces that the owner Org Peers must endorse future update transactions for the specified assetId Key
|
// setAssetStateBasedEndorsement enforces that the owner Org Peers must endorse future update transactions for the specified assetId Key
|
||||||
private async setAssetStateBasedEndorsement(ctx: Context, assetId: string, ownerOrgs: string[]): Promise<void> {
|
private static async setAssetStateBasedEndorsement(ctx: Context, assetId: string, ownerOrgs: string[]): Promise<void> {
|
||||||
let ep = new KeyEndorsementPolicy();
|
const ep = new KeyEndorsementPolicy();
|
||||||
ep.addOrgs("MEMBER", ...ownerOrgs);
|
ep.addOrgs('MEMBER', ...ownerOrgs);
|
||||||
await ctx.stub.setStateValidationParameter(assetId, ep.getPolicy());
|
await ctx.stub.setStateValidationParameter(assetId, ep.getPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
// getClientOrgId gets the client's OrgId (MSPID)
|
// getClientOrgId gets the client's OrgId (MSPID)
|
||||||
private getClientOrgId(ctx: Context): string {
|
private static getClientOrgId(ctx: Context): string {
|
||||||
return ctx.clientIdentity.getMSPID();
|
return ctx.clientIdentity.getMSPID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,14 @@ jobs:
|
||||||
vmImage: ubuntu-18.04
|
vmImage: ubuntu-18.04
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
Basic-Application-Go:
|
||||||
|
DIRECTORY: asset-transfer-basic
|
||||||
|
LANGUAGE: go
|
||||||
|
TYPE: application
|
||||||
|
Basic-Application-Java:
|
||||||
|
DIRECTORY: asset-transfer-basic
|
||||||
|
LANGUAGE: java
|
||||||
|
TYPE: application
|
||||||
Basic-Application-Javascript:
|
Basic-Application-Javascript:
|
||||||
DIRECTORY: asset-transfer-basic
|
DIRECTORY: asset-transfer-basic
|
||||||
LANGUAGE: javascript
|
LANGUAGE: javascript
|
||||||
|
|
@ -96,18 +104,30 @@ jobs:
|
||||||
DIRECTORY: asset-transfer-basic
|
DIRECTORY: asset-transfer-basic
|
||||||
LANGUAGE: typescript
|
LANGUAGE: typescript
|
||||||
TYPE: chaincode
|
TYPE: chaincode
|
||||||
|
Ledger-Application-Java:
|
||||||
|
DIRECTORY: asset-transfer-ledger-queries
|
||||||
|
LANGUAGE: java
|
||||||
|
TYPE: application
|
||||||
Ledger-Chaincode-Go:
|
Ledger-Chaincode-Go:
|
||||||
DIRECTORY: asset-transfer-ledger-queries
|
DIRECTORY: asset-transfer-ledger-queries
|
||||||
LANGUAGE: go
|
LANGUAGE: go
|
||||||
TYPE: chaincode
|
TYPE: chaincode
|
||||||
PrivateData-Chaincode-Go:
|
Ledger-Chaincode-Javascript:
|
||||||
DIRECTORY: asset-transfer-private-data
|
DIRECTORY: asset-transfer-ledger-queries
|
||||||
LANGUAGE: go
|
LANGUAGE: javascript
|
||||||
TYPE: chaincode
|
TYPE: chaincode
|
||||||
PrivateData-Application-Javascript:
|
PrivateData-Application-Javascript:
|
||||||
DIRECTORY: asset-transfer-private-data
|
DIRECTORY: asset-transfer-private-data
|
||||||
LANGUAGE: javascript
|
LANGUAGE: javascript
|
||||||
TYPE: application
|
TYPE: application
|
||||||
|
PrivateData-Chaincode-Go:
|
||||||
|
DIRECTORY: asset-transfer-private-data
|
||||||
|
LANGUAGE: go
|
||||||
|
TYPE: chaincode
|
||||||
|
SBE-Chaincode-Typescript:
|
||||||
|
DIRECTORY: asset-transfer-sbe
|
||||||
|
LANGUAGE: typescript
|
||||||
|
TYPE: chaincode
|
||||||
Secured-Chaincode-Go:
|
Secured-Chaincode-Go:
|
||||||
DIRECTORY: asset-transfer-secured-agreement
|
DIRECTORY: asset-transfer-secured-agreement
|
||||||
LANGUAGE: go
|
LANGUAGE: go
|
||||||
|
|
@ -158,6 +178,9 @@ jobs:
|
||||||
Ledger-Go:
|
Ledger-Go:
|
||||||
CHAINCODE_NAME: ledger
|
CHAINCODE_NAME: ledger
|
||||||
CHAINCODE_LANGUAGE: go
|
CHAINCODE_LANGUAGE: go
|
||||||
|
Ledger-Javascript:
|
||||||
|
CHAINCODE_NAME: ledger
|
||||||
|
CHAINCODE_LANGUAGE: javascript
|
||||||
steps:
|
steps:
|
||||||
- template: templates/install-deps.yml
|
- template: templates/install-deps.yml
|
||||||
- script: ../ci/scripts/run-test-network-ledger.sh
|
- script: ../ci/scripts/run-test-network-ledger.sh
|
||||||
|
|
@ -179,6 +202,21 @@ jobs:
|
||||||
workingDirectory: test-network
|
workingDirectory: test-network
|
||||||
displayName: Run Test Network Private Chaincode
|
displayName: Run Test Network Private Chaincode
|
||||||
|
|
||||||
|
- job: TestNetworkSBE
|
||||||
|
displayName: Test Network
|
||||||
|
pool:
|
||||||
|
vmImage: ubuntu-18.04
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
SBE-Typescript:
|
||||||
|
CHAINCODE_NAME: sbe
|
||||||
|
CHAINCODE_LANGUAGE: typescript
|
||||||
|
steps:
|
||||||
|
- template: templates/install-deps.yml
|
||||||
|
- script: ../ci/scripts/run-test-network-sbe.sh
|
||||||
|
workingDirectory: test-network
|
||||||
|
displayName: Run Test Network Private Chaincode
|
||||||
|
|
||||||
- job: TestNetworkSecured
|
- job: TestNetworkSecured
|
||||||
displayName: Test Network
|
displayName: Test Network
|
||||||
pool:
|
pool:
|
||||||
|
|
|
||||||
|
|
@ -11,20 +11,42 @@ function print() {
|
||||||
echo -e "${GREEN}${1}${NC}"
|
echo -e "${GREEN}${1}${NC}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createNetwork() {
|
||||||
print "Creating network"
|
print "Creating network"
|
||||||
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
||||||
print "Deploying ${CHAINCODE_NAME} chaincode"
|
print "Deploying ${CHAINCODE_NAME} chaincode"
|
||||||
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}"
|
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopNetwork() {
|
||||||
|
print "Stopping network"
|
||||||
|
./network.sh down
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run Go application
|
||||||
|
#createNetwork
|
||||||
|
#print "Initializing Go application"
|
||||||
|
#pushd ../asset-transfer-basic/application-go
|
||||||
|
#print "Executing AssetTransfer.go"
|
||||||
|
#go run .
|
||||||
|
#popd
|
||||||
|
#stopNetwork
|
||||||
|
|
||||||
|
# Run Java application
|
||||||
|
createNetwork
|
||||||
|
print "Initializing Java application"
|
||||||
|
pushd ../asset-transfer-basic/application-java
|
||||||
|
print "Executing Gradle Run"
|
||||||
|
gradle run
|
||||||
|
popd
|
||||||
|
stopNetwork
|
||||||
|
|
||||||
# Run Javascript application
|
# Run Javascript application
|
||||||
|
createNetwork
|
||||||
print "Initializing Javascript application"
|
print "Initializing Javascript application"
|
||||||
pushd ../asset-transfer-basic/application-javascript
|
pushd ../asset-transfer-basic/application-javascript
|
||||||
npm install
|
npm install
|
||||||
print "Executing app.js"
|
print "Executing app.js"
|
||||||
node app.js
|
node app.js
|
||||||
popd
|
popd
|
||||||
|
stopNetwork
|
||||||
print "Stopping network"
|
|
||||||
./network.sh down
|
|
||||||
rm -R ../asset-transfer-basic/application-javascript/wallet
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
FABRIC_VERSION=${FABRIC_VERSION:-2.2}
|
FABRIC_VERSION=${FABRIC_VERSION:-2.2}
|
||||||
|
CHAINCODE_LANGUAGE=${CHAINCODE_LANGUAGE:-go}
|
||||||
CHAINCODE_NAME=${CHAINCODE_NAME:-ledger}
|
CHAINCODE_NAME=${CHAINCODE_NAME:-ledger}
|
||||||
|
|
||||||
function print() {
|
function print() {
|
||||||
|
|
@ -10,31 +11,33 @@ function print() {
|
||||||
echo -e "${GREEN}${1}${NC}"
|
echo -e "${GREEN}${1}${NC}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createNetwork() {
|
||||||
print "Creating network"
|
print "Creating network"
|
||||||
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
||||||
|
print "Deploying ${CHAINCODE_NAME} chaincode"
|
||||||
|
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}"
|
||||||
|
}
|
||||||
|
|
||||||
print "Deploying ${CHAINCODE_NAME} go chaincode"
|
function stopNetwork() {
|
||||||
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1.0 -ccs 1 -ccl go
|
print "Stopping network"
|
||||||
|
./network.sh down
|
||||||
|
}
|
||||||
|
|
||||||
# Run Javascript application against the go chaincode
|
# Run Java application
|
||||||
|
createNetwork
|
||||||
|
print "Initializing Java application"
|
||||||
|
pushd ../asset-transfer-ledger-queries/application-java
|
||||||
|
print "Executing Gradle Run"
|
||||||
|
gradle run
|
||||||
|
popd
|
||||||
|
stopNetwork
|
||||||
|
|
||||||
|
# Run Javascript application
|
||||||
|
createNetwork
|
||||||
print "Initializing Javascript application"
|
print "Initializing Javascript application"
|
||||||
pushd ../asset-transfer-ledger-queries/application-javascript
|
pushd ../asset-transfer-ledger-queries/application-javascript
|
||||||
npm install
|
npm install
|
||||||
print "Executing app.js"
|
print "Executing app.js"
|
||||||
node app.js
|
node app.js
|
||||||
popd
|
popd
|
||||||
|
stopNetwork
|
||||||
print "Deploying ${CHAINCODE_NAME} javascript chaincode"
|
|
||||||
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 2.0 -ccs 2 -ccl javascript
|
|
||||||
|
|
||||||
# Run Javascript application against the javascript chaincode
|
|
||||||
print "Initializing Javascript application"
|
|
||||||
pushd ../asset-transfer-ledger-queries/application-javascript
|
|
||||||
npm install
|
|
||||||
print "Executing app.js"
|
|
||||||
node app.js skipInit
|
|
||||||
popd
|
|
||||||
|
|
||||||
print "Stopping network"
|
|
||||||
./network.sh down
|
|
||||||
rm -R ../asset-transfer-ledger-queries/application-javascript/wallet
|
|
||||||
|
|
|
||||||
|
|
@ -11,19 +11,24 @@ function print() {
|
||||||
echo -e "${GREEN}${1}${NC}"
|
echo -e "${GREEN}${1}${NC}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createNetwork() {
|
||||||
print "Creating network"
|
print "Creating network"
|
||||||
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
||||||
|
print "Deploying ${CHAINCODE_NAME} chaincode"
|
||||||
|
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}"
|
||||||
|
}
|
||||||
|
|
||||||
print "Deploying private-data ${CHAINCODE_NAME} chaincode"
|
function stopNetwork() {
|
||||||
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}" -ccep "OR('Org1MSP.peer','Org2MSP.peer')" -cccg ../asset-transfer-private-data/chaincode-go/collections_config.json
|
|
||||||
|
|
||||||
# Run Javascript application
|
|
||||||
print "Initializing Javascript application"
|
|
||||||
pushd ../asset-transfer-private-data/application-javascript
|
|
||||||
npm install
|
|
||||||
print "Executing app.js"
|
|
||||||
node app.js
|
|
||||||
popd
|
|
||||||
|
|
||||||
print "Stopping network"
|
print "Stopping network"
|
||||||
./network.sh down
|
./network.sh down
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run Javascript application
|
||||||
|
createNetwork
|
||||||
|
#print "Initializing Javascript application"
|
||||||
|
#pushd ../asset-transfer-private-data/application-javascript
|
||||||
|
#npm install
|
||||||
|
#print "Executing app.js"
|
||||||
|
#node app.js
|
||||||
|
#popd
|
||||||
|
stopNetwork
|
||||||
|
|
|
||||||
28
ci/scripts/run-test-network-sbe.sh
Executable file
28
ci/scripts/run-test-network-sbe.sh
Executable file
|
|
@ -0,0 +1,28 @@
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
FABRIC_VERSION=${FABRIC_VERSION:-2.2}
|
||||||
|
CHAINCODE_LANGUAGE=${CHAINCODE_LANGUAGE:-typescript}
|
||||||
|
CHAINCODE_NAME=${CHAINCODE_NAME:-sbe}
|
||||||
|
|
||||||
|
function print() {
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
NC='\033[0m'
|
||||||
|
echo
|
||||||
|
echo -e "${GREEN}${1}${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function createNetwork() {
|
||||||
|
print "Creating network"
|
||||||
|
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
||||||
|
print "Deploying ${CHAINCODE_NAME} chaincode"
|
||||||
|
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopNetwork() {
|
||||||
|
print "Stopping network"
|
||||||
|
./network.sh down
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run Javascript application
|
||||||
|
createNetwork
|
||||||
|
stopNetwork
|
||||||
|
|
@ -11,11 +11,18 @@ function print() {
|
||||||
echo -e "${GREEN}${1}${NC}"
|
echo -e "${GREEN}${1}${NC}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createNetwork() {
|
||||||
print "Creating network"
|
print "Creating network"
|
||||||
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
./network.sh up createChannel -ca -s couchdb -i "${FABRIC_VERSION}"
|
||||||
|
|
||||||
print "Deploying ${CHAINCODE_NAME} chaincode"
|
print "Deploying ${CHAINCODE_NAME} chaincode"
|
||||||
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}"
|
./network.sh deployCC -ccn "${CHAINCODE_NAME}" -ccv 1 -ccs 1 -ccl "${CHAINCODE_LANGUAGE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopNetwork() {
|
||||||
print "Stopping network"
|
print "Stopping network"
|
||||||
./network.sh down
|
./network.sh down
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run Javascript application
|
||||||
|
createNetwork
|
||||||
|
stopNetwork
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue