-
Notifications
You must be signed in to change notification settings - Fork 8.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <mike.zaccardo@cloudsoftcorp.com>
- Loading branch information
Mike Zaccardo
committed
Dec 2, 2016
1 parent
de00eaa
commit eba912b
Showing
11 changed files
with
2,118 additions
and
0 deletions.
There are no files selected for viewing
169 changes: 169 additions & 0 deletions
169
examples/chaincode/go/asset_management_interactive/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
# Hyperledger Fabric - Interactive Asset Management App | ||
|
||
## Overview | ||
|
||
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. | ||
|
||
In particular, we consider a scenario in which we have the following parties: | ||
|
||
1. *Alice* is the chaincode deployer, represented by `app1` | ||
2. *Bob* is the chaincode administrator, represented by `app2` | ||
3. *Charlie*, *Dave*, and *Edwina* are asset owners, each represented by a separate instance of `app3` | ||
|
||
that interact in the following way: | ||
|
||
1. *Alice* deploys and assigns the administrator role to *Bob* | ||
2. *Bob* assigns the assets listed in [assets.txt](app2/assets.txt) to *Charlie*, *Dave*, and *Edwina* | ||
3. *Charlie*, *Dave*, and *Edwina* can transfer the ownership of their assets between each other | ||
|
||
In the following sections, we describe in more detail the interactions | ||
described above that the asset management app exercises. | ||
|
||
### Alice deploys and assigns the administrator role to Bob via `app1` | ||
|
||
The following actions take place: | ||
|
||
1. *Alice* obtains, via an out-of-band channel, the ECert of Bob, let us call these certificates *BobCert* | ||
2. Alice constructs a deploy transaction, as described in *application-ACL.md*, setting the transaction metadata to *DER(BobCert)* | ||
3. Alice submits the deploy transaction to the fabric network | ||
|
||
*Bob* is now the administrator of the chaincode. | ||
|
||
### Bob assigns ownership of all the assets via `app2` | ||
|
||
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 | ||
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)))* | ||
3. *Bob* submits the transaction to the fabric network | ||
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 | ||
|
||
*Charlie*, *Dave*, and *Edwina* are now each the owners of 1/3 of the assets. | ||
|
||
Notice that, to assign ownership of assets, *Bob* has to use *BobCert* to authenticate his invocations. | ||
|
||
### Charlie, Dave, and Edwina transfer the ownership of their assets between each other via separate instances of `app3` | ||
|
||
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 | ||
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)))*. | ||
3. *X* submits the transaction to the fabric network. | ||
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 | ||
|
||
*Y* is now the owner of the asset. | ||
|
||
Notice that, to transfer the ownership of a given asset, user *X* has to use *XCert* to authenticate his/her invocations. | ||
|
||
## How To run the Interactive Asset Management App | ||
|
||
In order to run the Interactive Asset Management App, the following steps are required. | ||
|
||
### Setup the fabric network and create app's configuration file | ||
|
||
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. | ||
|
||
### Build the apps | ||
|
||
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: | ||
|
||
``` | ||
cd $GOPATH/src/github.com/hyperldger/fabric/examples/chaincode/go/asset_management_interactive | ||
``` | ||
|
||
Then build all three applications by issuing the following command: | ||
|
||
``` | ||
./build.sh | ||
``` | ||
|
||
### Run `app1` | ||
|
||
Run `app1` by issuing the following command: | ||
|
||
``` | ||
cd app1 | ||
./app1 | ||
``` | ||
|
||
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. | ||
|
||
### Run `app2` | ||
|
||
Run `app2` by issuing the following command: | ||
|
||
``` | ||
cd ../app2 | ||
./app2 8bc69f84aa55195b9eba6aed6261a01ba528acd3413f37b34df580f96e0d8a525e0fe8d41f967b38f192f7a731d63596eedcbd08ee636afdadb96be02d5d150d | ||
``` | ||
|
||
### Run `app3` for each owner | ||
|
||
Run `app3` for each owner by issuing the following commands (note that a separate terminal window for each owner is recommended): | ||
|
||
``` | ||
cd ../app3 | ||
``` | ||
|
||
Run as *Charlie*: | ||
|
||
``` | ||
./app3 8bc69f84aa55195b9eba6aed6261a01ba528acd3413f37b34df580f96e0d8a525e0fe8d41f967b38f192f7a731d63596eedcbd08ee636afdadb96be02d5d150d charlie | ||
``` | ||
|
||
Run as *Dave*: | ||
|
||
``` | ||
./app3 8bc69f84aa55195b9eba6aed6261a01ba528acd3413f37b34df580f96e0d8a525e0fe8d41f967b38f192f7a731d63596eedcbd08ee636afdadb96be02d5d150d dave | ||
``` | ||
|
||
Run as *Edwina*: | ||
|
||
``` | ||
./app3 8bc69f84aa55195b9eba6aed6261a01ba528acd3413f37b34df580f96e0d8a525e0fe8d41f967b38f192f7a731d63596eedcbd08ee636afdadb96be02d5d150d edwina | ||
``` | ||
|
||
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. | ||
|
||
#### List Assets | ||
|
||
List an owner's assets by issuing the `list` command. For example, this is the expected output of *Charlie's* first `list`: | ||
|
||
``` | ||
charlie$ list | ||
... | ||
'charlie' owns the following 16 assets: | ||
'Lot01: BERNARD LEACH VASE WITH 'LEAPING FISH' DESIGN' | ||
'Lot04: PETER LANYON TREVALGAN' | ||
'Lot07: DAVID BOMBERG MOORISH RONDA, ANDALUCIA' | ||
'Lot10: HAROLD GILMAN INTERIOR (MRS MOUNTER)' | ||
'Lot13: WILLIAM SCOTT, R.A. GIRL SEATED AT A TABLE' | ||
'Lot16: JACK BUTLER YEATS, R.H.A. SLEEP SOUND' | ||
'Lot19: SIR EDUARDO PAOLOZZI, R.A. WEDDING OF THE ROCK AND DYNAMO' | ||
'Lot22: JEAN-MICHEL BASQUIAT AIR POWER' | ||
'Lot25: KENNETH ARMITAGE, R.A. MODEL FOR DIARCHY (SMALL VERSION)' | ||
'Lot28: FRANK AUERBACH E.O.W'S RECLINING HEAD' | ||
'Lot31: SIR EDUARDO PAOLOZZI, R.A. FORMS ON A BOW NO. 2' | ||
'Lot34: MARCEL DUCHAMP WITH HIDDEN NOISE (A BRUIT SECRET)' | ||
'Lot37: FRANCIS PICABIA MENDICA' | ||
'Lot40: DAVID BOMBERG PLAZUELA DE LA PAZ, RONDA' | ||
'Lot43: PATRICK CAULFIELD, R.A., C.B.E. FOYER' | ||
'Lot46: DAMIEN HIRST UNTITLED FISH FOR DAVID' | ||
``` | ||
|
||
#### Transfer Assets | ||
|
||
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*. | ||
|
||
``` | ||
charlie$ transfer Lot01 dave | ||
... | ||
'dave' is the new owner of 'Lot01: BERNARD LEACH VASE WITH 'LEAPING FISH' DESIGN'! | ||
------------- Done! | ||
``` | ||
|
||
## Compatibility | ||
|
||
This demo application has been successfully tested against the | ||
[v0.6.0-preview](https://github.com/hyperledger/fabric/releases/tag/v0.6.0-preview) and | ||
[v0.6.1-preview](https://github.com/hyperledger/fabric/releases/tag/v0.6.1-preview) releases. | ||
|
||
## Copyright Note | ||
|
||
The new source code files retain `Copyright IBM Corp.` because they are closely adopted from a preexisting example that contains an IBM copyright. |
103 changes: 103 additions & 0 deletions
103
examples/chaincode/go/asset_management_interactive/app1/app1.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/* | ||
Copyright IBM Corp. 2016 All Rights Reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package main | ||
|
||
import ( | ||
"os" | ||
"time" | ||
|
||
"github.com/hyperledger/fabric/core/crypto" | ||
pb "github.com/hyperledger/fabric/protos" | ||
"github.com/op/go-logging" | ||
"google.golang.org/grpc" | ||
) | ||
|
||
var ( | ||
// Logging | ||
appLogger = logging.MustGetLogger("app") | ||
|
||
// NVP related objects | ||
peerClientConn *grpc.ClientConn | ||
serverClient pb.PeerClient | ||
|
||
// Alice is the deployer | ||
alice crypto.Client | ||
|
||
// Bob is the administrator | ||
bob crypto.Client | ||
bobCert crypto.CertificateHandler | ||
) | ||
|
||
func deploy() (err error) { | ||
appLogger.Debug("------------- Alice wants to assign the administrator role to Bob;") | ||
// Deploy: | ||
// 1. Alice is the deployer of the chaincode; | ||
// 2. Alice wants to assign the administrator role to Bob; | ||
// 3. Alice obtains, via an out-of-band channel, the ECert of Bob, let us call this certificate *BobCert*; | ||
// 4. Alice constructs a deploy transaction, as described in *application-ACL.md*, setting the transaction | ||
// metadata to *DER(CharlieCert)*. | ||
// 5. Alice submits th e transaction to the fabric network. | ||
|
||
resp, err := deployInternal(alice, bobCert) | ||
if err != nil { | ||
appLogger.Errorf("Failed deploying [%s]", err) | ||
return | ||
} | ||
appLogger.Debugf("Resp [%s]", resp.String()) | ||
appLogger.Debugf("Chaincode NAME: [%s]-[%s]", chaincodeName, string(resp.Msg)) | ||
|
||
appLogger.Debug("Wait 60 seconds") | ||
time.Sleep(60 * time.Second) | ||
|
||
appLogger.Debug("------------- Done!") | ||
return | ||
} | ||
|
||
func testAssetManagementChaincode() (err error) { | ||
// Deploy | ||
err = deploy() | ||
if err != nil { | ||
appLogger.Errorf("Failed deploying [%s]", err) | ||
return | ||
} | ||
|
||
appLogger.Debug("Deployed!") | ||
|
||
closeCryptoClient(alice) | ||
closeCryptoClient(bob) | ||
|
||
return | ||
} | ||
|
||
func main() { | ||
// Initialize a non-validating peer whose role is to submit | ||
// transactions to the fabric network. | ||
// A 'core.yaml' file is assumed to be available in the working directory. | ||
if err := initNVP(); err != nil { | ||
appLogger.Debugf("Failed initiliazing NVP [%s]", err) | ||
os.Exit(-1) | ||
} | ||
|
||
// Enable fabric 'confidentiality' | ||
confidentiality(true) | ||
|
||
// Exercise the 'asset_management' chaincode | ||
if err := testAssetManagementChaincode(); err != nil { | ||
appLogger.Debugf("Failed testing asset management chaincode [%s]", err) | ||
os.Exit(-2) | ||
} | ||
} |
Oops, something went wrong.