如何查询指定账户的所有NFT?Corda SDK查询条件异常排查
解决Corda中通过External ID查询特定用户NonFungibleToken返回空的问题
问题根源
Corda的NonFungibleToken状态本身并不存储Account的External ID,你直接用withExternalIds(listOf(user))作为查询条件过滤NonFungibleToken,相当于在查询一个不存在的字段,自然返回空数组。
Account的External ID保存在AccountInfo状态中,而NonFungibleToken的holder字段对应的是Account的公钥。要查询特定用户的NFT,需要先通过External ID找到对应的Account公钥,再用该公钥过滤NonFungibleToken。
解决方案
步骤1:通过External ID获取AccountInfo
调用Corda RPC的vaultQueryBy方法,根据External ID查询对应的AccountInfo,从中提取Account的公钥。
步骤2:用Account公钥查询NonFungibleToken
以NonFungibleToken的holder字段匹配Account公钥作为查询条件,筛选出该用户持有的所有NFT。
修改后的Controller代码
@GetMapping("/tokens/{user}") fun getUserTokens(@PathVariable user: UUID): ResponseEntity<String> { return try { // 1. 通过External ID查询AccountInfo val accountCriteria = QueryCriteria.VaultQueryCriteria() .withExternalIds(listOf(user)) val accountInfo = proxy.vaultQueryByCriteria(accountCriteria, AccountInfo::class.java) .states.singleOrNull()?.state?.data ?: return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Account not found") // 2. 以Account公钥为条件查询NonFungibleToken val tokenCriteria = QueryCriteria.VaultQueryCriteria( participantKeys = listOf(accountInfo.host) ) val userNFTs = proxy.vaultQueryByCriteria(tokenCriteria, NonFungibleToken::class.java).states ResponseEntity.status(HttpStatus.ACCEPTED).body("tokens: $userNFTs") } catch (e: Exception) { ResponseEntity.status(HttpStatus.BAD_REQUEST).body("exception: ${e.message}") } }
补充说明
如果需要更精确的字段匹配,也可以构造针对NonFungibleToken.holder的自定义查询条件:
val tokenExpression = QueryCriteria.VaultCustomQueryCriteria( Builder.equal(NonFungibleToken::holder, AnonymousParty(accountInfo.host)) ) val userNFTs = proxy.vaultQueryByCriteria(tokenExpression, NonFungibleToken::class.java).states
内容的提问来源于stack exchange,提问作者Ricardo Passos
相关产品推荐
相关产品推荐

