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.)
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);
});
}
sell.goods
resource passed in to the txn as a relationship.