Solidity -

in #solidity8 years ago

One of the challenges I've found in Ethereum development has been in moving beyond a 'Hello World' type sample app and trying to create something a bit more realistic. Solidity is such a new language, and it sits on top of such a new platform that there just aren't many established design patterns and anti-patterns yet.

Here's a small example... I found lots of high-level guidance explaining that functions should only be used to return small values, and larger datasets ought to be handled with events. Makes sense, but nobody ever quantified an amout or defined large from small.

The function below returns a list of election names to be held on an 'election day'. It will only return a maximum of 10 bytes32 items. This function works perfectly on TestRPC / Ganache no matter how many items are returned. However, when I tried this code on the Ropsten test network, it would only return five items. If there were more than five, the function response came back empty. Note that the return array size did not matter. Returning five items in a 10 element array works just as well (efficiency aside) as returning five items in a 100 element array.

// Returns a list of all the elections (by name) in the current
// voting session.
function getAllElectionNames() public returns (bytes32[10]) {
    // Array to hold return results.
    bytes32[10] memory returnArray;
    
    // Loop through an array containing all election names.
    for (uint i = 0; i < myElectionInfo.length; i++) {
        returnArray[i] = myElectionInfo[i].electionName;
    } // for
    
    // Return the array directly to the caller.
    return (returnArray);        
} // getAllElectionNames

The solution is very simple, just pass results to an event. Add one line of code to define the event, change your function signature and pass return data to the event. This works for me in Ropsten with results sets numbering in the hundreds.

// Event to be called when this contract wants to hand back
// a list of election names.
event GetElectionsEvent(bytes32[10] electionsArray);

// Returns a list of all the elections (by name) in the current
// voting session.
function getAllElectionNames() public {
    // Array to hold return results.
    bytes32[10] memory returnArray;
    
    // Loop through an array containing all election names.
    for (uint i = 0; i < myElectionInfo.length; i++) {
        returnArray[i] = myElectionInfo[i].electionName;
    } // for
    
    // Pass the results array to an event.
    GetElectionsEvent(returnArray);        
} // getAllElectionNames

The pattern I've implemented? A function can only return data directly if the return data is two elements or less, and returning that data involves no state change (a 'view' or 'constant' function).

I'm no expert at any of this, so if there's a better or more elegant way let me know!

Coin Marketplace

STEEM 0.04
TRX 0.32
JST 0.083
BTC 60578.05
ETH 1558.21
USDT 1.00
SBD 0.50