简体   繁体   English

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

[英]Bit operators and gas saving on solidity

I've only started looking into solidity like a month ago and I'm trying to understand and run some tests on reducing gas consumption.一个月前我才开始研究可靠性,我正在尝试了解并运行一些关于减少气体消耗的测试。 I've read this ( https://medium.com/@novablitz/storing-structs-is-costing-you-gas-774da988895e ) and it seems like a super interesting way of reducing the number of storage/read calls but when I try this I'm getting quite different results.我读过这篇文章( https://medium.com/@novablitz/storing-structs-is-costing-you-gas-774da988895e ),这似乎是一种减少存储/读取调用次数的超级有趣的方法,但是当我试试这个,我得到了完全不同的结果。 Not sure if I'm doing something incorrectly or if maybe solidity recently updated the bit operators but it doesn't seem to be working.不确定我是否做错了事情,或者是否 Solidity 最近更新了位运算符,但它似乎没有工作。 Using solidity version 0.8.9.使用solidity 0.8.9版本。

My code:我的代码:

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

entryCount is a uint32 so if I understand correctly, address takes up 160 bytes, so can be converted to a uint160, each uint32 is 32 bytes on in total I would need 224 bytes. entryCount 是一个 uint32,所以如果我理解正确,地址占用 160 个字节,所以可以转换为 uint160,每个 uint32 总共是 32 个字节,我需要 224 个字节。 So a uint224 should be enough to fit my data.所以 uint224 应该足以适合我的数据。

My read is as follows:我的阅读如下:

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

The result is, the address is being read nicely but the two uints are always 0. I've tried to place console logs in the storing and I noticed the result doesn't change so:结果是,地址被很好地读取,但两个 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);

This outputs twice the same value almost like the |= is simply not doing anything, either that or the console.log is only taking the result due to some... async if any?这输出了两倍相同的值,几乎就像 |= 根本没有做任何事情,或者 console.log 只是由于某些原因而获取结果......如果有的话? even tho I believe that's not the case in solitidy.即使我相信在孤独中情况并非如此。

Never the less, on the read I'm getting 0 for both uints and a correct address.无论如何,在读取时我得到 0 为 uints 和一个正确的地址。 Any ideas what the issue could be here?有什么想法可能是这里的问题吗?

Thanks, João.谢谢,若昂。

I hope you were able to solve the problem.我希望你能解决这个问题。 If not, entryCount needs to be converted to uint224 before being left shifted.如果不是,entryCount 需要在左移之前转换为 uint224。 Otherwise, it's like shifting a 4 bit number 4 times or more.否则,这就像将一个 4 位数字移动 4 次或更多次。

1101 << 4:
1010
0100
1000
0000

As you can see all the info is lost after shifting 4 times.如您所见,移动 4 次后所有信息都丢失了。 Same thing happens when shifting entryCount 160 or 192 times and entryRange is bitwise ORed with 0 which has no effect.当将 entryCount 移动 160 或 192 次并且 entryRange 与 0 进行按位或运算时,也会发生同样的情况,但没有任何效果。 That is why entryRange only has the address information.这就是 entryRange 只有地址信息的原因。

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

This should solve the problem of getting 0 for the other two uints.这应该可以解决其他两个 uint 为 0 的问题。

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

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