为基于 Hyperledger Fabric v0.6 的区块链网络开发客户端应用程序(10)
- UID
- 1066743
|
为基于 Hyperledger Fabric v0.6 的区块链网络开发客户端应用程序(10)
用于链代码调用的请求规范这是 getRequestSpec 方法的代码段:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
| function getRequestSpec(params){
if(!validate.isValidJson(params)){
logHelper.logError(logger, 'getRequestSpec', 'Invalid params');
throw new Error("Invalid params");
}
var chaincodeID = config['chaincode']['id']
if(!validate.isValidString(chaincodeID)){
logHelper.logError(logger, 'getRequestSpec', 'Invalid chaincodeID');
throw new Error("Invalid chaincodeID");
}
var functionName = params.functionName;
if(!validate.isValidString(functionName)){
logHelper.logError(logger, 'getRequestSpec', 'Invalid function name');
throw new Error("Invalid function name");
}
var args = []
if(validate.isValidArray(params.args)){
args = params.args;
}
var attributes = ['username', 'role']
if(validate.isValidArray(params.attributes)){
attributes = params.attributes;
}
var spec = {
chaincodeID: chaincodeID,
fcn: functionName,
args: args,
attrs: attributes
}
return spec;
}
|
- 第 8 行将从配置 (runtime.json) 中获取部署的链代码的链代码 ID。这是我们想要调用的链代码。
- 第 14 行将获取要在链代码中调用的函数的名称。在本例中,它是 CreateLoanApplication 方法。
- 第 26 行将输入属性键。这些键已硬编码到角色和用户名中,但在理想情况下,应将它们作为参数传递给 getRequestSpec 方法。 备注:如果未在请求规范中传入属性键,这些属性不会在 TCert 获取请求中发送给 TCA,因此得到的 TCert 将没有任何嵌入式属性。当链代码尝试解析此 TCert 来获取特定属性(例如角色和用户名)实现访问控制时,该操作会失败。第 32 到 37 行包含实际的请求规范模式。
调用部署在区块链上的链代码这是 doInvoke 方法的代码段:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| var chain = bcNetwork.getChain();
var chainAsync = Promise.promisifyAll(chain);
chainAsync.getMemberAsync(user)
.then(function(member){
var tx = member.invoke(requestSpec);
tx.on('submitted', function(data) {
logHelper.logMessage(logger, 'doInvoke', 'Transaction for invoke submitted ',requestSpec);
return resolve({statusCode: constants.SUCCESS, body: data});
});
tx.on('complete', function(data) {
//logHelper.logMessage(logger, 'doInvoke', 'Transaction for invoke complete ',data);
});
tx.on('error', function (err) {
logHelper.logError(logger, 'doInvoke', 'Could not perform invoke ',err);
return reject({statusCode: constants.INTERNAL_SERVER_ERROR, body: 'Could not perform invoke ' });
});
})
|
- 第 1 到第 7 行将重复获取链对象并获取成员对象的过程。
- 第 8 行将在成员对象上调用 invoke 方法,以便根据传入的请求规范调用链代码。这次调用会返回一个事务对象。
备注 1:您需要在事务对象上注册 submitted、complete 和 error 事件,才能获知事务的状态:
- Submitted:事务已成功提交到区块链网络并被该网络执行。此时会从区块链网络返回一个事务 UUID。
- Error:事务无法提交到区块链网络,或者无法被区块链网络接受。
- Complete:事务已完成。这不代表成功完成。(complete 事件会连同 submitted 和 error 事件一起被调用。)
备注 2:调用请求仅返回链代码调用的事务 UUID。它不会返回从链代码函数本身返回的任何数据。
备注 3:即使实际的链代码函数抛出了错误且没有成功完成,也不会调用 error 事件。此时会调用 complete 事件。
我采用的方法是等待 submitted 事件。这至少表明链代码函数将被调用。要确保成功执行链代码,您可以:
- 订阅一个将在成功执行链代码函数后生成的事件。
- 查询区块链。
|
|
|
|
|
|