Solidity – How to Add Data to a Dynamic Array

arrayssolidity

I am trying to create a list of bytes data on a dynamic array. Here is a very simple contract for an example of what I want to do. I want to be able to call the array to get a list, but it only returns the first bytes32 input I insert using the function.

pragma solidity ^0.4.24;

contract MyContract {

     /* Bytes32 Array */
     bytes32[] public MyBytesArray;


     function addItem(bytes32 _item) public {
          MyBytesArray.push(_item) -1;
     }
}

Also is there a way to remove items from the array in another function?

Best Answer

-1 doesn't do anything in this case. The push method returns the array length. This value minus one gives the index of the element that was pushed (e.g. 0 because length will now be 1 and the index starts counting at 0). You're not doing anything with the return value, so it's just wasting gas to compute the offset.

The MyBytesArray() function that you get for "free" owing to the keyword public accepts one argument for the index and returns one element at a time. I suspect index is defaulting to 0 because it's overlooked when you call it. If so, that returns the first element. If you ask for the second element (index 1) then you'll get the second element.

On the caller side, using a Truffle contract abstraction, it would look something like:

var myContract; var rowToGet = 0; // 1,2,3 var instance = MyContract.Deployed() .then(function(instance) { myContract = instance; return myContract.myBytesArray(rowToGet); }) .then(function(response) { console.log(response); // one element of the array }); }

It might help to think of public as giving you a "free" function that looks like this:

function MyBytesArray(uint index) public view returns(bytes32) { return(MyBytesArray[index]); }

By convention, your variable name should be camelCase, e.g. myBytesArray.

You can return the entire array but this is expensive, possibly wastefully so, and there are concerns about scaling. That said, you could add a function:

function getMyBytesArray() public view returns(bytes32[]) { return myBytesArray; }

Hope it helps.