Sawtooth Java客户端实现:Protobuf导入问题求助
解决Sawtooth Lake Java客户端Batch构建与Protobuf导入问题
嘿,我刚好之前帮人捋过这个事儿——你大概率是把Sawtooth核心仓库里的底层client模块当成了面向开发者的Java SDK,这是很多刚接触Sawtooth的朋友容易踩的坑!
下面一步步帮你搞定:
1. 先搞对SDK:别用核心仓库的client,用官方Java SDK
Sawtooth的核心仓库里的client、messaging这些都是底层通信模块,不是给开发者直接用来构建Batch、调用REST API的工具。你需要单独引入官方维护的Java SDK,它已经封装好了所有你需要的Protobuf类、Batch构建工具和REST客户端。
如果用Maven,在pom.xml里加这个依赖:
<dependency> <groupId>org.hyperledger.sawtooth</groupId> <artifactId>sawtooth-sdk-java</artifactId> <version>1.2.0</version> <!-- 建议用和你Sawtooth节点匹配的稳定版,比如1.2.x系列 --> </dependency>
Gradle的话,在build.gradle里加:
implementation 'org.hyperledger.sawtooth:sawtooth-sdk-java:1.2.0'
2. Protobuf导入问题迎刃而解
导入SDK之后,你不用自己去编译核心仓库里的.proto文件了——SDK已经预编译了所有需要的Protobuf类,直接导入就行:
import org.hyperledger.sawtooth.sdk.protobuf.Batch; import org.hyperledger.sawtooth.sdk.protobuf.BatchHeader; import org.hyperledger.sawtooth.sdk.protobuf.Transaction; import org.hyperledger.sawtooth.sdk.protobuf.TransactionHeader;
要是之前手动加过核心仓库的Protobuf文件,建议删掉,避免类冲突。
3. 快速上手:Batch构建+提交REST API的示例代码
给你写个极简示例,把构建Batch到提交的流程串起来,你可以直接改改参数用:
import org.hyperledger.sawtooth.sdk.signing.*; import org.hyperledger.sawtooth.sdk.protobuf.*; import org.hyperledger.sawtooth.sdk.rest.RestClient; import java.util.ArrayList; import java.util.List; public class SawtoothBatchDemo { public static void main(String[] args) throws Exception { // 生成签名用的密钥对(实际项目里可以用持久化的密钥) Context context = new Secp256k1Context(); PrivateKey privateKey = context.newRandomPrivateKey(); PublicKey publicKey = context.getPublicKey(privateKey); // 1. 构造交易头 TransactionHeader txHeader = TransactionHeader.newBuilder() .setSignerPublicKey(publicKey.toString()) .setFamilyName("your-custom-family") // 替换成你的交易族名称 .setFamilyVersion("1.0") .addInputs("your-input-address") // 交易需要读取的状态地址 .addOutputs("your-output-address") // 交易会修改的状态地址 .setNonce(java.util.UUID.randomUUID().toString()) // 防重放的随机串 .build(); // 签名交易头 byte[] txHeaderBytes = txHeader.toByteArray(); String txHeaderSignature = context.sign(txHeaderBytes, privateKey); // 2. 构造交易 Transaction transaction = Transaction.newBuilder() .setHeader(txHeaderBytes) .setHeaderSignature(txHeaderSignature) .setPayload("your-transaction-data".getBytes()) // 替换成你的交易负载 .build(); // 3. 构造Batch头 BatchHeader batchHeader = BatchHeader.newBuilder() .setSignerPublicKey(publicKey.toString()) .addTransactionIds(transaction.getHeaderSignature()) .build(); // 签名Batch头 byte[] batchHeaderBytes = batchHeader.toByteArray(); String batchHeaderSignature = context.sign(batchHeaderBytes, privateKey); // 4. 构造Batch Batch batch = Batch.newBuilder() .setHeader(batchHeaderBytes) .setHeaderSignature(batchHeaderSignature) .addTransactions(transaction) .build(); // 5. 提交到Sawtooth的REST API RestClient restClient = new RestClient("http://localhost:8008"); // 替换成你的节点REST地址 BatchList batchList = BatchList.newBuilder().addBatches(batch).build(); restClient.sendBatches(batchList); System.out.println("Batch提交成功!"); } }
4. 几个要注意的坑
- 版本匹配:SDK版本必须和你的Sawtooth节点版本一致,比如节点是1.2.3,SDK就用1.2.3,不然会有兼容性问题。
- 别混用核心模块:核心仓库的
client模块是给Sawtooth内部用的,不要和官方SDK一起导入,会导致类冲突或者依赖缺失。 - 依赖拉取问题:如果Maven/Gradle没拉到SDK,检查一下仓库配置,或者去官方仓库手动下载jar包导入项目。
内容的提问来源于stack exchange,提问作者PARVATHY P B
相关产品推荐
相关产品推荐

