Why are the following added assets not persisted i

2019-06-11 14:57发布

问题:

I have the following application code in my Hyperledger composer environment (My question only pertains to the RequestT transaction as I am yet to write the Respond transaction code):

Model Code (.cto)

/*
* Defines a data model for chama transaction
*/

namespace org.acme.account.chama

enum responseType {
  o YES
  o NO
}

enum requestType{
  o DEPOSIT
  o WITHDRAW
}

enum State {
  o PENDING_AUTHORIZATION
  o AUTHORIZED
  o DECLINED
}

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

asset Request identified by id {
  o String id
  o requestType type
  o State state
  o Double amount
  o Response[] responses
  --> User user
}

asset Account identified by id {
  o String id
  o requestType transaction
  o Double amount
  --> Request request
  --> User user
}

asset Response identified by id {
  o String id
  o responseType reply
  --> Request request
  --> User user
}

transaction Respond {
  o responseType reply
  --> Request request
  --> User user
}

transaction RequestT{
  o Request request
}

JavaScript code (.js)

var getAccountBalance = function(){
  var accountQuery = buildQuery("SELECT org.acme.account.chama.Account \
    WHERE (transaction == _$type)");
  return query(accountQuery, { type: "DEPOSIT" })
    // sum up the amounts of the deposits made
    .then(function(deposits){
      var depositedAmount = 0;
      deposits.forEach(function(deposit){
        depositedAmount += deposit.amount;
      });
      return depositedAmount;
    })
    .then(function(depositedAmount){
      return query(accountQuery, { type: "WITHDRAW" })
        // sum up the amounts of the withdrawals made
        .then(function(withdrawals){
          var withdrawnAmount = 0;
          withdrawals.forEach(function(withdrawal){
            withdrawnAmount += withdrawal.amount;
          });
          return withdrawnAmount;
        })
        // find the account's balance
        .then(function(withdrawnAmount){
          return depositedAmount - withdrawnAmount;
        });
    });
};

/**
* @param  {org.acme.account.chama.RequestT} requestT
* @transaction
*/
function request(requestT){
  var request = requestT.request;
  var user = request.user;
  // get the account's balance
  getAccountBalance()
    .then(function(balance){
      // reject deposit if user has insufficient funds
      if ((user.balance < request.amount) && (request.type === "DEPOSIT")){
        throw new Error("ERROR: User has insufficient funds!");
      }
      // reject withdrawal if account has insufficient funds
      if ((balance < request.amount) && (request.type === "WITHDRAW")){
        throw new Error("ERROR: Account has insufficient funds!");
      }
      console.log("CHECKING VALIDITY");
      return balance;
    })
    // get the users' registry
    .then(function(){
      console.log("GETTING USERS' REGISTRY");
      return getParticipantRegistry("org.acme.account.chama.User");
    })
    // get all the users
    .then(function(userRegistry){
      console.log("GETTING ALL USERS");
      return userRegistry.getAll();
    })
    .then(function(users){
      console.log("USERS:", users);
      // authorize the request if the requester is the sole user
      if (users.length === 1){
        request.state = "AUTHORIZED";
      }
      console.log("GETTING REQUESTS' REGISTRY");
      // get the requests' registry
      return getAssetRegistry("org.acme.account.chama.Request")
        // save the request
        .then(function(requestRegistry){
          return requestRegistry.add(request)
            // get all of the requests
            .then(function(){ return requestRegistry.getAll(); })
            // obtain the total number of requests made
            .then(function(requests){ console.log("REQUESTS", requests);return requests.length; });
        });
    })
    .then(function(length){
      console.log("LENGTH:", length);
      // if the request has been authorized
      if (request.state === "AUTHORIZED"){
        console.log("GETTING ACCOUNT REGISTRY");
        return getAssetRegistry("org.acme.account.chama.Account")
          .then(function(accountRegistry){
            // create new deposit transaction
            var factory = getFactory();
            var depositTransaction = factory.newResource(
              "org.acme.account.chama", "Account", user.id + length);
            depositTransaction.transaction = request.type;
            depositTransaction.amount = request.amount;
            depositTransaction.user =  request.user;
            depositTransaction.request = request;
            console.log("DEPO T:", depositTransaction);
            console.log("ADDING DEPOSIT REQUEST TO REGISTRY");
            // save deposit transaction
            return accountRegistry.add(depositTransaction);
          })
          // update user's balance
          .then(function(){
            console.log("GETTING USER REGISTRY");
            return getParticipantRegistry("org.acme.account.chama.User")
              .then(function(userRegistry){
                if (request.type === "WITHDRAW"){
                  user.balance += request.amount;
                } else if (request.type === "DEPOSIT"){
                  user.balance -= request.amount;
                }
                console.log("UPDATING USER IN REGISTRY");
                return userRegistry.update(user);
              });
          });
      }
      return true;
    })
    .catch(function(error){
      alert(error);
    });
}

On the Hyperledger Composer online playground, I create a new user asset with the following data:

{
  "$class": "org.acme.account.chama.User",
  "id": "id:1001",
  "balance": 1000,
  "firstName": "ONE",
  "lastName": "ONE"
}

Now when I submit a RequestT transaction with the following data:

{
  "$class": "org.acme.account.chama.RequestT",
  "request": {
    "$class": "org.acme.account.chama.Request",
    "id": "id:8729",
    "type": "DEPOSIT",
    "state": "PENDING_AUTHORIZATION",
    "amount": 500,
    "responses": [],
    "user": "resource:org.acme.account.chama.User#id:1001"
  }
}

All promises seem to be running and resolve without an error as depicted in the following image:

But the assets added in the JavaScript code do not get persisted to the registry. Any ideas why?

回答1:

Your promise chain is more complex than it needs to be, but the reason that nothing appears to work is you have forgotten a return statement before the getAccountBalance, so you just need

function request(requestT){
var request = requestT.request;
var user = request.user;
// get the account's balance
return getAccountBalance()