You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Coll[Byte]类型ErgoValue转为UTF-8字符串并在ErgoScript中比对

问题根因
  • 输出[B@7a1b8a46是Java语言的默认行为,不是字节内容错误:[B标识当前对象为字节数组类型,@后是对象的内存哈希值,和数组内存储的实际字节完全无关,属于打印逻辑错误,和ErgoScript执行状态不一致无关。
  • 原有寄存器写入代码存在调用错误:getBytes是字符串实例方法,不是String类的静态方法,代码中String.getBytes("utf-8")的写法无法获取目标字符串对应的字节数组,写入值本身不符合预期。
  • 额外注意:代币ID有两种存储形式,混用会导致比对失败:
    1. 原始字节形式:32字节长度,是链上代币ID的实际存储格式
    2. 可读字符串形式:32字节转十六进制得到的64位字符串,用UTF-8编码后为64字节长度,仅用于显示
正确实现方案

链下(Java/Scala 客户端侧)

写入寄存器:正确存储UTF-8字符串对应的字节集合

修正原有静态方法调用的错误,先实例化目标字符串,再转成UTF-8字节数组包装为ErgoValue:

// 替换为实际要存储的字符串,此处以SigUSD ID的十六进制显示字符串为例
String targetContent = "03faf2cb329f2e90d6d23b58d91bbb6c046aa143261cc21f52fbe2824bfcbf04";
// 调用字符串实例的getBytes方法,指定UTF-8编码
byte[] contentBytes = targetContent.getBytes("UTF-8");
Coll<Byte> byteColl = Javahelpers.SigmaDsl.Colls.fromArray(contentBytes);
ErgoValue<Coll<Byte>> regValue = ErgoValue.of(byteColl, ErgoType.byteType());

读取寄存器:正确将Coll[Byte]转回UTF-8字符串

不要直接打印toArray()返回的byte[]对象,将字节数组传入String构造方法、指定UTF-8编码即可得到正确字符串:

// 读取寄存器中存储的字节集合
val storedColl = inputBox.getRegisters.get(0).getValue.asInstanceOf[Coll[Byte]]
val storedBytes = storedColl.toArray
// 转成UTF-8字符串
val storedContent = new String(storedBytes, "UTF-8")
// 此时打印storedContent即可看到正确的字符串内容
println(storedContent)

链上(ErgoScript 合约侧)

ErgoScript没有原生字符串类型,所有字节类值(包括代币ID、寄存器存储值)直接比对Coll[Byte]类型即可,无需转码:

  • 如果寄存器存储的是原始32字节格式的代币ID(更省存储,推荐):直接取寄存器值和代币ID字节做相等判断
    // 读取R4寄存器中预存的目标代币ID(原始字节格式)
    val targetTokenId = SELF.R4[Coll[Byte]].get
    // 校验交易中存在该ID的代币
    val valid = INPUTS.flatMap(box => box.tokens).exists(token => token._1 == targetTokenId)
    
  • 如果寄存器存储的是十六进制字符串转成的UTF-8字节:需要先将待比对的原始代币ID转成对应十六进制字符串的UTF-8字节格式再比对,该方式多占一倍存储空间,不推荐使用。

内容的提问来源于stack exchange,提问作者kii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 01:57:22