Circom电路无法比较时间戳问题咨询(小数值可正常运行)
问题分析与修复方案
问题出在GreaterEqThan(8)的比特宽度设置上——8比特只能处理0到255之间的数值,而Unix时间戳(秒级一般是10位十进制,对应30+比特;毫秒级是13位,对应40+比特)远大于这个范围,数值会直接溢出,导致比较逻辑完全失效。小数值测试正常只是因为它们没超过8比特的上限。
修复步骤
- 调整
GreaterEqThan的比特宽度,匹配时间戳的实际范围:- 秒级Unix时间戳用32位足够(最大支持到2106年)
- 毫秒级时间戳需要64位
- 确保输入的
expiryDate和threshold不超过设定比特宽度的最大值
修改后的完整代码
pragma circom 2.0.0; include "../node_modules/circomlib/circuits/comparators.circom"; include "../node_modules/circomlib/circuits/poseidon.circom"; template drivingLicenseConstraint() { // public signal input hashData; // SBT中存储的哈希值,由ownerAddress和expiryDate通过Poseidon生成 signal input ownerAddress; signal input threshold; // 当前时间戳,需小于有效期 // private signal input expiryDate; // 输出结果 signal output out; // 验证哈希一致性 component hash = Poseidon(2); hash.inputs[0] <== ownerAddress; hash.inputs[1] <== expiryDate; hashData === hash.out; // 验证驾照未过期:expiryDate >= threshold component greaterEqThan = GreaterEqThan(32); // 改为32位适配秒级时间戳,毫秒级用64 greaterEqThan.in[0] <== expiryDate; greaterEqThan.in[1] <== threshold; out <-- greaterEqThan.out; out === 1; } component main {public [hashData,ownerAddress,threshold]} = drivingLicenseConstraint();
额外注意事项
- 如果使用毫秒级时间戳,务必把
GreaterEqThan的参数改成64,避免再次溢出 - 测试时可以先验证时间戳的二进制长度,确保不超过设定的比特宽度
内容的提问来源于stack exchange,提问作者fabriziogianni7
相关产品推荐
相关产品推荐

