繁体   English   中英

钻头操作员和坚固性节省气体

[英]Bit operators and gas saving on solidity

一个月前我才开始研究可靠性,我正在尝试了解并运行一些关于减少气体消耗的测试。 我读过这篇文章( https://medium.com/@novablitz/storing-structs-is-costing-you-gas-774da988895e ),这似乎是一种减少存储/读取调用次数的超级有趣的方法,但是当我试试这个,我得到了完全不同的结果。 不确定我是否做错了事情,或者是否 Solidity 最近更新了位运算符,但它似乎没有工作。 使用solidity 0.8.9版本。

我的代码:

uint224 entryRange = uint224(uint160(msg.sender));
entryRange |= ref.entryCount<<160;
entryRange |= (ref.entryCount + amount)<<192;
ref.raffleEntries.push(entryRange);

entryCount 是一个 uint32,所以如果我理解正确,地址占用 160 个字节,所以可以转换为 uint160,每个 uint32 总共是 32 个字节,我需要 224 个字节。 所以 uint224 应该足以适合我的数据。

我的阅读如下:

console.log(address(uint160(entryRange)));
console.log(uint32(entryRange>>160));
console.log(uint32(entryRange>>192));

结果是,地址被很好地读取,但两个 uint 始终为 0。我试图将控制台日志放在存储中,我注意到结果没有改变,所以:

    uint224 entryRange = uint224(uint160(msg.sender));
    console.log(entryRange);
    entryRange |= ref.entryCount<<160;
    entryRange |= (ref.entryCount + amount)<<192;
    ref.raffleEntries.push(entryRange);
    console.log(entryRange);

这输出了两倍相同的值,几乎就像 |= 根本没有做任何事情,或者 console.log 只是由于某些原因而获取结果......如果有的话? 即使我相信在孤独中情况并非如此。

无论如何,在读取时我得到 0 为 uints 和一个正确的地址。 有什么想法可能是这里的问题吗?

谢谢,若昂。

我希望你能解决这个问题。 如果不是,entryCount 需要在左移之前转换为 uint224。 否则,这就像将一个 4 位数字移动 4 次或更多次。

1101 << 4:
1010
0100
1000
0000

如您所见,移动 4 次后所有信息都丢失了。 当将 entryCount 移动 160 或 192 次并且 entryRange 与 0 进行按位或运算时,也会发生同样的情况,但没有任何效果。 这就是 entryRange 只有地址信息的原因。

entryRange |= uint224(ref.entryCount)<<160;
entryRange |= uint224(ref.entryCount + amount)<<192;

这应该可以解决其他两个 uint 为 0 的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM