如何使用Java绑定通过Key获取DAML合约?
通过Key获取DAML合约的JVM实现方案
一、使用DAML RxJava绑定直接调用fetchByKey
当你通过DAML代码生成Java绑定后,每个带key的模板会自动生成对应的fetchByKey方法,无需手动处理底层通信。
假设你的DAML模板定义如下(带Text类型的key):
template User with userId: Text name: Text where signatory userId key userId : Text maintainer key
生成绑定后,可通过LedgerClient调用fetchByKey,示例代码(Java):
import com.daml.ledger.javaapi.data.Text; import com.daml.ledger.rxjava.components.LedgerClient; import com.your.package.User; import io.reactivex.Single; public class DamlFetchExample { public static Single<User.Contract> fetchUserByKey(LedgerClient ledgerClient, String party, String userId) { // 构造模板的Key对象 User.Key userKey = new User.Key(new Text(userId)); // 调用fetchByKey并转换为具体合约类型 return ledgerClient.getActiveContractsClient() .fetchByKey(User.TEMPLATE_ID, userKey, party) .map(fetchResult -> User.Contract.fromValue(fetchResult.getContract())); } }
Kotlin简化版本:
import com.daml.ledger.javaapi.data.Text import com.daml.ledger.rxjava.components.LedgerClient import com.your.package.User import io.reactivex.Single fun fetchUserByKey(ledgerClient: LedgerClient, party: String, userId: String): Single<User.Contract> { val userKey = User.Key(Text(userId)) return ledgerClient.activeContractsClient .fetchByKey(User.TEMPLATE_ID, userKey, party) .map { User.Contract.fromValue(it.contract) } }
注意事项:
- 需先通过
daml codegen java生成对应模板的Java绑定类 party必须是有权限查看目标合约的参与方- 若合约不存在,
fetchByKey会返回错误,可通过Single.onErrorResumeNext处理该场景
二、使用DAML JSON-API客户端(无需手动构造请求)
如果倾向于用JSON-API,DAML提供官方客户端库,无需手动拼接JSON请求。
1. 添加Maven依赖
<dependency> <groupId>com.daml</groupId> <artifactId>daml-json-api-client</artifactId> <version>你的DAML版本</version> </dependency>
2. Java示例代码
import com.daml.jsonapi.client.JsonApiClient; import com.daml.jsonapi.client.JsonApiClientConfig; import com.daml.jsonapi.generated.models.FetchRequest; import com.daml.jsonapi.generated.models.User; import java.net.URI; import java.util.concurrent.CompletableFuture; public class JsonApiFetchExample { public static CompletableFuture<User.Contract> fetchUserByKey(String ledgerUrl, String party, String userId) { // 初始化JSON-API客户端 JsonApiClient client = JsonApiClient.of(JsonApiClientConfig.builder() .ledgerUri(URI.create(ledgerUrl)) .build()); // 构造fetch请求 FetchRequest fetchRequest = FetchRequest.builder() .templateId("your.package:User") .key(userId) .party(party) .build(); // 发送请求并转换结果 return client.fetch(fetchRequest) .thenApply(response -> response.getContract().as(User.Contract.class)); } }
常见问题说明
- 官方示例未展示
fetchByKey是因为默认使用不带key的模板,并非该功能不存在 - 无需将合约存储到本地数据库再查询,直接通过上述两种方法即可从账本直接通过key获取合约,效率更高
内容的提问来源于stack exchange,提问作者Vsevolod
相关产品推荐
相关产品推荐

