vyper
vyper copied to clipboard
VIP: Tightly packed structs/arrays and smaller unsigned integers
Smart contract efficiency is one of the most important methods of scaling. There is no good reason:
struct Gucci:
yolo: bool
swag: bool
needs two separate 32 bytes storage slots. Currently, the only good way to store multiple values in a single storage slot is something like this:
doubleStorage: public(bytes32)
@public
def doubleStore(amount1: uint256, amount2: uint256):
amount1_bytes32: bytes32 = convert(amount1, bytes32)
amount2_bytes32: bytes32 = convert(amount2, bytes32)
amount1_bytes: bytes[16] = slice(amount1_bytes32, start=16, len=16)
amount2_bytes: bytes[16] = slice(amount2_bytes32, start=16, len=16)
self.doubleStorage = convert(concat(amount1_bytes, amount2_bytes), bytes32)
@public
@constant
def getAmounts() -> (uint256, uint256):
firstAmount: bytes[16] = slice(self.doubleStorage, start=0, len=16)
secondAmount: bytes[16] = slice(self.doubleStorage, start=16, len=16)
return convert(firstAmount, uint256), convert(secondAmount, uint256)
With the addition of new uint sizes and tightly packed structs, this could become:
struct tightlyPacked:
amount1: uint128
amount2: uint128
Lower values would support tighter packing, with the following would taking only one storage slot:
struct evenTighter:
amount1: uint64
amount2: uint64
amount3: uint64
amount4: uint64
truuuu: bool[256]
As per a convo with @jacqueswww this probably only makes sense for structs (and possibly arrays). This should take two storage slots:
yolo: public(uint64)
swag: public(uint64)
Thanks @jacqueswww for helping me think through some of this!
Similar closed issue https://github.com/ethereum/vyper/issues/599
Notes from meeting: although the gas savings would be really large, added complexity with this that would be introduced is also quite high:
- Shift in & Shift out of storage
- Have read(sload) before doing sstore of a single value
- Coalesce/Batch both Read & Write steps
- Adding of new types
@jacqueswww where does that leave this proposal? "Still possible but requires lots of work and not a priority" or "unlikely"?
Unlikely to come sooner than later. We'd accept some contributions to work on this as an experimental feature, but it's too much of a rabbit hole to go after now.
An interesting approach using bit fields to pack 256 bool
variables into one word (32 bytes): https://mudit.blog/solidity-tips-and-tricks-to-save-gas-and-reduce-bytecode-size/#2a76