我在 IBM 云上部署了一个区块链。我实现了一个 Node.js 客户端应用程序,该应用程序为 MyOrg 注册了管理员用户,并在文件系统上本地导入了一个钱包。导入钱包后,我可以在链码上提交交易以将数据上传到账本中并评估交易以查询账本。一切都在使用 Node.js 客户端。
我现在想用 Java 实现一个类似的 Hyperledger 客户端。https://hyperledger.github.io/fabric-gateway-java/上的 fabric-gateway 示例与上传和查询账本的 Node.js 代码非常相似。将下面的基本 Node.js 代码与 Java 网关示例代码进行比较,Node.js 和使用的 Java 类之间有明显的对应关系(两者都有网关、网络、合同方法相似的类):
// Node.js code
// Create a new gateway, and connect to the gateway peer node(s).
gateway = new Gateway();
await gateway.connect(ccp, { wallet: wallet, identity: OrgAdmin, discovery: {"enabled": true, "asLocalhost":false }});
// Get the network channel that the smart contract is deployed to.
let network = await gateway.getNetwork('mychannel');
// Get the smart contract from the network channel.
let contract = network.getContract('mycontract');
// submit transaction to add data in the ledger
await contract.submitTransaction('txName', txParam1, txParam2);
// query the ledger
let queryResult = await contract.evaluateTransaction('queryTx', queryStr);
问题是 Java 网关示例假定本地已经有一个可用的钱包,并且没有显示如何创建该钱包。我尝试将 Node.js 客户端导入的钱包目录与 Java 网关示例一起使用,但它不起作用。它在调用下面的 .identity() 方法时抛出异常(说指定的身份“MyOrg_Admin”不存在):
// 配置用于访问网络的网关连接。Gateway.Builder builder = Gateway.createBuilder() .identity(wallet, "MyOrg_Admin") .networkConfig(networkConfigFile);
我尝试使用较低级别的 fabric-sdk-java 类来创建钱包。下面是为 MyOrg 注册管理员用户并在本地导入钱包的 Node.js 代码:
async function enrollOrgAdmin(aOrgName, aOrgCAUrl, aWalletFilePath)
{
try
{
// Create a new CA client for interacting with the CA.
const ca = new FabricCAServices(aOrgCAUrl);
// Create a new file system based wallet for managing identities.
const wallet = new FileSystemWallet(aWalletFilePath);
// Enroll the admin user, and import the new identity into the wallet.
const enrollment = await ca.enroll({ enrollmentID: OrgAdmin, enrollmentSecret: OrgAdminPasswd });
const identity = X509WalletMixin.createIdentity(aOrgName, enrollment.certificate, enrollment.key.toBytes());
await wallet.import(OrgAdmin, identity);
}
catch(error)
{
console.error(`Failed to enroll "${OrgAdmin}": ${error}`);
process.exit(1);
}
}
唯一需要的信息是 OrgCA URL 和组织名称(都可以通过解析 connection.json 文件获得)以及组织管理员用户名和密码(您只需要知道)。FabricCAServices 对应的 Java 类似乎是 HFCAClient。使用此类搜索代码示例,最有用的链接是以下链接(除了 fabric-sdk-java 源代码的单元测试): https ://developer.ibm.com/technologies/blockchain/tutorials/hyperledger-fabric -java-sdk-for-tls-enabled-fabric-network/
我注册管理员用户的 Java 代码(导入钱包的第一步):
String pemStr = "copy-pasted from connection.json['certificateAuthorities'][adr]['tlsCACerts']['pem']";
Properties caProperties = new Properties();
caProperties.put("pemBytes", pemStr.getBytes());
try
{
// caName and caUrl copy-pasted from connection.json['certificateAuthorities'][adr]['caName'] and ['url']
HFCAClient ca = HFCAClient.createNewInstance(caName, caUrl, caProperties);
CryptoSuite cryptoSuite = CryptoSuite.Factory.getCryptoSuite();
ca.setCryptoSuite(cryptoSuite);
Enrollment adminEnrollment = ca.enroll("MyOrg_Admin", "password");
}
catch (Exception e) {
e.printStackTrace();
}
ca.enroll() 调用引发此异常:错误 org.hyperledger.fabric_ca.sdk.HFCAClient - org.hyperledger.fabric.sdk.exception.CryptoException: Unable to add CA certificate to trust store。错误:java.io.IOException:数据不完整
你能帮忙注册管理员用户吗?我究竟做错了什么?
谢谢, Ionut