Search code examples
hyperledger-composer

Simple transaction in hyperledger-composer application yields expected a resource or concept error


I was building a simple business network where a user can create an assest and sell/buy the assest. I installed the playground locally and was working on it. I had success in being able to create a user and asset(goods) but sell transaction yields expected resource or concept error.

Model.cto file

/**
 * Simple buy and sell goods business network definition.
 */

namespace org.example.biznet

enum GoodsState {
  o FOR_SALE
  o SOLD
}

asset Goods identified by goodsId {
  o String goodsId
  o GoodsState state
  o String description
  --> User owner
}

participant User identified by email {
  o String email
  o String firstName
  o String lastName
  o Double balance
}

transaction Buy {
  --> User user
  --> Goods goods
  o Double productPrice
}

transaction Sell { 
  --> User user 
  --> Goods goods
  o Double sellingPrice 
}

logic.js file

/**
 * Selling the product owned by the user
 * @param {org.example.biznet.Sell} selling - the selling transaction
 * @transaction
 */

function sell(sell) {
    if(sell.user.email !== sell.goods.owner.email){
        throw new Error('The user does not own the assest');
   }
   state = sell.goods.state;
   state = 'SOLD';
   console.log('#### he can sell the goods');
   return getAssetRegistry('org.example.biznet.Goods')
     .then(function(goodsRegistry) {
     // save the updated goods status
     return goodsRegistry.update(state);
   });
 }

permissions.acl file

/**
 * Access control list for simple buy and sell network.
 */
rule Member {
    description: "Allow all participants read access to all resources"
    participant: "org.example.biznet.User"
    operation: READ
    resource: "org.example.biznet.*"
    action: ALLOW
}

rule OwnerHasFullAccessToTheirAssets {
    description: "Allow all participants full access to their assets"
    participant(p): "org.example.biznet.User"
    operation: ALL
    resource(r): "org.example.biznet.Goods"
    condition: (r.owner.getIdentifier() === p.getIdentifier())
    action: ALLOW
}

rule SystemACL {
  description:  "System ACL to permit all access"
  participant: "org.hyperledger.composer.system.Participant"
  operation: ALL
  resource: "org.hyperledger.composer.system.**"
  action: ALLOW
}

rule NetworkAdminUser {
    description: "Grant business network administrators full access to user resources"
    participant: "org.hyperledger.composer.system.NetworkAdmin"
    operation: ALL
    resource: "**"
    action: ALLOW
}

rule NetworkAdminSystem {
    description: "Grant business network administrators full access to system resources"
    participant: "org.hyperledger.composer.system.NetworkAdmin"
    operation: ALL
    resource: "org.hyperledger.composer.system.**"
    action: ALLOW
}

So after that as I previously mentioned, I tried creating a couple of users and goods this way.

{
  "$class": "org.example.biznet.User",
  "email": "memberA@gmail.com",
  "firstName": "Jenny",
  "lastName": "Jones",
  "balance": 3000
}

{
  "$class": "org.example.biznet.User",
  "email": "memberB@gmail.com",
  "firstName": "Amy",
  "lastName": "Williams",
  "balance": 5000
}

{
  "$class": "org.example.biznet.Goods",
  "goodsId": "goodsId:1",
  "state": "FOR_SALE",
  "description": "car",
  "owner": "resource:org.example.biznet.User#memberA@gmail.com"
}

It worked.

But when I try to sell an asset, the following way, I get this error that I can't figure out why

{
  "$class": "org.example.biznet.Sell",
  "sellingPrice": 5000,
  "user": "resource:org.example.biznet.User#memberA@gmail.com",
  "goods": "resource:org.example.biznet.Goods#goodsId:1"
}

Error: Error trying invoke business network. Error: No valid responses from any peers. Response from attempted peer comms was an error: Error: chaincode error (status: 500, message: Error: Expected a Resource or Concept.)


Solution

  • you have a problem in your transaction code:

     /**
     * Selling the product owned by the user
     * @param {org.example.biznet.Sell} sell - the selling transaction
     * @transaction
     */
    
    function sell(sell) {
        if(sell.user.email !== sell.goods.owner.email){
            throw new Error('The user does not own the assest');
       }
       state = 'SOLD';
       sell.goods.state = state;
       console.log('#### he can sell the goods');
       return getAssetRegistry('org.example.biznet.Goods')
         .then(function(goodsRegistry) {
         // save the updated goods status to the goods asset instance
          return goodsRegistry.update(sell.goods);
       });
     }
    
    • your @param definition is incorrect (should be 'sell')
    • you need to save the state to sell.goods resource passed in to the txn as a relationship.