While some protocols require value attached to OP_RETURN outputs, this otherwise seems like a mistake.

Setting the value to 0 should really be done by the wallet/script creating the transaction (like createrawtransaction does for `data` outputs). However, as an additional check, similar to the high-fee check, sendrawtransaction could also check for non-zero value OP_RETURN outputs.

This should be configurable by a new RPC argument.

See also https://transactionfee.info/charts/output-opreturn-amount/

#### Useful skills:

* Bitcoin Core RPC code
* Transaction output types
* Bitcoin Core functional tests

#### Want to work on this issue?

For guidance on contributing, please read [CONTRIBUTING.md](https://github.com/bitcoin/bitcoin/blob/master/CONTRIBUTING.md) before opening your pull request.

{
    for (const auto& cp : vRPCConvertParams) {
        members.emplace(cp.methodName, cp.paramIdx);
        membersByName.emplace(cp.methodName, cp.paramName);
    }
}
static CRPCConvertTable rpcCvtTable;
/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null)
 * as well as objects and arrays.
 */
UniValue ParseNonRFCJSONValue(const std::string& strVal)
{
    UniValue jVal;
    if (!jVal.read(std::string("[")+strVal+std::string("]")) ||
        !jVal.isArray() || jVal.size()!=1)
        throw std::runtime_error(std::string("Error parsing JSON: ") + strVal);
    return jVal[0];
}
UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
{
    UniValue params(UniValue::VARR);
    for (unsigned int idx = 0; idx < strParams.size(); idx++) {
        const std::string& strVal = strParams[idx];
        params.push_back(rpcCvtTable.ArgToUniValue(strVal, strMethod, idx));
    }
    return params;
}
UniValue RPCConvertNamedValues(const std::string &strMethod, const std::vector<std::string> &strParams)