Я адаптирую коммерческий пример из документации по Hyperledger fabri c. Я хотел иметь два списка для двух типов отдельных активов: Лицензии и Экземпляры. При выполнении функции создания экземпляра (см. Ниже) я получаю следующий код ошибки:
mychannel-46929be4] Calling chaincode Invoke() returned error response [TypeError: Converting circular structure to JSON
dev-peer0.org2.example.com-cp_0-a3fdadf58dfce7730ff554e8e9761d6e18d63bb408441a42818daeacbfc9e75c|
--> starting at object with constructor 'LicenseContext'
dev-peer0.org2.example.com-cp_0-a3fdadf58dfce7730ff554e8e9761d6e18d63bb408441a42818daeacbfc9e75c| | property 'licenseList' -> object with constructor 'LicenseList'
dev-peer0.org2.example.com-cp_0-a3fdadf58dfce7730ff554e8e9761d6e18d63bb408441a42818daeacbfc9e75c|
--- property 'ctx' closes the circle
dev-peer0.org2.example.com-cp_0-a3fdadf58dfce7730ff554e8e9761d6e18d63bb408441a42818daeacbfc9e75c| at JSON.stringify (<anonymous>)
dev-peer0.org2.example.com-cp_0-a3fdadf58dfce7730ff554e8e9761d6e18d63bb408441a42818daeacbfc9e75c| at Function.serialize (/usr/local/src/ledger-api/state.js:50:33)
dev-peer0.org2.example.com-cp_0-a3fdadf58dfce7730ff554e8e9761d6e18d63bb408441a42818daeacbfc9e75c| at InstanceList.addState (/usr/local/src/ledger-api/statelist.js:33:26)
dev-peer0.org2.example.com-cp_0-a3fdadf58dfce7730ff554e8e9761d6e18d63bb408441a42818daeacbfc9e75c| at InstanceList.addInstance (/usr/local/src/lib/instanceList.js:16:21)
dev-peer0.org2.example.com-cp_0-a3fdadf58dfce7730ff554e8e9761d6e18d63bb408441a42818daeacbfc9e75c| at LicenseContract.createInstance1 (/usr/local/src/lib/licensecontract.js:119:28)
dev-peer0.org2.example.com-cp_0-a3fdadf58dfce7730ff554e8e9761d6e18d63bb408441a42818daeacbfc9e75c| at processTicksAndRejections (internal/process/task_queues.js:85:5)
dev-peer0.org2.example.com-cp_0-a3fdadf58dfce7730ff554e8e9761d6e18d63bb408441a42818daeacbfc9e75c| at async ChaincodeFromContract.invokeFunctionality (/usr/local/src/node_modules/fabric-shim/lib/contract-spi/chaincodefromcontract.js:379:32)
dev-peer0.org2.example.com-cp_0-a3fdadf58dfce7730ff554e8e9761d6e18d63bb408441a42818daeacbfc9e75c| at async handleMessage (/usr/local/src/node_modules/fabric-shim/lib/handler.js:580:24)]. Sending ERROR message back to peer
Я добавил два списка в контекст транзакции следующим образом:
/**
* A custom context provides easy access to list of all licenses.
*/
class LicenseContext extends Context {
constructor() {
super();
// All licenses & instances are held in a list
this.licenseList = new LicenseList(this);
this.instanceList = new InstanceList(this);
}
}
Следующая функция вызывается в коде цепи:
async createInstance(ctx, owner, id, licenseNumber) {
// See if instance already exists:
let instanceKey = Instance.makeKey([id]);
let instance = await ctx.instanceList.getInstance(instanceKey);
if(instance != null) {
throw(new Error('Instance ID Already Exists'));
}
// Create an instance of the instance
instance = Instance.createInstance(ctx, owner, id, licenseNumber, 0, 0);
// Smart contract, sets instance to passive state
instance.setPassive();
// Add the instance to the list of all instances in the ledger world state
await ctx.instanceList.addInstance(instance);
return instance;
}
Класс экземпляра:
'use strict';
// Utility class for ledger state
const State = require('../ledger-api/state.js');
// Enumerate instance state values
const cpState = {
ACTIVE: 1,
PASSIVE: 2,
};
class Instance extends State {
constructor(obj) {
super(Instance.getClass(), [obj.id]);
Object.assign(this, obj);
}
/**
* Basic getters and setters
*/
getOwner() {
return this.owner;
}
setOwner(newOwner) {
this.owner = newOwner;
}
getActiveLicense() {
return this.licenseNumber;
}
setActiveLicense(newLicenseNumber) {
this.licenseNumber = newLicenseNumber;
}
getUsedCapacity() {
return this.usedCapacity;
}
setUsedCapacity(newCapacity) {
this.capacity = newCapacity;
}
getActiveCapacity() {
return this.capacity;
}
setActiveCapacity(newCapacity) {
this.activeCapacity = newCapacity;
}
isActive() {
return this.currentState === cpState.ACTIVE;
}
setActive() {
this.currentState = cpState.ACTIVE;
}
isPassive() {
return this.currentState === cpState.PASSIVE;
}
setPassive() {
this.currentState = cpState.PASSIVE;
}
/**
* Parsing functions
*/
static fromBuffer(buffer) {
return Instance.deserialize(buffer);
}
toBuffer() {
return Buffer.from(JSON.stringify(this));
}
/**
* Deserialize a state data to license
* @param {Buffer} data to form back into the object
*/
static deserialize(data) {
return State.deserializeClass(data, Instance);
}
/**
* Factory method to create a license
*/
static createInstance(owner, id, licenseNumber, activeCapacity, usedCapacity) {
return new Instance({owner, id, licenseNumber, activeCapacity, usedCapacity});
}
static getClass() {
return 'org.datadobi.instance';
}
}
module.exports = Instance;
Класс InstanceList:
'use strict';
// Utility class for collections of ledger states -- a state list
const StateList = require('../ledger-api/statelist.js');
const Instance = require('./instance.js');
class InstanceList extends StateList {
constructor(ctx) {
super(ctx, 'org.datadobi.instancelist');
this.use(Instance);
}
async addInstance(instance) {
return this.addState(instance);
}
async getInstance(instance) {
return this.getState(instance);
}
async updateInstance(instance) {
return this.updateState(instance);
}
}
module.exports = InstanceList;
Я не понимаю, почему можно добавить лицензию в licenseList, но когда я пытаюсь добавить экземпляр в instanceList, я получаю эту ошибку типа. У кого-нибудь есть идея, где мне искать ошибку? Я новичок в javascript и Hyperledger Fabri c, любая помощь приветствуется.