1

I am trying to develop a chaincode for Hyperledger Fabric 1.4 using the IBM Blockchain Platform plugin for Visual Studio Code and the fabric-contract-api v1.4.2. In this situation, I am facing some problems when trying to use interfaces from my chaincode methods. This is the error:

Error: Type not properly specified for parameter myAssetConfig, can not process pure Object types

The asset I am using is called MyAsset. This is the declaration of that element:

@Object()
export class MyAsset {
    @Property()
    public propertyA: string;

    @Property()
    public propertyB: string;

    @Property()
    public propertyC?: string;

    constructor(myAssetConfig: IMyAssetConfig) {
        this.propertyA = myAssetConfig.propertyA;
        this.propertyB = myAssetConfig.propertyB;

        if (myAssetConfig.hasOwnProperty('propertyC')) {
            this.propertyC = myAssetConfig.propertyC;
        }
    }
}

Apart from it, this the content of types/index.d.ts (I am using the flag @Object here but I am not exactly sure if I should and why/why not):

@Object
export interface IMyAssetConfig {
    propertyA: string;
    propertyB: string;
    propertyC?: string;
}

export type MyAssetId = string;

Finally, this is the content of myasset-contract.ts

@Info({title: 'MyAssetContract', description: 'My MyAsset Contract'})
export class MyAssetContract extends Contract {

    @Transaction(false)
    @Returns('boolean')
    public async myAssetExists(ctx: Context, myAssetId: MyAssetId): Promise<boolean> {
        const buffer = await ctx.stub.getState(myAssetId);
        return (!!buffer && buffer.length > 0);
    }

    @Transaction()
    public async createMyAsset(ctx: Context, myAssetConfig: IMyAssetConfig): Promise<MyAssetId> {
        const myAssetId: MyAssetId = myAssetConfig.shippingCompanyId + '-' + this.generateInternMyAssetId(ctx);

        const exists = await this.myAssetExists(ctx, myAssetId);
        if (exists) {
            throw new Error(`The myAsset ${myAssetId} already exists`);
        }

        const myAsset = new MyAsset(myAssetConfig);
        const buffer = Buffer.from(JSON.stringify(myAsset));
        await ctx.stub.putState(myAssetId, buffer);

        return myAssetId;
    }

    @Transaction(false)
    @Returns('MyAsset')
    public async readMyAsset(ctx: Context, myAssetId: MyAssetId): Promise<MyAsset> {
        const exists = await this.myAssetExists(ctx, myAssetId);
        if (!exists) {
            throw new Error(`The myAsset ${myAssetId} does not exist`);
        }
        const buffer = await ctx.stub.getState(myAssetId);
        return JSON.parse(buffer.toString()) as MyAsset;
    }

    @Transaction()
    public async splitMyAsset(ctx: Context, myAssetId: MyAssetId, children: IMyAssetConfig[]): Promise<MyAssetId[]> {
        // REMOVED because it is actually irrelevant to the problem and makes the post too long.

        return [];
    }
}

Of course, this is all anonymized and reduced but I think the problem is clear enough. I can not use IMyAssetConfig as I type for the parameter myAssetConfig but there is no problem if I use string. I could understand till some point that fabric-contract-api does not accept Objects as parameters. However, if I comment all the code of createMyAsset I get no errors, and I am also using an object in splitMyAsset and I have no problem there.

Can anyone explain me what this is happening? The problems I get happen when I try to instantiate the chaincode/run tests using npm test.

Thank you very much.

msolefonte
  • 153
  • 1
  • 11
  • I guess that if the only solution is to use strings, I am going to use stringified JSONs. However, it is strange to me to see that Objects are not allowed. – msolefonte Mar 05 '20 at 15:20
  • 1
    It seems like I solved it by deleting the tag @Property from each property of the Asset. I do not know if it makes sense. – msolefonte Mar 06 '20 at 12:10

0 Answers0