Solidity 0.8.9使用位操作优化gas时uint32值读取恒为0问题求助
问题原因
- Solidity 位移运算的返回值类型与左操作数类型保持一致。你代码中的
ref.entryCount是uint32类型,直接执行<<160/<<192操作时,位移后的结果仍为uint32类型,超出32位的比特位会被直接截断,最终计算得到的结果就是0。所以你用|=赋值时相当于给原值或上0,entryRange自然不会发生变化,后续取值时两个uint32字段自然都是0。 - 该问题和Solidity 0.8.x的位运算逻辑更新无关,不管是0.8版本还是更早的版本,位移运算的类型规则都是一致的。0.8.x默认开启的溢出校验也不会拦截这个场景,因为uint32位移后截断得到的0属于合法取值。
补充小提示:你对变量的比特位长度计算是正确的,只是表述存在笔误:address占160比特,uint32占32比特,总和224比特刚好匹配uint224的容量。
修复方案
位移操作前先把uint32类型的entryCount、entryCount + amount转换为和entryRange一致的uint224类型,避免比特位被截断,修改后的存值代码如下:
uint224 entryRange = uint224(uint160(msg.sender)); // 先转换为uint224再执行位移操作 entryRange |= uint224(ref.entryCount) << 160; entryRange |= uint224(ref.entryCount + amount) << 192; ref.raffleEntries.push(entryRange);
修改后不需要调整原有取值逻辑,即可正常读出两个uint32类型的数值。
内容的提问来源于stack exchange,提问作者Joaogl
相关产品推荐
相关产品推荐

