1
votes

Problème pour obtenir la réponse de la structure hyperledger getStateByRange et getStateByPartialCompositeKey

J'ai du mal à obtenir une réponse de cette méthode, peu importe ce que je fais Je n'obtiens que l'objet final terminé dans l'itérateur sans autres objets. Je sais avec certitude qu'il y a des objets dans la blockchain, je peux les obtenir en utilisant la méthode getState.

Voici mon code pour getStateByPartialCompositeKey:

[{"done":true}]

Voici mon code pour la méthode getStateByRange:

getStatesByPartialKey('com.example.state', 'COMPANY1');
getStatesByRange('COMPANY0', 'COMPANYz');

C'est l'un des objets que j'ai dans la blockchain:

{
    "class":"com.example.state",
    "key":"\"COMPANY1\":\"1f5ee25d-546e-46d2-96cd-f7b7a347f84f\"",
    "currentState":1,
    "id":"1f5ee25d-546e-46d2-96cd-f7b7a347f84f",
    "issuer":"COMPANY1"
}

Voici comment Je les utilise:

public async getStatesByRange(startKey: string, endKey: string): Promise<any> {
    const states = [];
    const datas = [];
    const iterator = await this.ctx.stub.getStateByRange(startKey, endKey);

    while (true) {
        const data = await iterator.next();
        datas.push(data);

        if (data.value && data.value.value.toString()) {
            const state = State.deserialize(data.value.value, this.supportedClasses);
            states.push(state);
        }
        if (data.done) {
            await iterator.close();
            return datas;
        }
    }
}

Voici la seule réponse que j'obtiens:

public async getStatesByPartialKey(className: string, key: string): Promise<any> {
    const states = [];
    const datas = [];
    const iterator = await this.ctx.stub.getStateByPartialCompositeKey(className, [key]);

    while (true) {
        const data = await iterator.next();
        datas.push(data);

        if (data.value && data.value.value.toString()) {
            const state = State.deserialize(data.value.value, this.supportedClasses);
            states.push(state);
        }
        if (data.done) {
            await iterator.close();
            return datas;
        }
    }
}

Que fais-je faux? J'utilise "fabric-shim": "^ 1.2.0".

Merci


0 commentaires

3 Réponses :


1
votes

Essayez mon extrait de code ci-dessous

let startKey = 'COMPANY0';
let endKey = 'COMPANYz';

// empty string for start and end keys returns full state
let iterator = await stub.getStateByRange(startKey, endKey);

let allResults = [];
while (true) {
  let res = await iterator.next();

  if (res.value && res.value.value.toString()) {
    let jsonRes = {};
    console.log(res.value.value.toString('utf8'));

    jsonRes.Key = res.value.key;
    try {
      jsonRes.Record = JSON.parse(res.value.value.toString('utf8'));
    } catch (err) {
      console.log(err);
      jsonRes.Record = res.value.value.toString('utf8');
    }

    allResults.push(jsonRes);
  }
  if (res.done) {
    console.log('end of data');
    await iterator.close();
    console.info(allResults);
    return Buffer.from(JSON.stringify(allResults));
  }


0 commentaires

2
votes

Le problème que j'avais était de créer les clés, j'utilisais le stub.createCompositeKey mais il créait les clés avec un caractère u0000 au début de la clé et la méthode stub.getStateByRange ne trouvait rien, même lorsque je recherché une plage créée avec la méthode stub.createCompositeKey.

J'ai dû changer la façon dont je crée les clés, puis j'ai commencé à trouver mes enregistrements.

Merci


1 commentaires

Merci! Cela a résolu mon problème. J'utilisais aussi createCompsiteKey et getSateByRange ne retournait rien.



0
votes

Dans les versions précédentes de Fabric, l'API getStateByRange était utilisée pour renvoyer des clés composites même lors d'une requête de plage sur des clés simples. Par exemple, la requête de plage suivante sur l'exemple de code de chaîne marbre02 a renvoyé à la fois des clés simples telles que marbre2 , marbre3 et des clés composites telles que color ~ namebluemarble2 , color ~ namebluemarble2 où il n'aurait dû renvoyer que marbre2 et marble3.

$ peer chaincode query -n mycc1 -v 0 -c {"Args": ["getMarblesByRange", "a", "z"]} -o 127.0.0.1:7050 -C ch1

Résultat de la requête:

[
    {"Key":"\u0000color~name\u0000blue\u0000marble2\u0000","Record":"\u0000"}, 
    {"Key":"\u0000color~name\u0000red\u0000marble1\u0000","Record":"\u0000"}, 
    {"Key":"\u0000color~name\u0000yellow\u0000azurite\u0000","Record":"\u0000"}, 
    {"Key":"azurite","Record": 
        {"color":"yellow","docType":"marble","name":"basil","owner":"john","size":2}
    },
    {"Key":"marble1","Record": 
        {"color":"red","docType":"marble","name":"marble1","owner":"tom","size":50}
    },
    {"Key":"marble2","Record": 
        {"color":"blue","docType":"marble","name":"marble2","owner":"tom","size":70}
    }
]

Fabric n'avait aucun moyen de différencier un simple ou un composite de sorte que GetStateByRange () ne puisse renvoyer que des clés simples.

Composite les clés ont un préfixe objectType. Chaque partie de la clé composite est délimitée par un caractère nul, par exemple chaincodeid 0x00 objectType 0x00 ck1 0x00 ck2 0x00 . Cette conception garantit que divers types de clés composites ont un espace de noms objectType pour garantir l'absence de collisions entre les types. Vous pouvez le vérifier vous-même en survolant l'icône copier sur n'importe quel enregistrement CouchDB qui a une clé composite comme dans l'image ci-dessous. couchdb-composite-key

Maintenant, getStateByRange () ne renvoie que des clés simples et getStateByPartialCompositeKey () renvoie uniquement composite clés. Les espaces de noms des clés simples et des clés composites sont différents pour éviter les collisions. Pour plus d'informations à ce sujet, vous pouvez vous référer à ce thread , où les responsables de Fabric avaient un discussion sur la façon d'aborder ce problème.

Si vous effectuez une requête de plage illimitée au début et à la fin, vous ne verrez aucune clé composite dans les résultats. Je l'ai essayé moi-même et voici les résultats que j'ai reçus.

peer chaincode query -n marbles -C mychannel -c '{"Args": ["getMarblesByRange", "", "" ]} '

Sortie:

[
    {"Key":"azurite","Record": 
        {"color":"yellow","docType":"marble","name":"azurite","owner":"john","size":2}
    },
    {"Key":"marble1","Record": 
        {"color":"red","docType":"marble","name":"marble1","owner":"tom","size":50}
    },
    {"Key":"marble2","Record": 
        {"color":"blue","docType":"marble","name":"marble2","owner":"tom","size":70}
    }
]

Cependant, lorsque j'ai gardé \ u0000 comme clé de démarrage, J'ai également reçu des enregistrements contenant une clé composite.

requête de code de chaîne homologue -n marbles4 -C mon canal -c '{"Args": ["getMarblesByRange", "\ u0000", ""] } '

Résultat:

[
    {"Key":"color~namebluemarble3", "Record":}
    {"Key":"color~nameredmarble2", "Record":}

    {"Key":"marble2", "Record": 
        {"docType":"marble","name":"marble2","color":"red","size":50,"owner":"tom"}
    },
    {"Key":"marble3", "Record": 
        {"docType":"marble","name":"marble3","color":"blue","size":70,"owner":"tom"}
    }
]

Donc, en conclusion, l'API getStateByRange ne doit pas être utilisée pour récupère les enregistrements qui ont des clés composites, mais getStateByPartialCompositeKey.


0 commentaires