0

Is there a way to print the values of an array in my contract to a console (using truffle or geth for example)?

Suppose this is my contract:

contract MetaCoin {

    uint256[] public someNumbers;

    function writeNumber(uint256 num) public {
      someNumbers.push(num);
    }
...

Now, I managed to get one value of someNumbers, but not all of them through

> meta.someNumbers.call(0)
> BigNumber { s: 1, e: 2, c: [ 123 ] }

Note that I made an instance of the MetaCoin contract first with MetaCoin.deployed().then(a => {meta = a})

2

I see you want a method to get each added number and that can be done just by specifying the variable as public, a getter is automatically created.

But you also need to know how many items are in there, a new method must be defined.

Let's consider this contract

pragma solidity ^0.4.24;

contract MetaCoin {

    uint256[] public someNumbers;

    function writeNumber(uint256 num) public {
        someNumbers.push(num);
    }


    function getSomeNumbers() public view returns(uint256[]) {
        return someNumbers;
    }

    function getSomeNumbersLength() public view returns(uint256) {
        return someNumbers.length;
    }
}

You can call writeNumber(item) to add numbers to your array.

getSomeNumbers() public view returns(uint256[])

In order to retrieve them you can use the method getSomeNumbers() which will return the complete array of items. This however is not a good practice because n items will be added to your array and you will return n items. The number of items can be infinitely large, thus your node will not be able to return the complete array.

Another method is more scalable

getSomeNumbersLength() public view returns(uint256)

You can retrieve the count of the items and get them one by one. Calling getSomeNumbersLength() will return the length of the array and you can retrieve the items one by one by calling someNumbers(uint256 index)

Web3

Going back to how you do this in web3, you will need to call this in 2 parts

length = await meta.getSomeNumbersLength.call()

for (i = 0; i < length; i++) {
    item = await meta.someNumbers.call(i)
    // Do things with the `item`
}

Experiment with this on remix ide https://gist.github.com/cleanunicorn/0025a060e7a5657a5e19855d11d36507

  • Both options give the values which is fine, I was looking for a more interactive solution (like a command line tool that let's one inspect contract variables or a feature in Ganache). But this does the job for now – Alex Aug 9 '18 at 13:21
1

Yes you achieve the this by adding a getter function as such:

...
uint256[] public someNumbers;

function writeNumber(uint256 num) public {
    someNumbers.push(num);
}

function getNumbers() public view returns(uint256[]) {
    return someNumbers;
}
...

You can test is with the following testcode in metacoin.js:

var MetaCoin = artifacts.require("./MetaCoin.sol");

contract('MetaCoin', function(accounts) {
  it("should get an array of uint256's", async function() {
    var meta = await MetaCoin.deployed();
    await meta.writeNumber(123);
    await meta.writeNumber(321);
    await meta.writeNumber(231);

    var numberAray = await meta.getNumbers();

    assert.equal(await numberAray.length, 3, "Array did not return as expected..");
  });
});
  • yes, that's how to work with it in JS I guess - is there a way to loop through the numbers right from the console? Just would be much more interactive than having to run a script each time. When I do truffle(development)> meta.someNumbers I get { [Function] call: [Function], sendTransaction: [Function], request: [Function: bound ], estimateGas: [Function] } which looks like there is more I can do with this – Alex Aug 2 '18 at 12:29
  • Yes, you can: var meta; MetaCoin.deployed().then(function(contract){meta = contract}) meta.writeNumber(321) meta.writeNumber(123) meta.getNumbers() then it returns the array which you can loop trough! – jasper Aug 3 '18 at 7:20
  • Just in case if you actually want to loop through the array you need the add the following steps: var numbers; meta.getNumbers().then(function(numberArr){numbers= numberArr }) numbers.forEach(function(d){console.log(d)}) – jasper Aug 3 '18 at 7:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.