| 3127 | } |
| 3128 | |
| 3129 | static RPCHelpMan rawreissueasset() |
| 3130 | { |
| 3131 | return RPCHelpMan{"rawreissueasset", |
| 3132 | "\nRe-issue an asset by attaching pseudo-inputs to transaction inputs, revealing the underlying reissuance token of the input. Returns the transaction hex.\n", |
| 3133 | { |
| 3134 | {"transaction", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Transaction in hex in which to include an issuance input."}, |
| 3135 | {"reissuances", RPCArg::Type::ARR, RPCArg::Optional::NO, "List of re-issuances to create. Each issuance must have one non-zero amount.", |
| 3136 | { |
| 3137 | {"", RPCArg::Type::OBJ, RPCArg::Optional::NO, "", |
| 3138 | { |
| 3139 | {"asset_amount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "Amount of asset to generate, if any."}, |
| 3140 | {"asset_address", RPCArg::Type::STR, RPCArg::Optional::NO, "Destination address of generated asset. Required if `asset_amount` given."}, |
| 3141 | {"input_index", RPCArg::Type::NUM, RPCArg::Optional::NO, "The input position of the reissuance in the transaction."}, |
| 3142 | {"asset_blinder", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The blinding factor of the reissuance token output being spent."}, |
| 3143 | {"entropy", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The `entropy` returned during initial issuance for the asset being reissued."}, |
| 3144 | } |
| 3145 | } |
| 3146 | } |
| 3147 | }, |
| 3148 | }, |
| 3149 | RPCResult{ |
| 3150 | RPCResult::Type::OBJ, "", "", |
| 3151 | { |
| 3152 | {RPCResult::Type::STR_HEX, "hex", "The transaction with reissuances appended"}, |
| 3153 | }, |
| 3154 | }, |
| 3155 | RPCExamples{""}, |
| 3156 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 3157 | { |
| 3158 | CMutableTransaction mtx; |
| 3159 | |
| 3160 | if (!DecodeHexTx(mtx, request.params[0].get_str())) |
| 3161 | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); |
| 3162 | |
| 3163 | if (mtx.vout.empty()) { |
| 3164 | throw JSONRPCError(RPC_INVALID_PARAMETER, "Transaction must have at least one output."); |
| 3165 | } |
| 3166 | |
| 3167 | // Validate fee output location, required by the implementation of reissueasset_base |
| 3168 | if (!mtx.vout[mtx.vout.size() - 1].IsFee()) { |
| 3169 | throw JSONRPCError(RPC_INVALID_PARAMETER, "Last transaction output must be fee."); |
| 3170 | } |
| 3171 | for (size_t i = 0; i < mtx.vout.size() - 1; i++) { |
| 3172 | if (mtx.vout[i].IsFee()) { |
| 3173 | throw JSONRPCError(RPC_INVALID_PARAMETER, "Transaction can only have one fee output."); |
| 3174 | } |
| 3175 | } |
| 3176 | |
| 3177 | UniValue issuances = request.params[1].get_array(); |
| 3178 | |
| 3179 | for (unsigned int idx = 0; idx < issuances.size(); idx++) { |
| 3180 | const UniValue& issuance = issuances[idx]; |
| 3181 | const UniValue& issuance_o = issuance.get_obj(); |
| 3182 | |
| 3183 | CAmount asset_amount = 0; |
| 3184 | const UniValue& asset_amount_uni = issuance_o["asset_amount"]; |
| 3185 | if (asset_amount_uni.isNum()) { |
| 3186 | asset_amount = AmountFromValue(asset_amount_uni, false); |
nothing calls this directly
no test coverage detected