Hey, Iโm thinking about a pattern that could be made safer by having a readonly
keyword.
When you have a Struct in storage, and you need to read from a couple of attributes of the Struct but not all, you have a couple of alternatives to write your function.
See example below:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract Packer {
struct Box {
uint256 x;
uint256 y;
uint256 z;
}
mapping(uint256 => Box) public boxes;
bool flagged;
constructor() {
boxes[0] = Box(1, 0, 0);
boxes[1] = Box(1, 1, 0);
boxes[2] = Box(0, 0, 1);
}
function somethingRef(uint256 n) public {
Box storage box = boxes[n];
if (box.x == 1 && box.y == 1) {
flagged = true;
}
}
function somethingVerbose(uint256 n) public {
if (boxes[n].x == 1 && boxes[n].y == 1) {
flagged = true;
}
}
function somethingStructMemory(uint256 n) public {
Box memory box = boxes[n];
if (box.x == 1 && box.y == 1) {
flagged = true;
}
}
function somethingLocalMemory(uint256 n) public {
uint256 x = boxes[n].x;
uint256 y = boxes[n].y;
if (x == 1 && y == 1) {
flagged = true;
}
}
}
I like option somethingRef()
because itโs shorter, consumes less gas and you can clearly see you are operating on the Struct attributes. The tradeoff I see is that it could be dangerous to inadvertently do box.x = <something>
and assign a value by mistake.
If we had a way to declare it like Box readonly storage box = boxes[n];
and the compiler to warn about any unwanted assignment we could make it safer to use.
Gas usage:
ยท--------------------------------------|---------------------------|-------------|-----------------------------ยท
| Solc version: 0.8.7 ยท Optimizer enabled: true ยท Runs: 200 ยท Block limit: 12000000 gas โ
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Methods โ
ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Contract ยท Method ยท Min ยท Max ยท Avg ยท # calls ยท usd (avg) โ
ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Packer ยท somethingLocalMemory ยท - ยท - ยท 25754 ยท 1 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Packer ยท somethingRef ยท - ยท - ยท 25730 ยท 1 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Packer ยท somethingStructMemory ยท - ยท - ยท 28009 ยท 1 ยท - โ
ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Packer ยท somethingVerbose ยท - ยท - ยท 25885 ยท 1 ยท - โ