Skip to content

Commit

Permalink
[FABN-1199] Simplify token owner parameter
Browse files Browse the repository at this point in the history
Simplify token owner to be a flat field for usability.
In the future, if new owner type is supported, we can add
another field.

Change-Id: I996c73b8e82b6d9bddd50f530fe272a7aea2ca8b
Signed-off-by: Wenjian Qiao <[email protected]>
  • Loading branch information
wenjianqiao committed Apr 5, 2019
1 parent 54e6d64 commit ffa998a
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 36 deletions.
8 changes: 4 additions & 4 deletions docs/tutorials/fabtoken.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ const txId = client.newTransactionID();
// create two parameters for issue, one for user1 and one for user2
const param1 = {
owner: {raw: user1.getIdentity().serialize(), type: 0},
owner: user1.getIdentity().serialize(),
type: 'USD',
quantity: '500',
};
const param2 = {
owner: {raw: user2.getIdentity().serialize(), type: 0},
owner: user2.getIdentity().serialize(),
type: 'EURO',
quantity: '300',
};
Expand Down Expand Up @@ -124,11 +124,11 @@ const txId = client1.newTransactionID();
// create two parameters, where param1 is to transfer 300 to user2 and param2 is to transfer the remaining 200 to user1.
const param1 = {
owner: {raw: user2.getIdentity().serialize(), type:0},
owner: user2.getIdentity().serialize(),
quantity: '300',
};
const param2 = {
owner: {raw: user1.getIdentity().serialize(), type:0},
owner: user1.getIdentity().serialize(),
quantity: '200',
};
Expand Down
13 changes: 3 additions & 10 deletions fabric-client/lib/TokenClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const {HashPrimitives} = require('fabric-common');
* // create request to issue tokens to user2
* // owner type is optional; default is 0 (i.e., TokenOwner_MSP_IDENTIFIER type)
* const txId = tokenClient1.newTransactionID();
* const owner = {raw: user2.getIdentity().serialize(), type: 0};
* const owner = user2.getIdentity().serialize();
* const tokenType = 'myTokenType';
* let param = {owner: owner, type: tokenType, quantity: '200'};
* let request = {params: [param], txId: txId};
Expand Down Expand Up @@ -94,7 +94,7 @@ const {HashPrimitives} = require('fabric-common');
*
* // user2 calls transfer method to transfer the token to user1
* // owner type is optional; default is 0 (i.e., TokenOwner_MSP_IDENTIFIER type)
* const newOwner = {raw: user1.getIdentity().serialize(), type: 0};
* const newOwner = user1.getIdentity().serialize();
* param = {owner: newOwner, quantity: '150'};
* request = {params: [param], tokenId: token.id, txId: txId};
* result = await tokenClient1.transfer(request);
Expand Down Expand Up @@ -164,18 +164,11 @@ const TokenClient = class {
this._targets = targets;
}

/**
* @typedef {Object} TokenOwner
* This object contains the bytes and type for the owner.
* @property {byte[]} raw - Required. The serialized bytes for the owner.
* @property {int} type - Optional. Default is 0 (i.e., TokenOwner_MSP_IDENTIFIER type).
*/

/**
* @typedef {Object} TokenParam
* This object contains properties that specify the owner, type,
* and quantity of a token kind.
* @property {TokenOwner} owner - Required for issue and transfer. The recipient of the token.
* @property {byte[]} owner - Required for issue and transfer. The serialized bytes for the recipient.
* @property {string} type - Required for issue. The type of the token.
* @property {string} quantity - Required. The quantity of the token in decimal string format.
* For example, use '200' for 200.
Expand Down
6 changes: 4 additions & 2 deletions fabric-client/lib/token-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ module.exports.buildIssueCommand = (request) => {
// iterate params to populate tokensToIssue
const tokensToIssue = [];
params.forEach((param) => {
const token = {owner: param.owner, type: param.type, quantity: param.quantity};
const owner = {raw: param.owner, type: fabprotos.token.TokenOwner_MSP_IDENTIFIER};
const token = {owner: owner, type: param.type, quantity: param.quantity};
tokensToIssue.push(token);
});

Expand All @@ -62,7 +63,8 @@ module.exports.buildTransferCommand = (request) => {
// iterate params to populate transfer shares
const shares = [];
params.forEach((param) => {
const share = {recipient: param.owner, quantity: param.quantity};
const owner = {raw: param.owner, type: fabprotos.token.TokenOwner_MSP_IDENTIFIER};
const share = {recipient: owner, quantity: param.quantity};
shares.push(share);
});

Expand Down
2 changes: 1 addition & 1 deletion fabric-client/test/TokenClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe('TokenClient', () => {
let client;
let tokenClient;

const testowner = {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: Buffer.from('testowner')};
const testowner = Buffer.from('testowner');
const txId = sinon.createStubInstance(TransactionID);
const channelId = 'mychannel';

Expand Down
18 changes: 10 additions & 8 deletions fabric-client/test/token-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe('token-utils', () => {

beforeEach(() => {
// prepare token request
const owner = {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: Buffer.from('test-owner')};
const owner = Buffer.from('test-owner');
param = {owner: owner, type: 'abc123', quantity: '210'};
request = {params: [param], txId: txId, tokenIds: tokenIds};
});
Expand Down Expand Up @@ -239,8 +239,8 @@ describe('token-utils', () => {
describe('#buildIssueCommand', () => {
beforeEach(() => {
// prepare token request for issue
const owner1 = {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: Buffer.from('owner1')};
const owner2 = {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: Buffer.from('owner2')};
const owner1 = Buffer.from('owner1');
const owner2 = Buffer.from('owner2');
param1 = {owner: owner1, type: 'abc123', quantity: '210'};
param2 = {owner: owner2, type: 'horizon', quantity: '300'};
request = {
Expand All @@ -249,8 +249,10 @@ describe('token-utils', () => {
};

// create expected command based on request
const token1 = {owner: {raw: owner1, type:0}, type: 'abc123', quantity: '210'};
const token2 = {owner: {raw: owner2, type:0}, type: 'horizon', quantity: '300'};
const issueRequest = new fabprotos.token.IssueRequest();
issueRequest.setTokensToIssue([param1, param2]);
issueRequest.setTokensToIssue([token1, token2]);
expectedCommand = new fabprotos.token.Command();
expectedCommand.set('issue_request', issueRequest);
});
Expand All @@ -265,8 +267,8 @@ describe('token-utils', () => {
beforeEach(() => {
// prepare token request for transfer
const tokenId = {tx_id: 'mock_tx_id', index: 0};
const owner1 = {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: Buffer.from('owner1')};
const owner2 = {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: Buffer.from('owner2')};
const owner1 = Buffer.from('owner1');
const owner2 = Buffer.from('owner2');
param1 = {owner: owner1, quantity: '100'};
param2 = {owner: owner2, quantity: '200'};

Expand All @@ -279,8 +281,8 @@ describe('token-utils', () => {
// create expected command based on request
const transferRequest = new fabprotos.token.TransferRequest();
transferRequest.setTokenIds([tokenId]);
const share1 = {recipient: param1.owner, quantity: param1.quantity};
const share2 = {recipient: param2.owner, quantity: param2.quantity};
const share1 = {recipient: {raw: owner1, type: 0}, quantity: param1.quantity};
const share2 = {recipient: {raw: owner2, type:0}, quantity: param2.quantity};
transferRequest.setShares([share1, share2]);
expectedCommand = new fabprotos.token.Command();
expectedCommand.set('transfer_request', transferRequest);
Expand Down
23 changes: 12 additions & 11 deletions test/integration/token.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ test('\n\n***** Token end-to-end flow (green path): issue, transfer, redeem and
// build the request for user2 to issue tokens to user1
let txId = user2TokenClient.getClient().newTransactionID();
let param = {
owner: {type: 0, raw: user1Identity.serialize()},
owner: user1Identity.serialize(),
type: 'abc123',
quantity: '200'
};
const param2 = {
owner: {type: 0, raw: user1Identity.serialize()},
owner: user1Identity.serialize(),
type: 'ibm',
quantity: '200'
};
Expand Down Expand Up @@ -125,7 +125,7 @@ test('\n\n***** Token end-to-end flow (green path): issue, transfer, redeem and
// build request for user1 to transfer transfer token to user2
txId = user1TokenClient.getClient().newTransactionID();
param = {
owner: {type: 0, raw: user2Identity.serialize()},
owner: user2Identity.serialize(),
quantity: transferToken.quantity,
};
request = {
Expand Down Expand Up @@ -213,7 +213,7 @@ test('\n\n***** Token end-to-end flow: double spending fails *****\n\n', async (
// build request for user2 to issue a token to user1
let txId = user2TokenClient.getClient().newTransactionID();
let param = {
owner: {raw: user1Identity.serialize()},
owner: user1Identity.serialize(),
type: 'abc123',
quantity: '210'
};
Expand All @@ -238,7 +238,7 @@ test('\n\n***** Token end-to-end flow: double spending fails *****\n\n', async (
// build request for user1 to transfer transfer token to user2
txId = user1TokenClient.getClient().newTransactionID();
param = {
owner: {raw: user2Identity.serialize()},
owner: user2Identity.serialize(),
quantity: transferToken.quantity
};
request = {
Expand Down Expand Up @@ -303,7 +303,7 @@ test('\n\n***** Token end-to-end flow: non owner transfer fails *****\n\n', asyn
// build request for user2 to issue a token to user1
let txId = user2TokenClient.getClient().newTransactionID();
let param = {
owner: {raw: user1Identity.serialize()},
owner: user1Identity.serialize(),
type: 'abc123',
quantity: '210'
};
Expand All @@ -328,7 +328,7 @@ test('\n\n***** Token end-to-end flow: non owner transfer fails *****\n\n', asyn
// token is owned by user1, but user2 attempts to transfer the token, should fail
txId = user2TokenClient.getClient().newTransactionID();
param = {
owner: {raw: user2Identity.serialize()},
owner: user2Identity.serialize(),
quantity: '10'
};
request = {
Expand Down Expand Up @@ -372,7 +372,7 @@ test('\n\n***** Token end-to-end flow: transfer with remaining balance succeeds
// build request for user2 to issue a token to user1
let txId = user2TokenClient.getClient().newTransactionID();
let param = {
owner: {raw: user1Identity.serialize()},
owner: user1Identity.serialize(),
type: 'abc123',
quantity: '210'
};
Expand All @@ -397,7 +397,7 @@ test('\n\n***** Token end-to-end flow: transfer with remaining balance succeeds
// build request for user1 to transfer transfer token to user2
txId = user1TokenClient.getClient().newTransactionID();
param = {
owner: {raw: user2Identity.serialize()},
owner: user2Identity.serialize(),
quantity: '10'
};
request = {
Expand Down Expand Up @@ -451,7 +451,7 @@ test('\n\n***** Token end-to-end flow: invalid redeem amount fails *****\n\n', a
// build request for user2 to issue a token to user1
let txId = user2TokenClient.getClient().newTransactionID();
let param = {
owner: {raw: user1Identity.serialize()},
owner: user1Identity.serialize(),
type: 'abc123',
quantity: '100'
};
Expand Down Expand Up @@ -562,8 +562,9 @@ function validateTransactionEnvelope(txEnvelope, commandName, expectedInputs, ex
for (let i = 0; i < expectedOutputs.length; i++) {
// fabtoken uses hex string in token transaction, so convert expectedQuantity to hex string
const expectedQuantityToHex = tokenUtils.toHex(parseInt(expectedOutputs[i].quantity));
// list tokens returns owner in TokenOwner format {raw: xxx}, so get raw field.
t.deepEqual(action_data.outputs[i].owner.raw, expectedOutputs[i].owner, 'Validationing owner in token transaction');
t.deepEqual(action_data.outputs[i].quantity, expectedQuantityToHex, 'Validationing quantity in token transaction');
t.deepEqual(action_data.outputs[i].owner, expectedOutputs[i].owner, 'Validationing owner in token transaction');
t.deepEqual(action_data.outputs[i].type, expectedOutputs[i].type, 'Validationing type in token transaction');
}
if (expectedInputs) {
Expand Down

0 comments on commit ffa998a

Please sign in to comment.