Hey @pynchmeister, I’m Martin, researcher @ Zeppelin.
I’ve run some super quick tests both in Remix and locally, with Truffle 5 and solc 0.5, and everything seems to run ok, so at first sight using that experimental feature should work fine. Bear in mind that this is the first time I actually use it, so I’m not that familiar with it.
Nevertheless, agreeing with everything @frangio said above, the feature is still labeled as experimental. A keyword saying “experimental”, along with a compiler warning, should be enough red flags to avoid deploying to mainnet using the ABIEncoderV2 feature until it’s more battle-tested both from functional and security standpoints.
You can find open issues regarding this feature in Solidity’s Github repo (https://github.com/ethereum/solidity/search?q=ABIEncoderV2&state=open&type=Issues). According to issue#4700, end-to-end testing with this feature enabled hasn’t been accomplished yet (though they seem to be pretty close according to the related PR https://github.com/ethereum/solidity/pull/5102). I haven’t found issues related to security vulnerabilities though, which does not mean that there aren’t any.
It’s hard to think of workarounds without further context. From the top of my head (probably you’ve already thought of these):
- If strings are short enough, just return an array of statically-sized arrays (i.e
bytes32 instead of
string) and throw away the
pragma experimental ABIEncoderV2. When calling that function and reading the returned values, it would be just a matter of calling
web3.utils.hexToUtf8 to get a readable form of the string.
- If strings are longer than 32 bytes (which I think should be your case), a more cumbersome approach would be to build an array of hashes for each string, thus just returning the hashes in a
bytes32 array. To save the corresponding original string for each hash, you could emit an event such as
MyEvent(bytes32 indexed hash, string originalString). This way, you can log both the original and hashed string, and then you’d just need to search through the logs to obtain the original text for a given hash.
- Lastly, a far simpler approach would be to remove the
string return values from your function and have one separate getter that returns each element of the
string arrays (no idea if that’s somehow in storage or how it’s built) and do subsequent calls to the getter to rebuild the whole array outside the contract.