1. pii-network

Personally Identifiable Information Network

A business network where members can grant/revoke access to their personal information to other members.

Participant Member

Transaction AuthorizeAccess RevokeAccess

pii

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
describe('#OwnRecordFullAccess', () => {

it('bob should be able to read own data only', () => {

return useIdentity(bobCardName)
.then(() => {
// use a query, bob should only see his own data
return businessNetworkConnection.query('selectMembers')
.then((results) => {
// check results
results.length.should.equal(1);
results[0].getIdentifier().should.equal('bob@email.com');
});
});
});


it('alice should be able to read own data only', () => {

return useIdentity(aliceCardName)
.then(() => {
// use a query, alice should only see her own data
return businessNetworkConnection.query('selectMembers')
.then((results) => {
// check results
results.length.should.equal(1);
results[0].getIdentifier().should.equal('alice@email.com');
});
});
});

});

describe('#ForeignRecordConditionalAccess', () => {

it('bob should be able to read alice data IFF granted access', () => {

return useIdentity(aliceCardName)
.then(() => {

// alice grants access to her data to bob
const authorize = factory.newTransaction('org.acme.pii', 'AuthorizeAccess');
authorize.memberId = 'bob@email.com';
return businessNetworkConnection.submitTransaction(authorize);
})
.then(() => {
return useIdentity(bobCardName);
})
.then(() => {

// use a query, bob should be able to see his own and alice's data
return businessNetworkConnection.query('selectMembers')
.then((results) => {
// check results
results.length.should.equal(2);
});
})
.then(() => {
// switch back to alice
return useIdentity(aliceCardName);
})
.then(() => {

// alice revokes access to her data to bob
const revoke = factory.newTransaction('org.acme.pii', 'RevokeAccess');
revoke.memberId = 'bob@email.com';
return businessNetworkConnection.submitTransaction(revoke);
})
.then(() => {
return useIdentity(bobCardName);
})
.then(() => {

// use a query, bob should now only see his own data
return businessNetworkConnection.query('selectMembers')
.then((results) => {
// check results
results.length.should.equal(1);
});
});
});

2. Trade Network

Trade Network

This Business Network illustrates commodity trading.

Participant Trader

Asset Commodity

Transaction(s) Transaction

Event TradeNotification

trade

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
describe('#tradeCommodity', () => {

it('should be able to trade a commodity', () => {
const factory = businessNetworkConnection.getBusinessNetwork().getFactory();

// create the traders
const dan = factory.newResource(namespace, 'Trader', 'dan@email.com');
dan.firstName = 'Dan';
dan.lastName = 'Selman';

const simon = factory.newResource(namespace, 'Trader', 'simon@email.com');
simon.firstName = 'Simon';
simon.lastName = 'Stone';

// create the commodity
const commodity = factory.newResource(namespace, 'Commodity', 'EMA');
commodity.description = 'Corn';
commodity.mainExchange = 'Euronext';
commodity.quantity = 100;
commodity.owner = factory.newRelationship(namespace, 'Trader', dan.$identifier);

// create the trade transaction
const trade = factory.newTransaction(namespace, 'Trade');
trade.newOwner = factory.newRelationship(namespace, 'Trader', simon.$identifier);
trade.commodity = factory.newRelationship(namespace, 'Commodity', commodity.$identifier);

// the owner should of the commodity should be dan
commodity.owner.$identifier.should.equal(dan.$identifier);

// create the second commodity
const commodity2 = factory.newResource(namespace, 'Commodity', 'XYZ');
commodity2.description = 'Soya';
commodity2.mainExchange = 'Chicago';
commodity2.quantity = 50;
commodity2.owner = factory.newRelationship(namespace, 'Trader', dan.$identifier);

// register for events from the business network
businessNetworkConnection.on('event', (event) => {
console.log( 'Received event: ' + event.getFullyQualifiedIdentifier() + ' for commodity ' + event.commodity.getIdentifier() );
});

// Get the asset registry.
return businessNetworkConnection.getAssetRegistry(namespace + '.Commodity')
.then((assetRegistry) => {

// add the commodities to the asset registry.
return assetRegistry.addAll([commodity,commodity2])
.then(() => {
return businessNetworkConnection.getParticipantRegistry(namespace + '.Trader');
})
.then((participantRegistry) => {
// add the traders
return participantRegistry.addAll([dan, simon]);
})
.then(() => {
// submit the transaction
return businessNetworkConnection.submitTransaction(trade);
})
.then(() => {
return businessNetworkConnection.getAssetRegistry(namespace + '.Commodity');
})
.then((assetRegistry) => {
// re-get the commodity
return assetRegistry.get(commodity.$identifier);
})
.then((newCommodity) => {
// the owner of the commodity should now be simon
newCommodity.owner.$identifier.should.equal(simon.$identifier);
})
.then(() => {
// use a query
return businessNetworkConnection.query('selectCommoditiesByExchange', {exchange : 'Euronext'});
})
.then((results) => {
// check results
results.length.should.equal(1);
results[0].getIdentifier().should.equal('EMA');
})
.then(() => {
// use another query
return businessNetworkConnection.query('selectCommoditiesByOwner', {owner : 'resource:' + simon.getFullyQualifiedIdentifier()});
})
.then((results) => {
// check results
results.length.should.equal(1);
results[0].getIdentifier().should.equal('EMA');
})
.then(() => {
// submit the remove transaction
const remove = factory.newTransaction(namespace, 'RemoveHighQuantityCommodities');
return businessNetworkConnection.submitTransaction(remove);
})
.then(() => {
// use a query
return businessNetworkConnection.query('selectCommodities');
})
.then((results) => {
// check results, should only have 1 commodity left
results.length.should.equal(1);
results[0].getIdentifier().should.equal('XYZ');
});
});
});
});

3. vehicle-lifecycle-network

vehicle-lifecycle-network

This network tracks the Lifecycle of Vehicles from manufacture to being scrapped involving private owners, manufacturers and scrap merchants. A regulator is able to provide oversight throughout this whole process.

Participants AuctionHouse Company Manufacturer PrivateOwner Regulator ScrapMerchant

Assets Order Vehicle

Transactions PlaceOrder UpdateOrderStatus ApplicationForVehicleRegistrationCertificate PrivateVehicleTransfer ScrapVehicle UpdateSuspicious ScrapAllVehiclesByColour SetupDemo

Events PlaceOrderEvent UpdateOrderStatusEvent ScrapVehicleEvent

vehicle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
describe('#placeOrder', function() {
it('should be able to place an order for a vehicle', function() {
return placeOrder()
.then(function() {
return businessNetworkConnection.getAssetRegistry(NS_M + '.Order');
})
.then(function(orderRegistry) {
return orderRegistry.get(orderId);
})
.then(function(order) {
order.orderStatus.should.equal('PLACED');
});
});
});

describe('#updateOrderStatus', function() {
it('should create a vehicle and assign it a VIN number', function() {
return placeOrder()
.then(function() {
return updateOrder();
})
.then(function() {
return businessNetworkConnection.getAssetRegistry(NS_D + '.Vehicle');
})
.then(function(vehicleRegistry) {
return vehicleRegistry.get('VIN_NUMBER');
})
.then(function(vehicle) {
should.exist(vehicle);
vehicle.vehicleStatus.should.equal('OFF_THE_ROAD');
vehicle.vehicleDetails.vin.should.equal('VIN_NUMBER');
});
});

it('should assign an owner to a vehicle and make it active', function() {
const updateOrderStatus = factory.newTransaction(NS_M, 'UpdateOrderStatus');
updateOrderStatus.orderStatus = 'OWNER_ASSIGNED';
updateOrderStatus.vin = 'VIN_NUMBER';
updateOrderStatus.numberPlate = 'NUMBER_PLATE';
updateOrderStatus.v5c = 'V5C';

return placeOrder()
.then(function() {
return updateOrder();
})
.then(function() {
return businessNetworkConnection.getAssetRegistry(NS_M + '.Order');
})
.then(function(orderRegistry) {
return orderRegistry.getAll();
})
.then(function(orders) {
const order = orders[0];
updateOrderStatus.order = factory.newRelationship(NS_M, 'Order', order.getIdentifier());
return businessNetworkConnection.submitTransaction(updateOrderStatus);
})
.then(function() {
return businessNetworkConnection.getAssetRegistry(NS_D + '.Vehicle');
})
.then(function(vehicleRegistry) {
return vehicleRegistry.get('VIN_NUMBER');
})
.then(function(vehicle) {
should.exist(vehicle);
vehicle.vehicleStatus.should.equal('ACTIVE');
vehicle.vehicleDetails.vin.should.equal(updateOrderStatus.vin);
vehicle.owner.getIdentifier().should.equal('dan');
});
});
});

describe('Setup', function() {
describe('#setupDemo', function() {
/**
*
* @param {String} registry - name of a registry
*/
function getAllFromRegistry(type, registry) {
const func = 'get' + type + 'Registry';
return businessNetworkConnection[func](registry)
.then(function(registry) {
return registry.getAll();
});
}

it('should create a scenario', function() {
// submit the transaction
const setupDemo = factory.newTransaction(NS, 'SetupDemo');

return businessNetworkConnection.submitTransaction(setupDemo)
.then(function() {
// (participants) get regulator registry
return getAllFromRegistry('Participant', NS + '.Regulator');
})
.then(function(regulators) {
regulators.length.should.equal(1);
})
.then(function() {
// (participants) get manufacturer registry
return getAllFromRegistry('Participant', NS_M + '.Manufacturer');
})
.then(function(manufacturers) {
manufacturers.length.should.be.above(1);
})
.then(function() {
// (participants) get private owner registry
return getAllFromRegistry('Participant', NS + '.PrivateOwner');
})
.then(function(privateOwners) {
privateOwners.length.should.be.above(10);
})
.then(function() {
// (assets) get vehicles registry
return getAllFromRegistry('Asset', NS_D + '.Vehicle');
})
.then(function(vehicles) {
vehicles.length.should.be.above(10);
});
});
});

});

describe('#privateVehicleTransfer', function() {
it('should be able to transfer a vehicle between two private owners', function() {
const vehicleToTransfer = '123456789';
const owners = ['dan', 'simon'];

let vehicleRegistry;
let privateOwnerRegistry;
let vehicle;

return businessNetworkConnection.getAssetRegistry(NS_D + '.Vehicle')
.then(function(vr) {
vehicleRegistry = vr;
return vehicleRegistry.get(vehicleToTransfer);
})
.then(function(v) {
vehicle = v;
should.not.exist(vehicle.logEntries);
vehicle.owner.getIdentifier().should.equal('dan');
})
.then(function() {
const privateVehicleTransfer = factory.newTransaction(NS_D, 'PrivateVehicleTransfer');
privateVehicleTransfer.vehicle = factory.newRelationship(NS_D, 'Vehicle', vehicle.getIdentifier());
privateVehicleTransfer.seller = vehicle.owner;
privateVehicleTransfer.buyer = factory.newRelationship(NS, 'PrivateOwner', 'simon');

return businessNetworkConnection.submitTransaction(privateVehicleTransfer);
})
.then(function() {
return vehicleRegistry.get(vehicle.getIdentifier());
})
.then(function(newVehicle) {
newVehicle.owner.getIdentifier().should.equal('simon');
should.exist(newVehicle.logEntries);
newVehicle.logEntries.length.should.equal(1);
newVehicle.logEntries[0].buyer.getIdentifier().should.equal('simon');
newVehicle.logEntries[0].seller.getIdentifier().should.equal('dan');
newVehicle.logEntries[0].vehicle.getIdentifier().should.equal(vehicleToTransfer);
});
});
});

describe('ScrapVehicle', function() {
it('should change a vehicles status to SCRAPPED', function() {
const vehicleToScrap = '123456789';

const scrapVehicle = factory.newTransaction(NS_D, 'ScrapVehicle');
scrapVehicle.vehicle = factory.newRelationship(NS_D, 'Vehicle', vehicleToScrap);

return businessNetworkConnection.submitTransaction(scrapVehicle)
.then(function() {
return businessNetworkConnection.getAssetRegistry(NS_D + '.Vehicle');
})
.then(function(assetRegistry) {
return assetRegistry.get(vehicleToScrap);
})
.then(function(vehicle) {
vehicle.vehicleStatus.should.equal('SCRAPPED');
});
});
});

describe('ScrapAllVehiclesByColour', function() {
it('should select vehicles by colour and change vehicles status to SCRAPPED', function() {
// Vehicle with beige colour and id 123456789 resides in reposritory
const vehicleId = '123456789';
const scrapVehicleTransaction = factory.newTransaction(NS_D, 'ScrapAllVehiclesByColour');
scrapVehicleTransaction.colour = 'Beige';
return businessNetworkConnection.submitTransaction(scrapVehicleTransaction)
.then(function() {
return businessNetworkConnection.getAssetRegistry(NS_D + '.Vehicle');
})
.then(function(ar) {
const assetRegistry = ar;
return assetRegistry.get(vehicleId);
})
.then(function(vehicle) {
vehicle.vehicleStatus.should.equal('SCRAPPED');
});

});
});

alltest