Skip to content

Conversation

@XZSt4nce
Copy link

@XZSt4nce XZSt4nce commented Mar 7, 2025

  • JSDoc returns Promises in async functions
  • Deleted redundant totalSupply param from Initialize JSDoc
  • Using DRY for ClientAccountID, BalanceOf etc
  • Added function ClientAccountMSPID
  • Added function CheckAuthorization
  • Using new function _update for minting, burning and transfering tokens
  • Additional functions for approving, spending allowance and checking empty values
  • Updated and repaired tests

…tID, BalanceOf etc; Added function ClientAccountMSPID; Added function CheckAuthorization; Using new function _update for minting, burning and transfering tokens; Additional functions for approving, spending allowance and checking empty values; Updated and repaired tests

Signed-off-by: XZSt4nce <xzstnc@mail.ru>
@XZSt4nce XZSt4nce requested a review from a team as a code owner March 7, 2025 23:45
Deleted redundant `totalSupply` param from `Initialize` JSDoc

Signed-off-by: Maxim Tiron <xzstnc@mail.ru>
@XZSt4nce
Copy link
Author

XZSt4nce commented Sep 2, 2025

?

Copy link
Member

@bestbeforetoday bestbeforetoday left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution. Improvements to the JSDoc are great. It looks like there are some subtle differences in error handling behaviour but nothing jumped out at me as breaking the intended functionality. I have added a few comments that generally I think are worth addressing.

It would give me much more confidence in accepting changes to these samples if some basic testing of them was added to the build, similar to the ones driven by .github/workflows/test-network-*.yaml.

* @param {Context} ctx the transaction context
* @returns {String} Returns the account MSP id
*/
ClientAccountMSPID(ctx) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is only one call to this function within the smart contract. Perhaps that one call should just be replaced with ctx.clientIdentity.getMSPID() and this function removed. The capitalised function name suggests it is intended to be evaluated by clients but this seems redundant since the client must already know its MSP ID in order to interact with the smart contract.

// Check if the sender has enough tokens to spend.
if (fromCurrentBalance < valueInt) {
throw new Error(`client account ${from} has insufficient funds.`);
if (this.isEmpty(from)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For strings !from also covers the case where from.length === 0 so this is equivalent to the (perhaps simpler) if (!from).

Suggested change
if (this.isEmpty(from)) {
if (!from) {

toCurrentBalance = 0;
} else {
toCurrentBalance = parseInt(toCurrentBalanceBytes.toString());
if (this.isEmpty(to)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (this.isEmpty(to)) {
if (!to) {

* @param {Boolean} emitEvent Whether to emit event
*/
async _approveEvent(ctx, owner, spender, value, emitEvent) {
if (this.isEmpty(owner)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (this.isEmpty(owner)) {
if (!owner) {

if (this.isEmpty(owner)) {
throw new Error('invalid approver');
}
if (this.isEmpty(spender)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (this.isEmpty(spender)) {
if (!spender) {

* @param {String} to The recipient
* @param {Number} value The amount of token to be transferred
*/
async _update(ctx, from, to, value) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate that you are trying to reduce code duplication across transaction functions but I am concerned that the logic of this _update implementation introduces a lot of complexity. Some flow explicitly require from and to values while others rely on those values being falsy. This means that this function has four potential modes of invocation:

  1. from and to both set.
  2. from set and to unset.
  3. from unset and to set.
  4. from and to both unset.

This creates high cyclomatic complexity. I think it would be preferable if each (valid) combination was implemented separately with each combination having only the parameters actually needed to make the intent very clear, despite some similarities between them. Alternatively you could still avoid duplication by splitting specific parts of this update flow into separate functions and having transfer, mint and burn compose those parts in the appropriate combination.

Comment on lines +112 to +113
sinon.assert.calledWith(mockStub.putState.getCall(4), 'balance_Alice', Buffer.from('0'));
sinon.assert.calledWith(mockStub.putState.getCall(5), 'balance_Bob', Buffer.from('1000'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The need to change the call number highlights the fragility of this testing approach. The call number should not matter. I suggest this instead, which checks that a call was made with the required arguments regardless of the call ordering:

Suggested change
sinon.assert.calledWith(mockStub.putState.getCall(4), 'balance_Alice', Buffer.from('0'));
sinon.assert.calledWith(mockStub.putState.getCall(5), 'balance_Bob', Buffer.from('1000'));
sinon.assert.calledWith(mockStub.putState, 'balance_Alice', Buffer.from('0'));
sinon.assert.calledWith(mockStub.putState, 'balance_Bob', Buffer.from('1000'));

Same suggestion for all the other changes in this file that required a different call number.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants