SyntaxError: неожиданный конец ввода JSON при попытке запросить сведения о транзакции из гиперреестра 2.2

Я пытаюсь запустить пример вознаграждения на .hyperledger 2.2. Контракт успешно упакован и развернут. Я также смог успешно запустить приложение и зарегистрировать администратора и пользователя.

Чейнкод успешно развернут:

Committed chaincode definition for chaincode 'customerloyalty' on channel 'mychannel':
Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
Query chaincode definition successful on peer0.org2 on channel 'mychannel'

Зарегистрировать администратора успешно:

 
Wallet path: ../fabric-samples/asset-transfer-basic/application-customerloyalty/wallet
Successfully enrolled admin user "admin" and imported it into the wallet

удалось успешно зарегистрировать пользователя:

app running on port: 8000
Using param - firstname: Test lastname: User email: [email protected] phonenumber: 111-111-1111 accountNumber: 123456 cardId: 123
Valid Entries
Wallet path: ../fabric-samples/asset-transfer-basic/application-customerloyalty/wallet
Successfully registered and enrolled admin user 123 and imported it into the wallet
admin user admin disconnected

Submit Create Member transaction.
createMemberResponse: 
{
  accountNumber: '123456',
  firstName: 'Test',
  lastName: 'User',
  email: '[email protected]',
  phoneNumber: '111-111-1111',
  points: 0
}

Get member state 
memberResponse.parse_response: 
{
  accountNumber: '123456',
  firstName: 'Test',
  lastName: 'User',
  email: '[email protected]',
  phoneNumber: '111-111-1111',
  points: 0
}
memberData using param -  accountNumber: 123456 cardId: 123
Wallet path: ../fabric-samples/asset-transfer-basic/application-customerloyalty/wallet

Get member state 
{
  accountNumber: '123456',
  firstName: 'Test',
  lastName: 'User',
  email: '[email protected]',
  phoneNumber: '111-111-1111',
  points: 0
}
Wallet path: ../fabric-samples/asset-transfer-basic/application-customerloyalty/wallet

Однако, когда я пытаюсь получить информацию о транзакции в приложении, я получаю следующую ошибку без ответа от одноранговых узлов:

Get use points transactions state for member 123456
2023-01-05T21:28:46.042Z - error: [Transaction]: Error: No valid responses from any peers. Errors:
    peer=peer0.org1.example.com:7051, status=500, message=error in simulation: transaction returned with failure: SyntaxError: Unexpected end of JSON input
    peer=peer0.org2.example.com:9051, status=500, message=error in simulation: transaction returned with failure: SyntaxError: Unexpected end of JSON input
    at newEndorsementError (../fabric-samples/asset-transfer-basic/application-customerloyalty/node_modules/fabric-network/lib/transaction.js:74:12)
    at getResponsePayload (/../fabric-samples/asset-transfer-basic/application-customerloyalty/node_modules/fabric-network/lib/transaction.js:41:23)
    at Transaction.submit (../fabric-samples/asset-transfer-basic/application-customerloyalty/node_modules/fabric-network/lib/transaction.js:255:28)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Object.usePointsTransactionsInfo (../fabric-samples/asset-transfer-basic/application-customerloyalty/network/network.js:592:41)
Error: No valid responses from any peers. Errors:
    peer=peer0.org1.example.com:7051, status=500, message=error in simulation: transaction returned with failure: SyntaxError: Unexpected end of JSON input
    peer=peer0.org2.example.com:9051, status=500, message=error in simulation: transaction returned with failure: SyntaxError: Unexpected end of JSON input
    at newEndorsementError (../fabric-samples/asset-transfer-basic/application-customerloyalty/node_modules/fabric-network/lib/transaction.js:74:12)
    at getResponsePayload (../fabric-samples/asset-transfer-basic/application-customerloyalty/node_modules/fabric-network/lib/transaction.js:41:23)
    at Transaction.submit (../fabric-samples/asset-transfer-basic/application-customerloyalty/node_modules/fabric-network/lib/transaction.js:255:28)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Object.usePointsTransactionsInfo (../fabric-samples/asset-transfer-basic/application-customerloyalty/network/network.js:592:41) {
  responses: [
    {
      version: 0,
      timestamp: null,
      response: [Object],
      payload: <Buffer >,
      endorsement: null,
      connection: [Object],
      peer: 'peer0.org1.example.com:7051'
    },
    {
      version: 0,
      timestamp: null,
      response: [Object],
      payload: <Buffer >,
      endorsement: null,
      connection: [Object],
      peer: 'peer0.org2.example.com:9051'
    }
  ],
  errors: []
}
Wallet path: ../fabric-samples/asset-transfer-basic/application-customerloyalty/wallet

Get earn points transactions state for member 123456
2023-01-05T21:28:46.192Z - error: [Transaction]: Error: No valid responses from any peers. Errors:
    peer=peer0.org1.example.com:7051, status=500, message=error in simulation: transaction returned with failure: SyntaxError: Unexpected end of JSON input
    peer=peer0.org2.example.com:9051, status=500, message=error in simulation: transaction returned with failure: SyntaxError: Unexpected end of JSON input
    at newEndorsementError (../fabric-samples/asset-transfer-basic/application-customerloyalty/node_modules/fabric-network/lib/transaction.js:74:12)
    at getResponsePayload (../fabric-samples/asset-transfer-basic/application-customerloyalty/node_modules/fabric-network/lib/transaction.js:41:23)
    at Transaction.submit (../fabric-samples/asset-transfer-basic/application-customerloyalty/node_modules/fabric-network/lib/transaction.js:255:28)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Object.earnPointsTransactionsInfo (../fabric-samples/asset-transfer-basic/application-customerloyalty/network/network.js:545:25)
Error: No valid responses from any peers. Errors:
    peer=peer0.org1.example.com:7051, status=500, message=error in simulation: transaction returned with failure: SyntaxError: Unexpected end of JSON input
    peer=peer0.org2.example.com:9051, status=500, message=error in simulation: transaction returned with failure: SyntaxError: Unexpected end of JSON input
    at newEndorsementError (../fabric-samples/asset-transfer-basic/application-customerloyalty/node_modules/fabric-network/lib/transaction.js:74:12)
    at getResponsePayload (../fabric-samples/asset-transfer-basic/application-customerloyalty/node_modules/fabric-network/lib/transaction.js:41:23)
    at Transaction.submit (../fabric-samples/asset-transfer-basic/application-customerloyalty/node_modules/fabric-network/lib/transaction.js:255:28)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Object.earnPointsTransactionsInfo (../fabric-samples/asset-transfer-basic/application-customerloyalty/network/network.js:545:25) {
  responses: [
    {
      version: 0,
      timestamp: null,
      response: [Object],
      payload: <Buffer >,
      endorsement: null,
      connection: [Object],
      peer: 'peer0.org1.example.com:7051'
    },
    {
      version: 0,
      timestamp: null,
      response: [Object],
      payload: <Buffer >,
      endorsement: null,
      connection: [Object],
      peer: 'peer0.org2.example.com:9051'
    }
  ],
  errors: []
}
node:internal/errors:484
    ErrorCaptureStackTrace(err);
    ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at new NodeError (node:internal/errors:393:5)
    at ServerResponse.setHeader (node:_http_outgoing:644:11)
    at ServerResponse.header (../fabric-samples/asset-transfer-basic/application-customerloyalty/node_modules/express/lib/response.js:794:10)
    at ServerResponse.send (../fabric-samples/asset-transfer-basic/application-customerloyalty/node_modules/express/lib/response.js:174:12)
    at ServerResponse.json (../fabric-samples/asset-transfer-basic/application-customerloyalty/node_modules/express/lib/response.js:278:15)
    at ../fabric-samples/asset-transfer-basic/application-customerloyalty/app.js:278:37
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  code: 'ERR_HTTP_HEADERS_SENT'
}

приведенный выше журнал указывает, что синтаксис json неверен в файле network.js, который вызывает функцию submitTransaction. выдержка из файла Network.js:

  /*
  * Get all EarnPoints transactions data
  * @param {String} cardId Card id to connect to network
  */
    earnPointsTransactionsInfo: async function (cardId, userType, userId) {

        // Create a new file system based wallet for managing identities.
        const walletPath = path.join(process.cwd(), '/wallet');
        const wallet = await Wallets.newFileSystemWallet(walletPath);
        console.info(`Wallet path: ${walletPath}`);

        try {
            // Create a new gateway for connecting to our peer node.
            const gateway2 = new Gateway();
            await gateway2.connect(ccp, { wallet, identity: cardId, discovery: gatewayDiscovery });

            // Get the network (channel) our contract is deployed to.
            const network = await gateway2.getNetwork('mychannel');

            // Get the contract from the network.
            const contract = network.getContract('customerloyalty');

            console.info(`\nGet earn points transactions state for ${userType} ${userId}`);
            //for debug only
            console.info(await contract.submitTransaction('EarnPointsTransactionsInfo', 'userType', 'userId'));
            //
            let earnPointsTransactions = await contract.submitTransaction('EarnPointsTransactionsInfo', userType, userId);
            //for debug only
            console.info(await contract.submitTransaction('EarnPointsTransactionsInfo', userType, userId));
            //
            earnPointsTransactions = JSON.parse(earnPointsTransactions.toString());
            console.info(earnPointsTransactions);

            // Disconnect from the gateway.
            await gateway2.disconnect();

            return earnPointsTransactions;
        }
        catch(err) {
            //print and return error
            console.info(err);
            let error = {};
            error.error = err.message;
            return error;
        }

    },
    usePointsTransactionsInfo: async function (cardId, userType, userId) {

        // Create a new file system based wallet for managing identities.
        const walletPath = path.join(process.cwd(), '/wallet');
        const wallet = await Wallets.newFileSystemWallet(walletPath);
        console.info(`Wallet path: ${walletPath}`);

        try {
            // Create a new gateway for connecting to our peer node.
            const gateway2 = new Gateway();
            await gateway2.connect(ccp, { wallet, identity: cardId, discovery: gatewayDiscovery });

            // Get the network (channel) our contract is deployed to.
            const network = await gateway2.getNetwork('mychannel');

            // Get the contract from the network.
            const contract = network.getContract('customerloyalty');

            console.info(`\nGet use points transactions state for ${userType} ${userId}`);
            let usePointsTransactions = await contract.submitTransaction('UsePointsTransactionsInfo',userType, userId);
            usePointsTransactions = JSON.parse(usePointsTransactions.toString());
            console.info(usePointsTransactions);

            // Disconnect from the gateway.
            await gateway2.disconnect();

            return usePointsTransactions;
        }

Я попытался проверить журналы от однорангового узла, используя журналы докеров <имя контейнера>:

2023-01-05 22:28:46 2023-01-05T21:28:46.023Z error [c-api:contracts-spi/chaincodefromcontract.js]     [mychannel-fedc897c] SyntaxError: Unexpected end of JSON input  
2023-01-05 22:28:46 2023-01-05T21:28:46.033Z error [c-api:lib/handler.js]                             [mychannel-fedc897c] Calling chaincode Invoke() returned error response [SyntaxError: Unexpected end of JSON input
2023-01-05 22:28:46     at JSON.parse (<anonymous>)
2023-01-05 22:28:46     at CustomerLoyalty.UsePointsTransactionsInfo (/usr/local/src/lib/customerloyalty.js:110:29)
2023-01-05 22:28:46     at processTicksAndRejections (node:internal/process/task_queues:96:5)
2023-01-05 22:28:46     at async ChaincodeFromContract.invokeFunctionality (/usr/local/src/node_modules/fabric-shim/lib/contract-spi/chaincodefromcontract.js:378:32)
2023-01-05 22:28:46     at async handleMessage (/usr/local/src/node_modules/fabric-shim/lib/handler.js:602:24)]. Sending ERROR message back to peer  
2023-01-05 22:28:46 2023-01-05T21:28:46.181Z error [c-api:contracts-spi/chaincodefromcontract.js]     [mychannel-644303c3] SyntaxError: Unexpected end of JSON input  
2023-01-05 22:28:46 2023-01-05T21:28:46.184Z error [c-api:lib/handler.js]                             [mychannel-644303c3] Calling chaincode Invoke() returned error response [SyntaxError: Unexpected end of JSON input
2023-01-05 22:28:46     at JSON.parse (<anonymous>)
2023-01-05 22:28:46     at CustomerLoyalty.EarnPointsTransactionsInfo (/usr/local/src/lib/customerloyalty.js:89:29)
2023-01-05 22:28:46     at processTicksAndRejections (node:internal/process/task_queues:96:5)
2023-01-05 22:28:46     at async ChaincodeFromContract.invokeFunctionality (/usr/local/src/node_modules/fabric-shim/lib/contract-spi/chaincodefromcontract.js:378:32)
2023-01-05 22:28:46     at async handleMessage (/usr/local/src/node_modules/fabric-shim/lib/handler.js:602:24)]. Sending ERROR message back to peer  
2023-01-05 22:32:51 2023-01-05T21:32:51.616Z info [c-api:lib/handler.js]                              [mychannel-68bdfcd2] Calling chaincode Invoke() succeeded. Sending COMPLETED message back to peer  
2023-01-05 22:32:53 2023-01-05T21:32:53.977Z error [c-api:contracts-spi/chaincodefromcontract.js]     [mychannel-7f185a49] SyntaxError: Unexpected end of JSON input  
2023-01-05 22:32:53 2023-01-05T21:32:53.989Z error [c-api:lib/handler.js]                             [mychannel-7f185a49] Calling chaincode Invoke() returned error response [SyntaxError: Unexpected end of JSON input
2023-01-05 22:32:53     at JSON.parse (<anonymous>)
2023-01-05 22:32:53     at CustomerLoyalty.UsePointsTransactionsInfo (/usr/local/src/lib/customerloyalty.js:110:29)
2023-01-05 22:32:53     at processTicksAndRejections (node:internal/process/task_queues:96:5)
2023-01-05 22:32:53     at async ChaincodeFromContract.invokeFunctionality (/usr/local/src/node_modules/fabric-shim/lib/contract-spi/chaincodefromcontract.js:378:32)
2023-01-05 22:32:53     at async handleMessage (/usr/local/src/node_modules/fabric-shim/lib/handler.js:602:24)]. Sending ERROR message back to peer  
2023-01-05 22:32:54 2023-01-05T21:32:54.195Z error [c-api:contracts-spi/chaincodefromcontract.js]     [mychannel-44d04ba9] SyntaxError: Unexpected end of JSON input  
2023-01-05 22:32:54 2023-01-05T21:32:54.197Z error [c-api:lib/handler.js]                             [mychannel-44d04ba9] Calling chaincode Invoke() returned error response [SyntaxError: Unexpected end of JSON input
2023-01-05 22:32:54     at JSON.parse (<anonymous>)
2023-01-05 22:32:54     at CustomerLoyalty.EarnPointsTransactionsInfo (/usr/local/src/lib/customerloyalty.js:89:29)
2023-01-05 22:32:54     at processTicksAndRejections (node:internal/process/task_queues:96:5)
2023-01-05 22:32:54     at async ChaincodeFromContract.invokeFunctionality (/usr/local/src/node_modules/fabric-shim/lib/contract-spi/chaincodefromcontract.js:378:32)
2023-01-05 22:32:54     at async handleMessage (/usr/local/src/node_modules/fabric-shim/lib/handler.js:602:24)]. Sending ERROR message back to peer  

Вот скрипт смарт-контракта customerloyalty.js:

'use strict';

const { Contract } = require('fabric-contract-api'); const allPartnersKey = 'all-partners'; const earnPointsTransactionsKey = 'earn-points-transactions'; const usePointsTransactionsKey = 'use-points-transactions';

class CustomerLoyalty extends Contract {
// Init function executed when the ledger is instantiated
async instantiate(ctx) {
    console.info('============= START : Initialize Ledger ===========');

    await ctx.stub.putState('instantiate', Buffer.from('INIT-LEDGER'));
    await ctx.stub.putState(allPartnersKey, Buffer.from(JSON.stringify([])));
    await ctx.stub.putState(earnPointsTransactionsKey, Buffer.from(JSON.stringify([])));
    await ctx.stub.putState(usePointsTransactionsKey, Buffer.from(JSON.stringify([])));

    console.info('============= END : Initialize Ledger ===========');
}

// Add a member on the ledger
async CreateMember(ctx, member) {
    member = JSON.parse(member);

    await ctx.stub.putState(member.accountNumber, Buffer.from(JSON.stringify(member)));

    return JSON.stringify(member);
}

// Add a partner on the ledger, and add it to the all-partners list
async CreatePartner(ctx, partner) {
    partner = JSON.parse(partner);

    await ctx.stub.putState(partner.id, Buffer.from(JSON.stringify(partner)));

    let allPartners = await ctx.stub.getState(allPartnersKey);
    allPartners = JSON.parse(allPartners);
    allPartners.push(partner);
    await ctx.stub.putState(allPartnersKey, Buffer.from(JSON.stringify(allPartners)));

    return JSON.stringify(partner);
}

// Record a transaction where a member earns points
async EarnPoints(ctx, earnPoints) {
    earnPoints = JSON.parse(earnPoints);
    earnPoints.timestamp = new Date((ctx.stub.txTimestamp.seconds.low*1000)).toGMTString();
    earnPoints.transactionId = ctx.stub.txId;

    let member = await ctx.stub.getState(earnPoints.member);
    member = JSON.parse(member);
    member.points += earnPoints.points;
    await ctx.stub.putState(earnPoints.member, Buffer.from(JSON.stringify(member)));

    let earnPointsTransactions = await ctx.stub.getState(earnPointsTransactionsKey);
    earnPointsTransactions = JSON.parse(earnPointsTransactions);
    earnPointsTransactions.push(earnPoints);
    await ctx.stub.putState(earnPointsTransactionsKey, Buffer.from(JSON.stringify(earnPointsTransactions)));

    return JSON.stringify(earnPoints);
}

// Record a transaction where a member redeems points
async UsePoints(ctx, usePoints) {
    usePoints = JSON.parse(usePoints);
    usePoints.timestamp = new Date((ctx.stub.txTimestamp.seconds.low*1000)).toGMTString();
    usePoints.transactionId = ctx.stub.txId;

    let member = await ctx.stub.getState(usePoints.member);
    member = JSON.parse(member);
    if (member.points < usePoints.points) {
        throw new Error('Member does not have sufficient points');
    }
    member.points -= usePoints.points;
    await ctx.stub.putState(usePoints.member, Buffer.from(JSON.stringify(member)));

    let usePointsTransactions = await ctx.stub.getState(usePointsTransactionsKey);
    usePointsTransactions = JSON.parse(usePointsTransactions);
    usePointsTransactions.push(usePoints);
    await ctx.stub.putState(usePointsTransactionsKey, Buffer.from(JSON.stringify(usePointsTransactions)));

    return JSON.stringify(usePoints);
}

// Get earn points transactions of the particular member or partner
async EarnPointsTransactionsInfo(ctx, userType, userId) {
    let transactions = await ctx.stub.getState(earnPointsTransactionsKey);
    transactions = JSON.parse(transactions);
    let userTransactions = [];

    for (let transaction of transactions) {
        if (userType === 'member') {
            if (transaction.member === userId) {
                userTransactions.push(transaction);
            }
        } else if (userType === 'partner') {
            if (transaction.partner === userId) {
                userTransactions.push(transaction);
            }
        }
    }

    return JSON.stringify(userTransactions);
}

// Get use points transactions of the particular member or partner
async UsePointsTransactionsInfo(ctx, userType, userId) {
    let transactions = await ctx.stub.getState(usePointsTransactionsKey);
    transactions = JSON.parse(transactions);
    let userTransactions = [];

    for (let transaction of transactions) {
        if (userType === 'member') {
            if (transaction.member === userId) {
                userTransactions.push(transaction);
            }
        } else if (userType === 'partner') {
            if (transaction.partner === userId) {
                userTransactions.push(transaction);
            }
        }
    }

    return JSON.stringify(userTransactions);
}

// get the state from key
async GetState(ctx, key) {
    let data = await ctx.stub.getState(key);

    let jsonData = JSON.parse(data.toString());
    return JSON.stringify(jsonData);
}

module.exports = CustomerLoyalty;`

кажется, что есть синтаксическая ошибка с json.stringify. Я не знаю, что делать дальше, или как решить эту проблему. Есть идеи?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
77
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я подозреваю, что вы никогда не вызывали функцию создания экземпляра транзакции, поэтому ключ реестра earnPointsTransactionsKey не содержит данных:

% node --eval = "JSON.parse(Buffer.from(''))"

SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)

Вместо того, чтобы полагаться на транзакцию инициализации для установки фактически пустого начального состояния, вы можете рассмотреть вспомогательную функцию в своем смарт-контракте, что-то вроде этого:

async getEarnPointsTransactions(ctx) {
    const data = await ctx.stub.getState(earnPointsTransactionsKey);
    if (!data || data.length === 0) {
        return [];
    }

    return JSON.parse(data);
}

Также учтите, что все ваши транзакции, которые обновляют реестр, изменяют значение ключа реестра earnPointsTransactionsKey. Это вызовет конкуренцию по мере увеличения нагрузки, и вы, вероятно, столкнетесь с ошибками MVCC_READ_CONFLICT, поскольку транзакции одновременно обновляют это состояние. Эти сбои можно смягчить, внедрив в клиентское приложение логику повторных попыток отправки. Вы можете рассмотреть различные подходы к реализации, такие как:

  1. используя составные ключи для разделения данных.
  2. используя историю ключей для чтения данных, связанных с предыдущими транзакциями.

Это сообщение об ошибке указывает на то, что заголовки ответа HTTP уже отправлены клиенту и не могут быть изменены. Обычно это происходит, когда ответ уже отправлен клиенту и предпринимается попытка отправить другой ответ. Конкретное место в коде, где возникает эта ошибка, находится в «ServerResponse.header» в файле «response.js» в библиотеке «express», а конкретная функция, вызывающая проблему, — «register» в «UserController». .js" в строке 60.

Другие вопросы по теме