1

My problem

Suppose I have this struct:

struct TextThatWorks {
        bytes32 text;
        uint reads;
}

How can I add a address variable to it?

What I tried

I tried simply adding address someadress; inside the struct declaration, like so:

struct TextThatDoesNotWork {
        bytes32 text;
        uint reads;
        address addr;
}

I have seen many examples doing this exact same thing. Example: Solidity Docs

But when I do this, my functions break.

What happens when I try the above

What works

So, in my contract I have a Text array:

TextThatWorks[] public textArray;

And I have a function to recall the texts inside this array, which returns arrays:

function listTexts () public view returns (bytes32[], uint[]) {

        bytes32[] memory texts = new bytes32[](textArray.length);
        uint[] memory readsArray = new uint[](textArray.length);

        for (uint i = 0; i < textArray.length; i++){
            texts[i] = textArray[i].text;
            readsArray[i] = textArray[i].reads;
        }

        return (texts, readsArray);

}

This returns a nice array in the format [["some hexadecimal example"],[12]]

What does not work

The second struct, TextThatDoesNotWork, only differs of TextThatWorks because it has an address field.

When I use it, my listTexts() function stops working. It always returns empty arrays like [[],[],[]]

To accomodate the additional field, my listTexts() function becomes the following:

function listTexts () public view returns (bytes32[], uint[], address[]) {

        bytes32[] memory texts = new bytes32[](textArray.length);
        uint[] memory readsArray = new uint[](textArray.length);
        address[] memory addresses = new address[](textArray.length);

        for (uint i = 0; i < textArray.length; i++){
            texts[i] = textArray[i].text;
            readsArray[i] = textArray[i].reads;
            addresses[i] = textArray[i].addr;
        }

        return (texts, readsArray, addresses);

}

How I fill the array

function put(bytes32 _text, uint _reads) public returns (uint){
    return textArray.push(TextThatDoesNotWork({
        text: _text,
        reads: _reads,
        addr: msg.sender
    }))-1;
}
0

Make sure that you fill the array properly

TextThatDoesNotWork[] textArray;

function put(bytes32 s, uint r, address a) public {
    textArray.push(TextThatDoesNotWork({
        text: s, 
        reads: r,
        addr: a
    }));
}

enter image description here

  • Check out my edit. I added your code. I tried it, but I still cannot make it work. There's something catchy though. Whenever I run contract.put("text", 200), I get a transaction hash in the console, instead of the index returned by the function. Could the problem be the way I call the function put()? – Diego Lima Sep 30 '18 at 21:38
  • Let's solve issues one by one, because return value from put function is another issue. What do you have after actions: deployment contract -> call put(0x1221, 10) -> call listTexts()? – Aquila Sep 30 '18 at 22:00
  • btw, contract.put("text", 200) will not work, because first parameter has type bytes32, you need to convert string to bytes32, you can use web3.utils.fromAscii("text") function – Aquila Sep 30 '18 at 22:04
  • it does work, as described in the question text. My guess is that the contract makes this conversion for me. The problem arises when I add the address attribute to the struct. It simply stops working, but before appending that attribute, it works! – Diego Lima Sep 30 '18 at 22:27
  • I'm using the geth console to test this contract. Without the address attribute in the struct, I can deploy the contract, call contract.put("some text", 200), and see the new data using contract.listTexts(). – Diego Lima Sep 30 '18 at 22:29

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.