Welcome to Part 2 of the Hyperledger Composer Composite Journey. This is a continuation of Composer Network Setup journey. This journey introduces more complexity in using Composer to define your smart contract. You will learn how to add multiple participants and add access control to your blockchain application. To do that - you will create an interactive, distributed, product auction demo network. You will list assets for sale (setting a reserve price) and watch as assets that have met their reserve price are automatically transferred to the highest bidder at the end of the auction. Also each participant will have different level of access permissions depending on the Access Control Rules (ACL) in permissions.acl
file. Access Control Lists (ACL) are the settings for sharing and privacy, which are automatically enforced by the Fabric Composer runtime.
This business network defines:
Participants:
Member
Seller
Assets:
Product
ProductListing
Transactions:
AddProduct
StartBidding
Offer
CloseBidding
The addProduct
function is called when an AddProduct
transaction is submitted. The logic allows a seller to create a product asset and update its registry.
The publishListing
function is called when a StartBidding
transaction is submitted by the owner of product. The logic allows a seller to create a smart contract in the form of product listing for their product with a reserve bid.
The makeOffer
function is called when an Offer
transaction is submitted. The logic simply checks that the listing for the offer is still for sale, and then adds the offer to the listing, and then updates the offers in the ProductListing
asset registry.
The closeBidding
function is called when a CloseBidding
transaction is submitted for processing. The logic checks that the listing is still for sale, sort the offers by bid price, and then if the reserve has been met, transfers the ownership of the product associated with the listing to the highest bidder. Money is transferred from the buyer's account to the seller's account, and then all the modified assets are updated in their respective registries.
product.cto
file present in models
directory defines a data model for the product auction demo which consists the definition for assets, participants and transactions. logic.js
file present in lib
directory implement the transactions defined in the product.cto
file. Recall that the .cto
file defines the structure of your business network in terms of Assets, Participants and Transactions.
ACL rules are present in permissions.acl
file to determine which user/role is permitted to create, read, update or delete an element in the business network's domain model. The default System
user has all the permissions. Members of the network have read access to all the resources and the seller can create a product, start and close the bidding for their products. Members of the network can make their bid for the product listing. Participants can access only permitted resources and transactions.
- Hyperledger Fabric
- Hyperledger Composer
- Docker
Creating multiple participants and adding ACL
- Adding additional participants
- Adding Access Control Lists
- Querying and invoking the Chaincode
- Generate the Business Network Archive (BNA)
- Deploy the Business Network Archive using Composer Playground
- Deploy the Business Network Archive on Hyperledger Composer running locally
To check that the structure of the files is valid, you can now generate a Business Network Archive (BNA) file for your business network definition. The BNA file is the deployable unit -- a file that can be deployed to the Composer runtime for execution.
Use the following command to generate the network archive:
npm install
You should see the following output:
> mkdirp ./dist && composer archive create --sourceType dir --sourceName . -a ./dist/product-auction.bna
Creating Business Network Archive
Looking for package.json of Business Network Definition
Input directory: /Users/ishan/Documents/git-demo/BlockchainBalanceTransfer-CompositeJourney
Found:
Description: Sample product auction network
Name: product-auction
Identifier: product-auction@0.0.1
Written Business Network Definition Archive file to
Output file: ./dist/product-auction.bna
Command succeeded
The composer archive create
command has created a file called product-auction.bna
in the dist
folder.
You can test the business network definition against the embedded runtime that stores the state of 'the blockchain' in-memory in a Node.js process. From your project working directory, open the file test/productAuction.js and run the following command:
npm test
You should see the following output :
> product-auction@0.0.1 test /Users/ishan/Documents/git-demo/BlockchainBalanceTransfer-CompositeJourney
> mocha --recursive
ProductAuction - AddProduct Test
#BiddingProcess
✓ Add the product to seller list (119ms)
✓ Authorized owner should start the bidding (90ms)
✓ Members bid for the product (127ms)
✓ Close bid for the product (53ms)
4 passing (2s)
Open Composer Playground, by default the Basic Sample Network is imported.
If you have previously used Playground, be sure to clear your browser local storage by running localStorage.clear()
in your browser Console. Now import the product-auction.bna
file and click on deploy button.
To test this Business Network Definition in the Test tab:
In the Seller
participant registry, create a new participant. Make sure you click on the Seller
tab on the far left-hand side.
{
"$class": "org.acme.product.auction.Seller",
"organisation": "ACME",
"email": "auction@acme.org",
"balance": 100,
"products": []
}
In the Member
participant registry, create two participants. Again, click on the Member
tab on the far left-hand side.
{
"$class": "org.acme.product.auction.Member",
"firstName": "Amy",
"lastName": "Williams",
"email": "memberA@acme.org",
"balance": 1000,
"products": []
}
{
"$class": "org.acme.product.auction.Member",
"firstName": "Billy",
"lastName": "Thompson",
"email": "memberB@acme.org",
"balance": 1000,
"products": []
}
Now we are ready to add Access Control. Do this by first clicking on the admin
tab to issue new ids to the participants and add the ids to the wallet.
Please follow the instructions as shown in the images below:
- Click +add to my Wallet under Option 2 to actually add to your wallet.
Select the seller id
from Wallet tab
tab. Now click on the test tab
to perform AddProduct
and StartBidding
transactions.
Now click on Submit Transaction
button and select AddProduct
transaction from the dropdown, to create a product for the seller.
{
"$class": "org.acme.product.auction.AddProduct",
"description": "Sample Product",
"owner": "resource:org.acme.product.auction.Seller#auction@acme.org"
}
You can verify the transaction by checking the product and seller registry.
To create a product listing for the above product, copy the ProductID
from the product registry. Then submit StartBidding
transaction. Remember to replace <ProductID>
with the product id you just copied.
{
"$class": "org.acme.product.auction.StartBidding",
"reservePrice": 50,
"product": "resource:org.acme.product.auction.Product#<ProductID>"
}
You've just listed Sample Product
for auction, with a reserve price of 50!
A listing has been created in ProductListing
registry for the product with FOR_SALE
state.
Now Member participants can submit Offer
transactions to bid on a product listing.
For each member id
, select the user id from the Wallet tab
. To submit an Offer
transaction select the test tab
and click on Submit Transaction
button.
ListingID
is the id of the listing copied from theProductListing
registry.
{
"$class": "org.acme.product.auction.Offer",
"bidPrice": 50,
"listing": "resource:org.acme.product.auction.ProductListing#<ListingID>",
"member": "resource:org.acme.product.auction.Member#memberA@acme.org"
}
{
"$class": "org.acme.product.auction.Offer",
"bidPrice": 100,
"listing": "resource:org.acme.product.auction.ProductListing#<ListingID>",
"member": "resource:org.acme.product.auction.Member#memberB@acme.org"
}
You can check the ProductListing
registry, to view all the bids for the product.
Now again select the seller id
from the Wallet tab
tab. Click on test tab
to end the auction by submitting a CloseBidding
transaction for the listing.
{
"$class": "org.acme.product.auction.CloseBidding",
"listing": "resource:org.acme.product.auction.ProductListing#<ListingID>"
}
This simply indicates that the auction for ListingID
is now closed, triggering the closeBidding
function that was described above.
To check whether the Product is sold you need to click on the ProductListing
asset registry and check the owner of the product. The highest bid was placed by owner memberB@acme.org
, so memberB@acme.org
should be the owner of the product.
You can check the state of the ProductListing with <ListingID>
is SOLD
.
Click on the Member
asset registry to verify the updated balance for buyer and seller. The product is added to the product list of the buyer memberB@acme.org
.
You can view history of all transactions by selecting the All transactions
tab.
You can also use the default
System user
to perform all the actions as we have a rule inpermissions.acl
to permit all accessSystem user
.
Please start the local Fabric using the instructions.
Now change directory to the dist
folder containing product-auction.bna
file and type:
cd dist
composer network deploy -a product-auction.bna -p hlfv1 -i PeerAdmin -s randomString -A admin -S
After sometime time business netwokr should be deployed to the local Hyperledger Fabric. You should see the output as follows:
Deploying business network from archive: product-auction.bna
Business network definition:
Identifier: product-auction@0.0.1
Description: Sample product auction network
✔ Deploying business network definition. This may take a minute...
Command succeeded
You can verify that the network has been deployed by typing:
composer network ping -n product-auction -p hlfv1 -i admin -s adminpw
To create the REST API we need to launch the composer-rest-server
and tell it how to connect to our deployed business network.
Now launch the server by changing directory to the product-auction folder and type:
cd ..
composer-rest-server
Answer the questions posed at startup. These allow the composer-rest-server to connect to Hyperledger Fabric and configure how the REST API is generated.
? Enter your Connection Profile Name: hlfv1
? Enter your Business Network name : product-auction
? Enter your enrollment ID : admin
? Enter your enrollment secret : adminpw
? Specify if you want namespaces in the generated REST API: never use namespaces
? Specify if you want to enable authentication for the REST API using Passport: No
? Specify if you want to enable event publication over WebSockets: No
? Specify if you want to enable TLS security for the REST API: No
To restart the REST server using the same options, issue the following command:
composer-rest-server -p hlfv1 -n product-auction -i admin -s adminpw -N never
Discovering types from business network definition ...
Discovered types from business network definition
Generating schemas for all types in business network definition ...
Generated schemas for all types in business network definition
Adding schemas for all types to Loopback ...
Swagger: skipping unknown type "Offer".
Swagger: skipping unknown type "Offer".
Swagger: skipping unknown type "Offer".
Added schemas for all types to Loopback
Web server listening at: http://localhost:3000
Browse your REST API at http://localhost:3000/explorer
Test REST API If the composer-rest-server started successfully you should see these two lines are output:
Web server listening at: http://localhost:3000
Browse your REST API at http://localhost:3000/explorer
Open a web browser and navigate to http://localhost:3000/explorer
You should see the LoopBack API Explorer, allowing you to inspect and test the generated REST API. Follow the instructions to test Business Network Definition as mentioned above in the composer section.