Skip to content

Commit eba912b

Browse files
author
Mike Zaccardo
committed
Add interactive asset management demo
This adds an expanded, interactive asset management demo that uses the preexisting example chaincode "asset_management.go". Rather than a single application which performs all of the asset administration, assignments, and transfers, three applications now exist which perform each of those operations. The third application offers a command line interface so the user can actually invoke specific asset transfers of his/her choosing. A detailed description of these applications and their usage can be found in the README. A video demonstration of the applications running can be viewed here: https://www.youtube.com/watch?v=PCZrFAKXlTE. Note that this video link is only present in this description and was not added to any of the committed files. Change-Id: I4da4bcf99c4829c59bd4659954013c4d42d9930f Signed-off-by: Mike Zaccardo <[email protected]>
1 parent de00eaa commit eba912b

File tree

11 files changed

+2118
-0
lines changed

11 files changed

+2118
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
# Hyperledger Fabric - Interactive Asset Management App
2+
3+
## Overview
4+
5+
The *Interactive Asset Management App* consists of three separate applications which test the behavior of the standard *asset management* chaincode example. The apps each bootstrap a non-validating peer and construct fabric confidential transactions to deploy, invoke, and/or query the asset management chaincode as described below.
6+
7+
In particular, we consider a scenario in which we have the following parties:
8+
9+
1. *Alice* is the chaincode deployer, represented by `app1`
10+
2. *Bob* is the chaincode administrator, represented by `app2`
11+
3. *Charlie*, *Dave*, and *Edwina* are asset owners, each represented by a separate instance of `app3`
12+
13+
that interact in the following way:
14+
15+
1. *Alice* deploys and assigns the administrator role to *Bob*
16+
2. *Bob* assigns the assets listed in [assets.txt](app2/assets.txt) to *Charlie*, *Dave*, and *Edwina*
17+
3. *Charlie*, *Dave*, and *Edwina* can transfer the ownership of their assets between each other
18+
19+
In the following sections, we describe in more detail the interactions
20+
described above that the asset management app exercises.
21+
22+
### Alice deploys and assigns the administrator role to Bob via `app1`
23+
24+
The following actions take place:
25+
26+
1. *Alice* obtains, via an out-of-band channel, the ECert of Bob, let us call these certificates *BobCert*
27+
2. Alice constructs a deploy transaction, as described in *application-ACL.md*, setting the transaction metadata to *DER(BobCert)*
28+
3. Alice submits the deploy transaction to the fabric network
29+
30+
*Bob* is now the administrator of the chaincode.
31+
32+
### Bob assigns ownership of all the assets via `app2`
33+
34+
1. *Bob* obtains, via out-of-band channels, the ECerts of *Charlie*, *Dave*, and *Edwina*; let us call these certificates *CharlieCert*, *DaveCert*, and *EdwinaCert*, respectively
35+
2. *Bob* constructs an invoke transaction, as described in *application-ACL.md* using *BobCert* to gain access, to invoke the *assign* function passing as parameters *('ASSET_NAME_HERE', Base64(DER(CharlieCert)))*
36+
3. *Bob* submits the transaction to the fabric network
37+
4. *Bob* repeates the above steps for every asset listed in [assets.txt](app2/assets.txt), rotating between *Charlie*, *Dave*, and *Edwina* as the assigned owner
38+
39+
*Charlie*, *Dave*, and *Edwina* are now each the owners of 1/3 of the assets.
40+
41+
Notice that, to assign ownership of assets, *Bob* has to use *BobCert* to authenticate his invocations.
42+
43+
### Charlie, Dave, and Edwina transfer the ownership of their assets between each other via separate instances of `app3`
44+
45+
1. *Charlie*, *Dave*, and *Edwina* each obtain, via out-of-band channels, the ECerts of the other owners; let us call these certificates *CharlieCert*, *DaveCert*, and *EdwinaCert*, respectively
46+
2. Owner *X* constructs an invoke transaction, as described in *application-ACL.md* using *XCert*, to invoke the *transfer* function passing as parameters *('ASSET_NAME_HERE', Base64(DER(YCert)))*.
47+
3. *X* submits the transaction to the fabric network.
48+
4. These steps can be repeated for any asset to be transferred between any two users *X* -> *Y*, if and only if *X* is the current owner of the asset
49+
50+
*Y* is now the owner of the asset.
51+
52+
Notice that, to transfer the ownership of a given asset, user *X* has to use *XCert* to authenticate his/her invocations.
53+
54+
## How To run the Interactive Asset Management App
55+
56+
In order to run the Interactive Asset Management App, the following steps are required.
57+
58+
### Setup the fabric network and create app's configuration file
59+
60+
Follow the [create](https://github.com/hyperledger/fabric/blob/master/examples/chaincode/go/asset_management/app/README.md#create-apps-configuration-file) and [setup](https://github.com/hyperledger/fabric/blob/master/examples/chaincode/go/asset_management/app/README.md#setup-the-fabric-network) steps from the original asset management demo instructions. Note that the `core.yaml` that is described should be placed in this directory on the CLI node.
61+
62+
### Build the apps
63+
64+
Follow the first two instructions of the [run step](https://github.com/hyperledger/fabric/blob/master/examples/chaincode/go/asset_management/app/README.md#run-the-app) from the original asset management demo instructions, but change into the following directory instead:
65+
66+
```
67+
cd $GOPATH/src/github.com/hyperldger/fabric/examples/chaincode/go/asset_management_interactive
68+
```
69+
70+
Then build all three applications by issuing the following command:
71+
72+
```
73+
./build.sh
74+
```
75+
76+
### Run `app1`
77+
78+
Run `app1` by issuing the following command:
79+
80+
```
81+
cd app1
82+
./app1
83+
```
84+
85+
Wait for `app1` to complete, and note the output value of `ChaincodeName`, which needs to be supplied to the following applications. For the rest of these instructions, we will use `8bc69f84aa55195b9eba6aed6261a01ba528acd3413f37b34df580f96e0d8a525e0fe8d41f967b38f192f7a731d63596eedcbd08ee636afdadb96be02d5d150d` as the `ChaincodeName` value.
86+
87+
### Run `app2`
88+
89+
Run `app2` by issuing the following command:
90+
91+
```
92+
cd ../app2
93+
./app2 8bc69f84aa55195b9eba6aed6261a01ba528acd3413f37b34df580f96e0d8a525e0fe8d41f967b38f192f7a731d63596eedcbd08ee636afdadb96be02d5d150d
94+
```
95+
96+
### Run `app3` for each owner
97+
98+
Run `app3` for each owner by issuing the following commands (note that a separate terminal window for each owner is recommended):
99+
100+
```
101+
cd ../app3
102+
```
103+
104+
Run as *Charlie*:
105+
106+
```
107+
./app3 8bc69f84aa55195b9eba6aed6261a01ba528acd3413f37b34df580f96e0d8a525e0fe8d41f967b38f192f7a731d63596eedcbd08ee636afdadb96be02d5d150d charlie
108+
```
109+
110+
Run as *Dave*:
111+
112+
```
113+
./app3 8bc69f84aa55195b9eba6aed6261a01ba528acd3413f37b34df580f96e0d8a525e0fe8d41f967b38f192f7a731d63596eedcbd08ee636afdadb96be02d5d150d dave
114+
```
115+
116+
Run as *Edwina*:
117+
118+
```
119+
./app3 8bc69f84aa55195b9eba6aed6261a01ba528acd3413f37b34df580f96e0d8a525e0fe8d41f967b38f192f7a731d63596eedcbd08ee636afdadb96be02d5d150d edwina
120+
```
121+
122+
Each app will then provide a simple console interface for perfoming one of two actions: listing owned assets and transferring an asset to another owner.
123+
124+
#### List Assets
125+
126+
List an owner's assets by issuing the `list` command. For example, this is the expected output of *Charlie's* first `list`:
127+
128+
```
129+
charlie$ list
130+
...
131+
'charlie' owns the following 16 assets:
132+
'Lot01: BERNARD LEACH VASE WITH 'LEAPING FISH' DESIGN'
133+
'Lot04: PETER LANYON TREVALGAN'
134+
'Lot07: DAVID BOMBERG MOORISH RONDA, ANDALUCIA'
135+
'Lot10: HAROLD GILMAN INTERIOR (MRS MOUNTER)'
136+
'Lot13: WILLIAM SCOTT, R.A. GIRL SEATED AT A TABLE'
137+
'Lot16: JACK BUTLER YEATS, R.H.A. SLEEP SOUND'
138+
'Lot19: SIR EDUARDO PAOLOZZI, R.A. WEDDING OF THE ROCK AND DYNAMO'
139+
'Lot22: JEAN-MICHEL BASQUIAT AIR POWER'
140+
'Lot25: KENNETH ARMITAGE, R.A. MODEL FOR DIARCHY (SMALL VERSION)'
141+
'Lot28: FRANK AUERBACH E.O.W'S RECLINING HEAD'
142+
'Lot31: SIR EDUARDO PAOLOZZI, R.A. FORMS ON A BOW NO. 2'
143+
'Lot34: MARCEL DUCHAMP WITH HIDDEN NOISE (A BRUIT SECRET)'
144+
'Lot37: FRANCIS PICABIA MENDICA'
145+
'Lot40: DAVID BOMBERG PLAZUELA DE LA PAZ, RONDA'
146+
'Lot43: PATRICK CAULFIELD, R.A., C.B.E. FOYER'
147+
'Lot46: DAMIEN HIRST UNTITLED FISH FOR DAVID'
148+
```
149+
150+
#### Transfer Assets
151+
152+
Transfer an asset to another owner by issuing the `transfer LotXX owner_here` command. For example, this is the command to transfer *Lot01* from *Charlie* to *Dave*.
153+
154+
```
155+
charlie$ transfer Lot01 dave
156+
...
157+
'dave' is the new owner of 'Lot01: BERNARD LEACH VASE WITH 'LEAPING FISH' DESIGN'!
158+
------------- Done!
159+
```
160+
161+
## Compatibility
162+
163+
This demo application has been successfully tested against the
164+
[v0.6.0-preview](https://github.com/hyperledger/fabric/releases/tag/v0.6.0-preview) and
165+
[v0.6.1-preview](https://github.com/hyperledger/fabric/releases/tag/v0.6.1-preview) releases.
166+
167+
## Copyright Note
168+
169+
The new source code files retain `Copyright IBM Corp.` because they are closely adopted from a preexisting example that contains an IBM copyright.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
Copyright IBM Corp. 2016 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"os"
21+
"time"
22+
23+
"github.com/hyperledger/fabric/core/crypto"
24+
pb "github.com/hyperledger/fabric/protos"
25+
"github.com/op/go-logging"
26+
"google.golang.org/grpc"
27+
)
28+
29+
var (
30+
// Logging
31+
appLogger = logging.MustGetLogger("app")
32+
33+
// NVP related objects
34+
peerClientConn *grpc.ClientConn
35+
serverClient pb.PeerClient
36+
37+
// Alice is the deployer
38+
alice crypto.Client
39+
40+
// Bob is the administrator
41+
bob crypto.Client
42+
bobCert crypto.CertificateHandler
43+
)
44+
45+
func deploy() (err error) {
46+
appLogger.Debug("------------- Alice wants to assign the administrator role to Bob;")
47+
// Deploy:
48+
// 1. Alice is the deployer of the chaincode;
49+
// 2. Alice wants to assign the administrator role to Bob;
50+
// 3. Alice obtains, via an out-of-band channel, the ECert of Bob, let us call this certificate *BobCert*;
51+
// 4. Alice constructs a deploy transaction, as described in *application-ACL.md*, setting the transaction
52+
// metadata to *DER(CharlieCert)*.
53+
// 5. Alice submits th e transaction to the fabric network.
54+
55+
resp, err := deployInternal(alice, bobCert)
56+
if err != nil {
57+
appLogger.Errorf("Failed deploying [%s]", err)
58+
return
59+
}
60+
appLogger.Debugf("Resp [%s]", resp.String())
61+
appLogger.Debugf("Chaincode NAME: [%s]-[%s]", chaincodeName, string(resp.Msg))
62+
63+
appLogger.Debug("Wait 60 seconds")
64+
time.Sleep(60 * time.Second)
65+
66+
appLogger.Debug("------------- Done!")
67+
return
68+
}
69+
70+
func testAssetManagementChaincode() (err error) {
71+
// Deploy
72+
err = deploy()
73+
if err != nil {
74+
appLogger.Errorf("Failed deploying [%s]", err)
75+
return
76+
}
77+
78+
appLogger.Debug("Deployed!")
79+
80+
closeCryptoClient(alice)
81+
closeCryptoClient(bob)
82+
83+
return
84+
}
85+
86+
func main() {
87+
// Initialize a non-validating peer whose role is to submit
88+
// transactions to the fabric network.
89+
// A 'core.yaml' file is assumed to be available in the working directory.
90+
if err := initNVP(); err != nil {
91+
appLogger.Debugf("Failed initiliazing NVP [%s]", err)
92+
os.Exit(-1)
93+
}
94+
95+
// Enable fabric 'confidentiality'
96+
confidentiality(true)
97+
98+
// Exercise the 'asset_management' chaincode
99+
if err := testAssetManagementChaincode(); err != nil {
100+
appLogger.Debugf("Failed testing asset management chaincode [%s]", err)
101+
os.Exit(-2)
102+
}
103+
}

0 commit comments

Comments
 (0)