mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-19 08:15:08 +00:00
Merge "[FAB-16232] Remove FabToken sample"
This commit is contained in:
commit
33b43b6550
8 changed files with 0 additions and 696 deletions
21
Jenkinsfile
vendored
21
Jenkinsfile
vendored
|
|
@ -136,27 +136,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
// Run fabtoken tests
|
||||
stage('Run FabToken Tests') {
|
||||
steps {
|
||||
script {
|
||||
// making the output color coded
|
||||
wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'xterm']) {
|
||||
try {
|
||||
dir("$ROOTDIR/$BASE_DIR/scripts/ci_scripts") {
|
||||
// Run fabtoken tests
|
||||
sh './ciScript.sh --fabtoken_Tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
failure_stage = "fabtoken_Tests"
|
||||
currentBuild.result = 'FAILURE'
|
||||
throw err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // stages
|
||||
post {
|
||||
always {
|
||||
|
|
|
|||
|
|
@ -1,185 +0,0 @@
|
|||
|
||||
# FabToken Sample Application
|
||||
|
||||
This is a Node.js sample application that demonstrates how to perform token operations on
|
||||
a Fabric network using Fabric Node SDK.
|
||||
|
||||
The sample assumes an understanding of the Hyperledger Fabric network (orderers, peers,
|
||||
and channels) and of Node.js application development, including the use of the Javascript
|
||||
promise, async and await.
|
||||
|
||||
For more information about tokens on Hyperledger Fabric, see
|
||||
[Using Fabtoken](https://hyperledger-fabric.readthedocs.io/en/latest/token/FabToken.html)
|
||||
|
||||
For more information about the Fabric SDK for Node.js, refer to
|
||||
[Node SDK documentation](https://fabric-sdk-node.github.io/master/index.html)
|
||||
|
||||
For more information about the Node SDK TokenClient API, refer to the following:
|
||||
* [TokenClient API reference](https://fabric-sdk-node.github.io/master/TokenClient.html)
|
||||
* [FabToken tutorial](https://fabric-sdk-node.github.io/master/tutorial-fabtoken.html)
|
||||
|
||||
## Run the sample
|
||||
You can find the `fabtoken.js` sample application in the `javascript` directory. You will
|
||||
use this application to create and transfer tokens on a network created using the
|
||||
`basic-network` sample. First, you need to have an initial setup.
|
||||
|
||||
### Setup
|
||||
You will need to install version 8.9.x of Node.js and download the application dependencies.
|
||||
* Change to `javascript` directory: `cd javascript`
|
||||
* Run the following command to install the required packages: `npm install`
|
||||
|
||||
Now you can start the network:
|
||||
* Navigate back to the main `FabToken` directory: `cd ..`
|
||||
* Start fabric network: `./startFabric.sh`
|
||||
|
||||
This command will create a fabric network with 1 peer, an ordering service, one
|
||||
channel, and two users that our application will use to issue and transfer tokens.
|
||||
|
||||
### Run the app right away
|
||||
|
||||
The `fabtoken.js` application includes a `demo` method that runs an end to end token flow
|
||||
with hardcoded parameters.
|
||||
|
||||
* Navigate to the `javascript` directory
|
||||
* Run the command `node fabtoken` without any arguments to run the demo.
|
||||
|
||||
You should see the output of the demo in your terminal. The demo uses user1 and user2 of
|
||||
the basic network to do the following token operations:
|
||||
* Issue a token worth 100 USD to user1
|
||||
* Transfer 30 USD from user1 to user2
|
||||
* Redeem 10 USD as user1 and 30 USD as user2
|
||||
* Check that user1 has a token worth 60 USD and user2 has no tokens
|
||||
|
||||
### Use the sample app to create your own tokens
|
||||
|
||||
You can pass arguments to `fabtoken.js` to create your own tokens and follow your own
|
||||
token flow.
|
||||
|
||||
#### Issue tokens
|
||||
|
||||
Tokens need to be issued before they can be spent. You can use the command
|
||||
`node fabtoken issue <username> <token_type> <quantity>` to issue tokens of any
|
||||
type and quantity to user1 or user2.
|
||||
|
||||
* As an example, the first command issues a token worth 100 US dollars to user1. The
|
||||
second command issues a token worth 200 Euros to user2:
|
||||
|
||||
```
|
||||
node fabtoken issue user1 USD 100
|
||||
node fabtoken issue user2 EURO 200
|
||||
```
|
||||
|
||||
#### List tokens
|
||||
|
||||
After you issue tokens, you can use the list method to query the tokens that you own. Run
|
||||
the command `node fabtoken list <username>`. You need to use this command to recover the
|
||||
tokenIDs that you will need to transfer or redeem your tokens.
|
||||
|
||||
* As an example, you can use the command below to list the tokens owned by user1:
|
||||
|
||||
```
|
||||
node fabtoken list user1
|
||||
```
|
||||
* The command returns a list of tokens, with the tokenID consisting of a tx_id and
|
||||
index. You will need to use these values for future commands.
|
||||
|
||||
```
|
||||
[ { id:
|
||||
{ tx_id: 'c9b1211d9ad809e6ee1b542de6886d8d1d9e1c938d88eff23a3ddb4e8c080e4d',
|
||||
index: 0 },
|
||||
type: 'USD',
|
||||
quantity: '100' }
|
||||
]
|
||||
```
|
||||
|
||||
* To list the tokens owned by user2, use the `node fabtoken list user2` command.
|
||||
|
||||
```
|
||||
[ { id:
|
||||
{ tx_id: 'ab5670d3b20b6247b17a342dd2c5c4416f79db95c168beccb7d32b3dd382e5a5',
|
||||
index: 0 },
|
||||
type: 'EURO',
|
||||
quantity: '200' }
|
||||
]
|
||||
```
|
||||
|
||||
#### Transfer tokens
|
||||
|
||||
Tokens can be transferred between users on a channel using the
|
||||
`node fabtoken transfer <from_user> <to_user> <quantity> <tx_id> <index>` command.
|
||||
* `<tx_id>` and `<index>` are the "tx_id" and "index" that you found using the list
|
||||
command
|
||||
* `<quantity>` is the quantity to be transferred
|
||||
|
||||
Any remaining quantity will be transferred back to the owner by creating a new token with
|
||||
a new tokenID.
|
||||
* As an example, the following command transfers 30 dollars from user1 to user2:
|
||||
|
||||
```
|
||||
node fabtoken transfer user1 user2 30 c9b1211d9ad809e6ee1b542de6886d8d1d9e1c938d88eff23a3ddb4e8c080e4d 0
|
||||
```
|
||||
|
||||
You can run the command `node fabtoken list user2` to verify that user2 now owns a new token
|
||||
worth 30 dollars. You can also run the command `node fabtoken list user1` to verify that
|
||||
a new token worth 70 dollars now belongs to user1.
|
||||
|
||||
|
||||
#### Redeem tokens
|
||||
|
||||
Tokens can be taken out of circulation by being redeemed. Redeemed tokens can no longer
|
||||
be transfered to any member of the channel. Run the command
|
||||
`node fabtoken redeem <username> <quantity> <tx_id> <index>` to redeem any tokens
|
||||
belonging to user1 or user2.
|
||||
* `<tx_id>` and `<index>` are the "tx_id" and "index" returned from the list command
|
||||
* `<quantity>` is the quantity to be redeemed
|
||||
|
||||
Any remaining quantity will be transferred back to the owner with a new tokenID.
|
||||
* As an example, the following command redeems 10 Euro's belonging to user2:
|
||||
|
||||
```
|
||||
node fabtoken redeem user2 10 ab5670d3b20b6247b17a342dd2c5c4416f79db95c168beccb7d32b3dd382e5a5 0
|
||||
```
|
||||
|
||||
#### Clean up
|
||||
|
||||
If you are finished using the sample application, you can bring down the network and any
|
||||
accompanying artifacts.
|
||||
|
||||
* Change to `fabric-samples/basic-network` directory
|
||||
* To stop the network, run `./stop.sh`
|
||||
* To completely remove all incriminating evidence of the network, run `./teardown.sh`
|
||||
|
||||
## Understanding the `fabtoken.js` application
|
||||
|
||||
You can examine the `fabtoken.js` file to get a better understanding of how the
|
||||
sample application uses the FabToken APIs.
|
||||
|
||||
|
||||
1. The `createFabricClient` method creates an instance of the fabric-client, and is
|
||||
used to connect to the components of your network.
|
||||
|
||||
2. The `createUsers` method uses the certificates generated by the basic network to
|
||||
create `admin`, `user1` and `user2` users for the application.
|
||||
|
||||
3. To perform token operations, you must create a `TokenClient` instance from a `Client`
|
||||
object. Make sure the client has set the user context. Below is the code snippet.
|
||||
|
||||
```
|
||||
// set user context to the client
|
||||
await client.setUserContext(user, true);
|
||||
|
||||
// create a TokenClient instance
|
||||
const tokenClient = client.newTokenClient(channel, 'localhost:7051');
|
||||
```
|
||||
|
||||
4. The `issue` method creates an issue request and submits the request to issue tokens to
|
||||
your network.
|
||||
|
||||
5. The `list` method submits the request to list tokens of a
|
||||
given owner. You will need the token IDs returned from this method to transfer or redeem tokens.
|
||||
|
||||
6. The `transfer` method creates a transfer request and submits the request to transfer tokens
|
||||
between users.
|
||||
|
||||
7. The `redeem` method creates a redeem request and submits the request to redeem a user's
|
||||
tokens.
|
||||
8
fabtoken/javascript/.gitignore
vendored
8
fabtoken/javascript/.gitignore
vendored
|
|
@ -1,8 +0,0 @@
|
|||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
package-lock.json
|
||||
|
||||
|
|
@ -1,345 +0,0 @@
|
|||
'use strict';
|
||||
/*
|
||||
* Copyright IBM Corp All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/*
|
||||
* Chaincode Invoke
|
||||
*/
|
||||
|
||||
const Fabric_Client = require('fabric-client');
|
||||
const path = require('path');
|
||||
const util = require('util');
|
||||
const os = require('os');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
const channel_name = "mychannel"
|
||||
|
||||
start();
|
||||
|
||||
async function start() {
|
||||
console.log('\n\n --- fabtoken.js - start');
|
||||
try {
|
||||
console.log('Setting up client side network objects');
|
||||
|
||||
// create fabric client and related instances
|
||||
// starting point for all interactions with the fabric network
|
||||
const {fabric_client, channel} = createFabricClient();
|
||||
|
||||
// create users from existing crypto materials
|
||||
const {admin, user1, user2} = await createUsers();
|
||||
|
||||
console.log('Successfully setup client side');
|
||||
|
||||
let operation = null;
|
||||
let user = null;
|
||||
const args = [];
|
||||
|
||||
// if there is no argument, it will run demo by calling hardcoded token operations
|
||||
// if there are arguments, it will invoke corresponding issue, list, transfer, redeem operations
|
||||
if (process.argv.length == 2) {
|
||||
demo(fabric_client, channel, admin, user1, user2)
|
||||
return
|
||||
} else if (process.argv.length >= 4) {
|
||||
operation = process.argv[2];
|
||||
if (process.argv[3] === 'user1') {
|
||||
user = user1;
|
||||
} else if (process.argv[3] === 'user2') {
|
||||
user = user2;
|
||||
} else {
|
||||
throw new Error(util.format('Invalid username "%s". Must be user1 or user2', process.argv[3]));
|
||||
}
|
||||
for (let i = 4; i < process.argv.length; i++) {
|
||||
if (process.argv[i]) {
|
||||
console.log(' Token arg: ' + process.argv[i]);
|
||||
args.push(process.argv[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new Error('Missing required arguments: operation, user');
|
||||
}
|
||||
|
||||
console.log('\n\nStart %s token operation', operation);
|
||||
let result = null;
|
||||
switch (operation) {
|
||||
case 'issue':
|
||||
if (args.length < 2) {
|
||||
throw new Error('Missing required parameter for issue: token_type, quantity');
|
||||
}
|
||||
result = await issue(fabric_client, channel, admin, user, args);
|
||||
break;
|
||||
case 'transfer':
|
||||
if (args.length < 4) {
|
||||
throw new Error('Missing required parameters for transfer: recipient, transfer_quantity, tx_id, index');
|
||||
}
|
||||
let recipient
|
||||
if (args[0] === 'user1') {
|
||||
recipient = user1;
|
||||
} else if (args[0] === 'user2') {
|
||||
recipient = user2;
|
||||
} else {
|
||||
throw new Error(util.format('Invalid recipient "%s". Must be user1 or user2', process.argv[3]));
|
||||
}
|
||||
// shift out args[0] because recipient object is passed separately
|
||||
args.shift();
|
||||
result = await transfer(fabric_client, channel, user, recipient, args);
|
||||
break;
|
||||
case 'redeem':
|
||||
if (args.length < 3) {
|
||||
throw new Error('Missing required parameter for redeem: quantity, tx_id, index');
|
||||
}
|
||||
result = await redeem(fabric_client, channel, user, args);
|
||||
break;
|
||||
case 'list':
|
||||
result = await list(fabric_client, channel, user);
|
||||
break;
|
||||
default:
|
||||
throw new Error(' Unknown operation requested: ' + operation);
|
||||
}
|
||||
|
||||
console.log('End %s token operation, returns\n %s', operation, util.inspect(result, {depth: null}));
|
||||
|
||||
} catch(error) {
|
||||
console.log('Problem with fabric token ::'+ error.toString());
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('\n\n --- fabtoken.js - end');
|
||||
};
|
||||
|
||||
// demo invokes token operations using hardcoded parameters
|
||||
async function demo(client, channel, admin, user1, user2) {
|
||||
await reset(client, channel, user1, user2);
|
||||
|
||||
console.log('admin issues token to user1, wait 5 seconds for transaction to be committed');
|
||||
await issue(client, channel, admin, user1, ['USD', '100']);
|
||||
await sleep(5000)
|
||||
|
||||
let user1_tokens = await list(client, channel, user1);
|
||||
console.log('\nuser1 has a token in USD type and 100 quantity after issue:\n%s', util.inspect(user1_tokens, {depth: null}));
|
||||
|
||||
console.log('\nuser1 transfers 30 quantity of the token to user2, wait 5 seconds for transaction to be committed');
|
||||
let token_id = user1_tokens[0].id;
|
||||
await transfer(client, channel, user1, user2, ['30', token_id.tx_id, token_id.index]);
|
||||
await sleep(5000)
|
||||
|
||||
user1_tokens = await list(client, channel, user1);
|
||||
console.log('\nuser1 has a token in 70 quantity after transfer:\n%s', util.inspect(user1_tokens, {depth: null}));
|
||||
|
||||
let user2_tokens = await list(client, channel, user2);
|
||||
console.log('\nuser2 has a token in 30 quantity after transfer:\n%s', util.inspect(user2_tokens, {depth: null}));
|
||||
|
||||
console.log('\nuser1 redeems 10 out of 70 quantity of the token');
|
||||
token_id = user1_tokens[0].id;
|
||||
await redeem(client, channel, user1, ['10', token_id.tx_id, token_id.index]);
|
||||
|
||||
console.log('\nuser2 redeems entire token, wait 5 seconds for transaction to be committed');
|
||||
token_id = user2_tokens[0].id;
|
||||
await redeem(client, channel, user2, ['30', token_id.tx_id, token_id.index]);
|
||||
await sleep(5000)
|
||||
|
||||
user1_tokens = await list(client, channel, user1);
|
||||
console.log('\nuser1 has a token in 60 quantity after redeem:\n%s', util.inspect(user1_tokens, {depth: null}));
|
||||
|
||||
user2_tokens = await list(client, channel, user2);
|
||||
console.log('\nuser2 has no token after redeem:\n%s', util.inspect(user2_tokens, {depth: null}));
|
||||
|
||||
await reset(client, channel, user1, user2);
|
||||
}
|
||||
|
||||
// reset removes all the existing tokens on the channel to get a fresh env
|
||||
async function reset(client, channel, user1, user2) {
|
||||
console.log('\nReset: remove all the tokens on the channel\n');
|
||||
|
||||
let tokens = await list(client, channel, user1);
|
||||
for (const token of tokens) {
|
||||
await redeem(client, channel, user1, [token.quantity, token.id.tx_id, token.id.index]);
|
||||
}
|
||||
|
||||
tokens = await list(client, channel, user2);
|
||||
for (const token of tokens) {
|
||||
await redeem(client, channel, user2, [token.quantity, token.id.tx_id, token.id.index]);
|
||||
}
|
||||
}
|
||||
|
||||
// Issue token to the user with args [type, quantity]
|
||||
// It uses "admin" to issue tokens, but other users can also issue tokens as long as they have the permission.
|
||||
async function issue(client, channel, admin, user, args) {
|
||||
console.log('Start token issue with args ' + args);
|
||||
|
||||
await client.setUserContext(admin, true);
|
||||
|
||||
const tokenClient = client.newTokenClient(channel, 'localhost:7051');
|
||||
|
||||
// build the request to issue tokens to the user
|
||||
const txId = client.newTransactionID();
|
||||
const param = {
|
||||
owner: user.getIdentity().serialize(),
|
||||
type: args[0],
|
||||
quantity: args[1]
|
||||
};
|
||||
const request = {
|
||||
params: [param],
|
||||
txId: txId,
|
||||
};
|
||||
|
||||
return await tokenClient.issue(request);
|
||||
}
|
||||
|
||||
// Transfers token from the user to the recipient with args [quantity, tx_id, index]
|
||||
async function transfer(client, channel, user, recipient, args) {
|
||||
console.log('Start token transfer with args ' + args);
|
||||
|
||||
await client.setUserContext(user, true);
|
||||
|
||||
const tokenClient = client.newTokenClient(channel, 'localhost:7051');
|
||||
|
||||
// build the request to transfer tokens to the recipient
|
||||
const txId = client.newTransactionID();
|
||||
const param1 = {
|
||||
owner: recipient.getIdentity().serialize(),
|
||||
quantity: args[0]
|
||||
};
|
||||
|
||||
const request = {
|
||||
tokenIds: [{tx_id: args[1], index: parseInt(args[2])}],
|
||||
params: [param1],
|
||||
txId: txId,
|
||||
};
|
||||
|
||||
return await tokenClient.transfer(request);
|
||||
}
|
||||
|
||||
// Redeem tokens from the user with args [quantity, tx_id, index]
|
||||
async function redeem(client, channel, user, args) {
|
||||
console.log('Start token redeem with args ' + args);
|
||||
|
||||
await client.setUserContext(user, true);
|
||||
|
||||
const tokenClient = client.newTokenClient(channel, 'localhost:7051');
|
||||
|
||||
// build the request to redeem tokens
|
||||
const txId = client.newTransactionID();
|
||||
const param = {
|
||||
quantity: args[0]
|
||||
};
|
||||
const request = {
|
||||
tokenIds: [{tx_id: args[1], index: parseInt(args[2])}],
|
||||
params: [param],
|
||||
txId: txId,
|
||||
};
|
||||
|
||||
return await tokenClient.redeem(request);
|
||||
}
|
||||
|
||||
// List tokens for the user
|
||||
async function list(client, channel, user) {
|
||||
await client.setUserContext(user, true);
|
||||
|
||||
const tokenClient = client.newTokenClient(channel, 'localhost:7051');
|
||||
|
||||
return await tokenClient.list();
|
||||
}
|
||||
|
||||
// Create fabric client, channel, orderer, and peer instances.
|
||||
// These are needed for SDK to invoke token operations.
|
||||
function createFabricClient() {
|
||||
// fabric client instance
|
||||
// starting point for all interactions with the fabric network
|
||||
const fabric_client = new Fabric_Client();
|
||||
|
||||
// -- channel instance to represent the ledger
|
||||
const channel = fabric_client.newChannel(channel_name);
|
||||
console.log(' Created client side object to represent the channel');
|
||||
|
||||
// -- peer instance to represent a peer on the channel
|
||||
const peer = fabric_client.newPeer('grpc://localhost:7051');
|
||||
console.log(' Created client side object to represent the peer');
|
||||
|
||||
// -- orderer instance to reprsent the channel's orderer
|
||||
const orderer = fabric_client.newOrderer('grpc://localhost:7050')
|
||||
console.log(' Created client side object to represent the orderer');
|
||||
|
||||
// add peer and orderer to the channel
|
||||
channel.addPeer(peer);
|
||||
channel.addOrderer(orderer);
|
||||
|
||||
return {fabric_client: fabric_client, channel: channel};
|
||||
}
|
||||
|
||||
// Create admin, user1 and user2 by loading crypto files
|
||||
async function createUsers() {
|
||||
// This sample application will read user idenitity information from
|
||||
// pre-generated crypto files and create users. It will use a client object as
|
||||
// an easy way to create the user objects from known cyrpto material.
|
||||
|
||||
const client = new Fabric_Client();
|
||||
|
||||
// load admin
|
||||
let keyPath = path.join(__dirname, '../../basic-network/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore');
|
||||
let keyPEM = Buffer.from(readAllFiles(keyPath)[0]).toString();
|
||||
let certPath = path.join(__dirname, '../../basic-network/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts');
|
||||
let certPEM = readAllFiles(certPath)[0];
|
||||
|
||||
let user_opts = {
|
||||
username: 'admin',
|
||||
mspid: 'Org1MSP',
|
||||
skipPersistence: true,
|
||||
cryptoContent: {
|
||||
privateKeyPEM: keyPEM,
|
||||
signedCertPEM: certPEM
|
||||
}
|
||||
};
|
||||
const admin = await client.createUser(user_opts);
|
||||
|
||||
// load user1
|
||||
keyPath = path.join(__dirname, '../../basic-network/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/keystore');
|
||||
keyPEM = Buffer.from(readAllFiles(keyPath)[0]).toString();
|
||||
certPath = path.join(__dirname, '../../basic-network/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/signcerts');
|
||||
certPEM = readAllFiles(certPath)[0];
|
||||
|
||||
user_opts = {
|
||||
username: 'user1',
|
||||
mspid: 'Org1MSP',
|
||||
skipPersistence: true,
|
||||
cryptoContent: {
|
||||
privateKeyPEM: keyPEM,
|
||||
signedCertPEM: certPEM
|
||||
}
|
||||
};
|
||||
const user1 = await client.createUser(user_opts);
|
||||
|
||||
// load user2
|
||||
keyPath = path.join(__dirname, '../../basic-network/crypto-config/peerOrganizations/org1.example.com/users/User2@org1.example.com/msp/keystore');
|
||||
keyPEM = Buffer.from(readAllFiles(keyPath)[0]).toString();
|
||||
certPath = path.join(__dirname, '../../basic-network/crypto-config/peerOrganizations/org1.example.com/users/User2@org1.example.com/msp/signcerts');
|
||||
certPEM = readAllFiles(certPath)[0];
|
||||
|
||||
user_opts = {
|
||||
username: 'user2',
|
||||
mspid: 'Org1MSP',
|
||||
skipPersistence: true,
|
||||
cryptoContent: {
|
||||
privateKeyPEM: keyPEM,
|
||||
signedCertPEM: certPEM
|
||||
}
|
||||
};
|
||||
const user2 = await client.createUser(user_opts);
|
||||
|
||||
return {admin: admin, user1: user1, user2: user2};
|
||||
}
|
||||
|
||||
function readAllFiles(dir) {
|
||||
const files = fs.readdirSync(dir);
|
||||
const certs = [];
|
||||
files.forEach((file_name) => {
|
||||
const file_path = path.join(dir, file_name);
|
||||
const data = fs.readFileSync(file_path);
|
||||
certs.push(data);
|
||||
});
|
||||
return certs;
|
||||
}
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"name": "fabtoken",
|
||||
"version": "1.0.0",
|
||||
"description": "Hyperledger Fabric Token Sample Application",
|
||||
"main": "fabtoken.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"dependencies": {
|
||||
"fabric-client": "unstable",
|
||||
"fs-extra": "^6.0.1",
|
||||
"util": "^0.10.3"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"keywords": [
|
||||
"Hyperledger",
|
||||
"Fabric",
|
||||
"Token",
|
||||
"Sample",
|
||||
"Application"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright IBM Corp All Rights Reserved
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Exit on first error
|
||||
set -e
|
||||
|
||||
# don't rewrite paths for Windows Git Bash users
|
||||
export MSYS_NO_PATHCONV=1
|
||||
starttime=$(date +%s)
|
||||
|
||||
# launch network; create channel and join peer to channel
|
||||
cd ../basic-network
|
||||
./start.sh
|
||||
|
||||
cat <<EOF
|
||||
|
||||
Total setup execution time : $(($(date +%s) - starttime)) secs ...
|
||||
|
||||
Next, use the FabToken application to interact with the Fabric network.
|
||||
|
||||
Start by changing into the "javascript" directory:
|
||||
cd javascript
|
||||
|
||||
Next, install all required packages:
|
||||
npm install
|
||||
|
||||
Then run the fabtoken application to perform the token operations.
|
||||
|
||||
node fabtoken
|
||||
- when no argument is passed, it will run a demo with predefined token operations
|
||||
node fabtoken issue <username> <token_type> <quantity>
|
||||
- example: node fabtoken issue user1 USD 100
|
||||
node fabtoken list <username>
|
||||
- example: node fabtoken list user1
|
||||
- select a token to transfer or redeem and pass "tx_id" and "index" as input parameters
|
||||
node fabtoken transfer <from_user> <to_user> <quantity> <tx_id> <index>
|
||||
- example: node fabtoken transfer user1 user2 30 c9b1211d9ad809e6ee1b542de6886d8d1d9e1c938d88eff23a3ddb4e8c080e4d 0
|
||||
- <tx_id> and <index> are the "tx_id" and "index" returned from the list operation that specifies the token id for transfer
|
||||
node fabtoken redeem <username> <quantity> <tx_id> <index>
|
||||
- example: node fabtoken redeem user2 10 477c7bf2002814497c228fd8cbc4d80c8b7f1602b2c17ffadb6cf7e5783fa47a 0
|
||||
- <tx_id> and <index> are the "tx_id" and "index" returned from the list operation
|
||||
|
||||
EOF
|
||||
|
|
@ -16,9 +16,6 @@ Parse_Arguments() {
|
|||
--fabcar_Tests)
|
||||
fabcar_Tests
|
||||
;;
|
||||
--fabtoken_Tests)
|
||||
fabtoken_Tests
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
|
@ -54,22 +51,4 @@ fabcar_Tests() {
|
|||
./fabcar.sh
|
||||
}
|
||||
|
||||
# run fabtoken tests
|
||||
fabtoken_Tests() {
|
||||
|
||||
echo " #############################"
|
||||
echo "npm version ------> $(npm -v)"
|
||||
echo "node version ------> $(node -v)"
|
||||
echo " #############################"
|
||||
|
||||
echo
|
||||
echo " _____ _ ____ _______ __ ___ __ _____ __ __ "
|
||||
echo " | ___| / \ | __ ) |__ __| / _ \ | | / / | ____| | |\ | | "
|
||||
echo " | |_ / _ \ | _ \ | | | | | | | |/ / | |___ | | \ | | "
|
||||
echo " | _| / ___ \ | |_) | | | | |_ | | | |\ \ | ___| | | \ | | "
|
||||
echo " |_| /_/ \_\ |____/ |_| \ __ / |_| \_\ |_|____ |_| \|_| "
|
||||
|
||||
./fabtoken.sh
|
||||
}
|
||||
|
||||
Parse_Arguments $@
|
||||
|
|
|
|||
|
|
@ -1,48 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
# docker container list - Check these from basic-network/docker-compose.yaml
|
||||
CONTAINER_LIST=(peer0.org1 orderer ca)
|
||||
|
||||
logs() {
|
||||
|
||||
for CONTAINER in ${CONTAINER_LIST[*]}; do
|
||||
docker logs $CONTAINER.example.com >& $WORKSPACE/$CONTAINER-$1.log
|
||||
echo
|
||||
done
|
||||
# Write couchdb container logs into couchdb.log file
|
||||
docker logs couchdb >& couchdb.log
|
||||
|
||||
}
|
||||
|
||||
copy_logs() {
|
||||
|
||||
# Call logs function
|
||||
logs $2 $3
|
||||
|
||||
if [ $1 != 0 ]; then
|
||||
echo -e "\033[31m $2 test case is FAILED" "\033[0m"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
cd $WORKSPACE/$BASE_DIR/fabtoken || exit
|
||||
export PATH=gopath/src/github.com/hyperledger/fabric-samples/bin:$PATH
|
||||
|
||||
LANGUAGE="javascript"
|
||||
|
||||
echo -e "\033[32m starting fabtoken test (${LANGUAGE})" "\033[0m"
|
||||
./startFabric.sh
|
||||
copy_logs $? fabtoken-start-script-${LANGUAGE}
|
||||
|
||||
pushd ${LANGUAGE}
|
||||
npm install
|
||||
node fabtoken.js
|
||||
copy_logs $? fabtoken-${LANGUAGE}
|
||||
popd
|
||||
|
||||
docker ps -aq | xargs docker rm -f
|
||||
docker rmi -f $(docker images -aq dev-*)
|
||||
echo -e "\033[32m finished fabtoken tests (${LANGUAGE})" "\033[0m"
|
||||
Loading…
Reference in a new issue