我很难从这种方法中得到答案,没有办法,我只能在迭代器中获得最终完成的对象,而没有其他对象。我肯定知道区块链中有对象,可以使用getState方法获取它们。
这是我的getStateByPartialCompositeKey代码:
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;
}
}
}
这是我的getStateByRange方法代码:
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;
}
}
}
这是我在区块链中拥有的对象之一:
{
"class":"com.example.state",
"key":"\"COMPANY1\":\"1f5ee25d-546e-46d2-96cd-f7b7a347f84f\"",
"currentState":1,
"id":"1f5ee25d-546e-46d2-96cd-f7b7a347f84f",
"issuer":"COMPANY1"
}
这是我使用它们的方式:
getStatesByPartialKey('com.example.state', 'COMPANY1');
getStatesByRange('COMPANY0', 'COMPANYz');
这是我得到的唯一答案:
[{"done":true}]
我在做什么错?我正在使用“ fabric-shim”:“ ^ 1.2.0”。
谢谢
答案 0 :(得分:1)
尝试下面的代码段
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));
}
答案 1 :(得分:1)
我遇到的问题是创建密钥,我使用的是stub.createCompositeKey,但是它在密钥的开头创建了带有u0000字符的密钥,而stub.getStateByRange方法找不到任何东西,即使我寻找使用stub.createCompositeKey方法读取的范围。
我不得不改变创建密钥的方式,然后我开始查找记录。
谢谢
答案 2 :(得分:0)
在Fabric的早期版本中,getStateByRange
API用于返回复合键,即使在对简单键进行范围查询时也是如此。例如,以下对marble02链码示例的范围查询返回了应该返回的简单键(例如marble2
,marble3
和组合键(例如color~namebluemarble2
,color~namebluemarble2
)仅marble2
和marble3
。
$ peer chaincode query -n mycc1 -v 0 -c {"Args":["getMarblesByRange","a","z"]} -o 127.0.0.1:7050 -C ch1
查询结果:
[
{"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"}
}
]
Fabric无法区分简单键还是复合键,因此GetStateByRange()
只能返回简单键。
复合键具有objectType前缀。复合键的每个部分都由空字符定界,例如chaincodeid 0x00 objectType 0x00 ck1 0x00 ck2 0x00
。这种设计确保了各种组合键类型都有一个objectType命名空间,以确保不同类型之间不会发生冲突。您可以将鼠标悬停在具有复合键的任何CouchDB记录上的 copy 图标上,如下图所示。
现在,getStateByRange()
仅返回简单键,而getStateByPartialCompositeKey()
仅返回复合键。简单键和组合键的名称空间不同,以避免冲突。有关此的更多信息,您可以参考此thread,Fabric维护人员在其中讨论了如何解决此问题。
如果您在开始和结束时执行无范围查询,则结果中将看不到任何复合键。我自己尝试过,这些是我收到的结果。
peer chaincode query -n marbles -C mychannel -c '{"Args":["getMarblesByRange", "", ""]}'
输出:
[
{"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}
}
]
但是,当我将\u0000
用作开始键时,我也收到了包含复合键的记录。
peer chaincode query -n marbles4 -C mychannel -c '{"Args":["getMarblesByRange", "\u0000", ""]}'
输出:
[
{"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}
}
]
因此,总而言之,getStateByRange
API不应用于获取具有复合键的记录,而应使用getStateByPartialCompositeKey
。