im struggling with struct in solidity, im learning about it. this is a sample todo example contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Todos {
struct Todo {
string text;
bool completed;
}
// An array of 'Todo' structs
Todo[] public todos;
function create(string calldata _text) public {
// 3 ways to initialize a struct
// - calling it like a function
todos.push(Todo(_text, false));
// key value mapping
todos.push(Todo({text: _text, completed: false}));
// initialize an empty struct and then update it
Todo memory todo;
todo.text = _text;
// todo.completed initialized to false
todos.push(todo);
}
// Solidity automatically created a getter for 'todos' so
// you don't actually need this function.
function get(uint _index) public view returns (string memory text, bool completed) {
Todo storage todo = todos[_index];
return (todo.text, todo.completed);
}
// update text
function updateText(uint _index, string calldata _text) public {
Todo storage todo = todos[_index];
todo.text = _text;
}
// update completed
function toggleCompleted(uint _index) public {
Todo storage todo = todos[_index];
todo.completed = !todo.completed;
}
}
the output of the get function in truffle is:
Result { '0': 'task 1', '1': true, text: 'task 1', completed: true }
so as you can see, i expected just keys and values like this Result {text: 'task 1', completed: true }
can you explain me why? is that normal we have index alongside keys and values?
The duplicate values are not returned by the contract itself. When you inspect the encoded binary returned by the contract, you'll see that each of the values (text
and completed
) is returned just once.
However, these values are duplicated in the Truffle JS framework. The framework uses the contract's ABI JSON to decode the returned binary into other types (in this case string
and bool
).
When the framework doesn't know the parameter names (e.g. they're not specified in your source code / ABI JSON), it only decodes the returned values into number-indexed result:
Result { '0': 'task 1', '1': true }
But since your contract source code (and for that reason, also the ABI JSON generated during contract compilation) contains the parameter names, Truffle framework also adds the named properties into the Result
object while still keeping the number-indexed values to enable accessing the values by indexes as well.
Result { '0': 'task 1', '1': true, text: 'task 1', completed: true }