I'm building a game on ethereum as my first project and I'm facing with the storage and gas limits. I would like to store a storage smart contract on the blockchain to be queried after the deployment. I really need to initialize a fixed length array with constant values I insert manually. My situation is the following:
contract A {
...some states variables/modifiers and events......
uint[] public vector = new uint[](162);
vector = [.......1, 2, 3,......];
function A () {
....some code....
ContractB contract = new ContractB(vector);
}
....functions....
}
This code doesn't deploy. Apparently I exceed gas limits on remix. I tried the following:
- I split the vector in 10 different vectors and then pass just one of them to the constructor. With this the deploy works.
I really need to have just one single vector because it represents the edges set of a graph where ContractB is the data structure to build a graph. Vectors elements are ordered like this:
vector = [edge1From, edge1To, edge2From, edge2To,.......]
and I got 81 edges (162 entries in the vector).
I tought I can create a setData function that push the values in the vector one by one calling this function after the deployment but this is not my case because I need to have the vector filled before the call
ContractB contract = new ContractB(vector);
Now I can see I have two doubts:
1) Am I wrong trying to pass a vector as parameter in a function call inside the A constructor ?
2) I can see that I can create a double mapping for the edges. Something like
mapping (bool => mapping(uint => uint))
but then I will need multi-key valued mappings (more edges starting from the same point) and I will have the problem to initialize all the mappings at once like I do with the vector?
Why does the contract need to be initialized at construction time?
This should work
If the range of values for you array are small enough, you can save on gas consumption by using a more appropriate size for your
uints
. Ethereum stores values into 32-bytes slots and you pay 20,000 gas for every slot used. If you are able to use a smaller sizeduint
(remember,uint
is the same asuint256
), you'll be able to save on gas usage.For example, consider the following contract:
Calling
addBig()
each time with a previously unused index will have an execution cost of a little over 20,000 gas and results in one value being added to an array. CallingaddSmall()
each time will cost about 26,000, but you're adding 2 elements to the array. Both only use 1 slot of storage. You can get even better results if you can go smaller thanuint128
.Another option (depending on if you need to manipulate the array data) is to store your
vector
off chain. You can use an oracle to retrieve data or store your data in IPFS.If neither of those options work for your use case, then you'll have to change your data structure and/or use multiple transactions to initialize your array.