<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>lourens.eth</title>
        <link>https://paragraph.com/@lourens</link>
        <description>undefined</description>
        <lastBuildDate>Thu, 16 Jul 2026 20:16:12 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[Bit Packing vs Gas in Solidity]]></title>
            <link>https://paragraph.com/@lourens/bit-packing-vs-gas-in-solidity</link>
            <guid>DGv1pJJogd0NXvP6SJLv</guid>
            <pubDate>Thu, 26 Jan 2023 07:42:36 GMT</pubDate>
            <description><![CDATA[Bit packing in Solidity is something I’ve been wanting to try for a while. My hypothesis was that using packing techniques would result in gas savings (and look cool). The result of the exercise was the packed-voting repo. The write-up and repo can be found here: https://github.com/lokithe5th/packed-voting I shared my repo with some colleagues, one of which asked a question I had taken for granted: “Is the gain in gas-efficiency worth the cost in terms of readability?” and “What about using a...]]></description>
            <content:encoded><![CDATA[<p>Bit packing in Solidity is something I’ve been wanting to try for a while. My hypothesis was that using packing techniques would result in gas savings (and look cool). The result of the exercise was the packed-voting repo. The write-up and repo can be found here:</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/lokithe5th/packed-voting">https://github.com/lokithe5th/packed-voting</a></p><p>I shared my repo with some colleagues, one of which asked a question I had taken for granted: “Is the gain in gas-efficiency worth the cost in terms of readability?” and “What about using a struct with appropriately sized variables?” - which is a generally accepted pattern for gas savings when using structs. (Thanks <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/bxmmm">@Ben</a>!)</p><p>The question made me realize that I had simply assumed gas savings will follow because I was using bit packing. But I hadn’t tested this out to prove my assumption. And so the <code>gas-comparison</code> branch was born.</p><p>And the results…surprised me.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/e8c9ae9d83e8954e6609e084189f8cf0def1e7ecacf09f666a25ef022f84d062.png" alt="Normal Voting vs Packed Voting" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Normal Voting vs Packed Voting</figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/e37655ab2b4b759a2807ac303b59fb8749f85a0c50bc7d59a7f8d9762f98a678.png" alt="Control Voting Implementation" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Control Voting Implementation</figcaption></figure><p>There are three versions of the Voting contract in the gas-comparison branch: <code>PackedVoting</code>, <code>NormalVoting</code> and <code>BadVoting</code></p><p><code>PackedVoting</code> is the original voting contract which uses bit packing to store proposals.</p><p><code>NormalVoting</code> implements the same <code>IVoting</code> interface as packed voting, but it stores proposals as a struct with the variables tightly packed to fit a 256 bit storage slot.</p><p><code>BadVoting</code> does the same as the previous two contracts BUT it does not implement any thoughtful arrangements of the proposal struct nor does it have any gas optimizations. I would go so far to say it is purposefully gas inefficient.</p><p><strong>To set the stage</strong>:</p><p><strong>H0</strong>: the packed voting will be the cheapest in terms of gas usage for voting</p><p><strong>H1</strong>: the packed voting will not be the cheapest in terms of gas usage for voting</p><p>For these gas tests I also allowed it to loop for 5000 <code>propose</code> and 10000 <code>vote</code> calls. <em>This did not significantly alter the gas results.</em></p><p>In contract to my expectations, the hardhat gas reporter showed that <code>NormalVoting</code> has the cheapest vote functions, by around 300 units per call (not much) when compared to <code>PackedVoting</code>. The <code>BadVoting</code> contract came last with a whopping 17 000 units more than the other two methods. We would not expect to see a contract such as <code>BadVoting</code> to be used in production, with such an obvious problem, but it can and does happen.</p><p>And so we must <strong>reject</strong> the null hypothesis. And a valuable lesson was learnt: Using bit packing without understanding why it should be used can lead to increasing gas costs.</p><p>But the gas reporter showed something else: the cost to create a proposal was cheaper in <code>PackedVoting</code> compared to <code>NormalVoting</code> (by about 100 units). This is not a significant difference and is likely to be reflective of the cost in creating the storage pointer to the appropriate proposal in the <code>_proposals</code> mapping.</p><p>The primary limitation of this test run is that this was a straightforward comparison with low contract complexity.</p><p>Although the results do not support the use of bit packing as a gas-efficiency method for these simple contracts, it does not preclude gas-optimizations through bit packing in more complex contacts. <strong>Tightly packing *structs (on the other hand) can yield significant gains in efficiency without sacrificing readability. For beginner developers, or low-complexity contracts, it makes sense to grab such low-hanging fruit first, before upping the complexity of their smart contract solutions.</strong></p><p><em>Next steps</em>: 1) I’m interested to see if bit packing yields better results for more complex contracts; 2) I would love to dig down into the bytecode to get a comprehensive understanding of where and when bit packing might save some gas - besides when storing 8 bools in an 8-bit space 😉</p><p>Interested in following my learning journey? Hit subscribe below 🤓</p><div data-type="subscribeButton" class="center-contents"><a class="email-subscribe-button" href="null">Subscribe</a></div>]]></content:encoded>
            <author>lourens@newsletter.paragraph.com (lourens.eth)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/a043a156845709c769804c8948189000478a3e507de1a7d3cd11157f86fe5300.png" length="0" type="image/png"/>
        </item>
    </channel>
</rss>