I want to return an array of tuples (source from an array of structs) from one of my smart contract view functions. What's the most effective way to do this?

Do I:

  • Build a JSON ARRAY as string with each struct/tuple as an element and then return that string for my Node.JS client to parse?

  • Do I add an extra function call that returns how many elements are available and then call a function that gets one element at a time with a Solidity tuple returned with each ndx passed to the function? This worries me because if there is a change in the number of available elements it would invalidate the iteration loop on the Web3.js client side.

What's the best way to do this from a performance point of view? Hopefully I can do this without modifying the contract state from a pure view function. Again, I'd like to return all the available elements at once if possible.

Here is my current smart contract code that shows the array of structs I'd like to return in bulk to a calling client (in my case, that client is a Node.JS app using Web3.js).

pragma solidity ^0.4.23;

// Can't seem to use experimental "return struct" feature at this time.  Leaving
//  this pragma statement here commented out for the day we can.
// pragma experimental ABIEncoderV2;

import "github.com/OpenZeppelin/zeppelin-solidity/contracts/ownership/Ownable.sol";

contract VideoDummyData is Ownable{

    // The array of video bookmarks this smart contract instance contains.
    VideoBookmark[] m_aryVideoBookmarks;

    // Constructor, MUST be public.
    constructor() public {
        // Sample data.
        m_aryVideoBookmarks.push(VideoBookmark("ZUSPD9zOyJs", 0, "The first video:0 seconds", true));
        m_aryVideoBookmarks.push(VideoBookmark("4nqJiBRNQuw", 5, "The second video:5 seconds", false));
        m_aryVideoBookmarks.push(VideoBookmark("PLcxE4UkJt0", 27, "The third video:27 seconds", true));
    }

    // This is the structure that holds the fields for one video lin.
    struct VideoBookmark {
        // Unique ID of the video.
        string video_id;
        // The offset into the video in seconds where the bookmark occurs.
        uint32 offset_in_seconds;
        // The user defined comment that describes the bookmark.
        string comment;
        // Flag that if TRUE, indicates the video is still available.  FALSE means it's not.
        bool is_available;
    }

    function videoBookmarksToJson() private returns(string)
    {
        // Bounds check on the desired index.
        require(ndx < m_aryVideoBookmarks.length);

        // Build a JSON string by "hand".
        // NOT IMPLEMENTED YET.

    }

    // Return one of the sample video IDs.
    function getVideoBookarkAt (uint ndx) public view returns(string, uint32, string, bool)
    {
        // Bounds check on the desired index.
        require(ndx < m_aryVideoBookmarks.length);

        return (
            m_aryVideoBookmarks[ndx].video_id, 
            m_aryVideoBookmarks[ndx].offset_in_seconds, 
            m_aryVideoBookmarks[ndx].comment,
            m_aryVideoBookmarks[ndx].is_available
        );

        // See note above the pragma statement above.
        // return m_aryVideoBookmarks[ndx];
    }
}

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.