5

When I call a solidity function to get a struct element, is it a best practice to use require and check if the element exists or should I just return the empty values?

Without require:

function getStruct(uint256 _id) returns (address, bool) {
  return (structs[_id].addr, structs[_id].boolean);
}

With require:

function getStruct(uint256 _id) returns (address, bool) {
  require(structElementExists(_id));
  return (structs[_id].addr, structs[_id].boolean);
}

Should view functions fail or should they just return empty results?

0

3 Answers 3

3

It is as a matter of style and context.

It is not possible to maintain the confidentiality of information stored in the contract, so as an access-control mechanism, it is pointless.

In my opinion, it is often useful to differentiate between a valid request and an invalid request. As in your example, require(exists()) is a good guard to prevent returning a non-existent instance of something. There are cases where you want to return a default, empty instance, and there are cases where there is no good reason why it should occur.

In cases where it's used, it's a good idea to expose the exists() function so a client can inspect it before invoking a strict function. That way, there really is no good reason why a client would go out of bounds.

function exists(bytes32 key) public view returns(bool doesIndeed) {
  return <expression>;
}

function get(bytes32 key) public {
  require(exists(key),"Can't do that. It doesn't exist");
  return ...
}

A client has some options.

if(!exists(key)) createIt(key);
// carry on

TL;DR; It depends on the context.

Hope it helps.

2

The answer to your question is generally subjected to opinion; here is mine:

If structs is public then the require statement is pointless, since users will be able to retrieve an "empty" value by calling the implicit getter-function generated by the compiler, i.e., function structs(uint256).

In fact, since the block-chain itself is public, users will be able to retrieve an "empty" value also when structs is not public, with the only difference being that they will have to "work a little harder" on their off-chain code in order to achieve that.

So my general opinion is that it is pointless to add require statements to a constant function which is designated only for off-chain users.

That said, if you designate this function also for on-chain users (i.e., if you intend for it to be called from other contracts), then it might actually be useful to have it "requiring" certain conditions (if such conditions are applicable of course), otherwise any on-chain user calling this function will have to apply these conditions on the returned value every time the function is called.

1

This depends on whether non-existing key is a valid input for your getter or not. Basically this is not a technical but rather religious question. Fail-fast adepts would put require to make sure caller will never treat empty returned values are a valid structure.

Though, in case live structure may never contain empty values in all fields, returning empty values may be a good way to signal that key does not exists. Also, such signal is easier to handle from within other smart contracts, because Solidity still lacks try ... catch.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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