Search code examples
ethereumsoliditysmartcontracts

Initialize a big fixed length array in Solidity


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?


Solution

  • Why does the contract need to be initialized at construction time?

    This should work

    pragma solidity ^0.4.2;
    
    contract Graph {
        address owner;
    
        struct GraphEdge {
            uint128 from;
            uint128 to;
        }
    
        GraphEdge[] public graph;
        bool public initialized = false;
    
        constructor() public {
            owner = msg.sender;
        }
    
        function addEdge(uint128 edgeFrom, uint128 edgeTo) public {
            require(!initialized);
            graph.push(GraphEdge({
                from: edgeFrom,
                to: edgeTo
            }));
        }
    
        function finalize() public {
            require(msg.sender == owner);
            initialized = true;
        }
    }
    
    contract ContractB {
        Graph graph;
    
        constructor(address graphAddress) public {
            Graph _graph = Graph(graphAddress);
            require(_graph.initialized());
            graph = _graph;
        }
    }