| 106 | } |
| 107 | |
| 108 | CMutableTransaction PartiallySignedTransaction::GetUnsignedTx(bool force_unblinded) const |
| 109 | { |
| 110 | if (tx != std::nullopt) { |
| 111 | return *tx; |
| 112 | } |
| 113 | |
| 114 | CMutableTransaction mtx; |
| 115 | mtx.nVersion = *tx_version; |
| 116 | bool locktime_success = ComputeTimeLock(mtx.nLockTime); |
| 117 | assert(locktime_success); |
| 118 | uint32_t max_sequence = CTxIn::SEQUENCE_FINAL; |
| 119 | for (const PSBTInput& input : inputs) { |
| 120 | CTxIn txin; |
| 121 | txin.prevout.hash = input.prev_txid; |
| 122 | txin.prevout.n = *input.prev_out; |
| 123 | txin.nSequence = input.sequence.value_or(max_sequence); |
| 124 | txin.assetIssuance.assetBlindingNonce = input.m_issuance_blinding_nonce; |
| 125 | txin.assetIssuance.assetEntropy = input.m_issuance_asset_entropy; |
| 126 | // If there is a commitment we should set the value to the commitment unless we are forcing unblinded. |
| 127 | // If we are forcing unblinded but there is no value, we just use the commitment. |
| 128 | if (input.m_issuance_value != std::nullopt && (input.m_issuance_value_commitment.IsNull() || force_unblinded)) { |
| 129 | txin.assetIssuance.nAmount.SetToAmount(*input.m_issuance_value); |
| 130 | } |
| 131 | else if(!input.m_issuance_value_commitment.IsNull()) { |
| 132 | txin.assetIssuance.nAmount = input.m_issuance_value_commitment; |
| 133 | } |
| 134 | else { |
| 135 | txin.assetIssuance.nAmount.SetNull(); |
| 136 | } |
| 137 | if (input.m_issuance_inflation_keys_amount != std::nullopt && (input.m_issuance_inflation_keys_commitment.IsNull() || force_unblinded)) { |
| 138 | txin.assetIssuance.nInflationKeys.SetToAmount(*input.m_issuance_inflation_keys_amount); |
| 139 | } |
| 140 | else if(!input.m_issuance_inflation_keys_commitment.IsNull()) { |
| 141 | txin.assetIssuance.nInflationKeys = input.m_issuance_inflation_keys_commitment; |
| 142 | } |
| 143 | else { |
| 144 | txin.assetIssuance.nInflationKeys.SetNull(); |
| 145 | } |
| 146 | mtx.vin.push_back(txin); |
| 147 | } |
| 148 | for (const PSBTOutput& output : outputs) { |
| 149 | CTxOut txout; |
| 150 | CTxOutWitness txoutwit; |
| 151 | txout.scriptPubKey = *output.script; |
| 152 | |
| 153 | bool exp_value = output.m_value_commitment.IsNull() || force_unblinded; |
| 154 | exp_value = exp_value && output.amount != std::nullopt; |
| 155 | if (!output.m_value_commitment.IsNull() && output.amount != std::nullopt) { |
| 156 | exp_value = exp_value && !output.m_blind_value_proof.empty(); |
| 157 | exp_value = exp_value && !output.m_asset_commitment.IsNull(); |
| 158 | exp_value = exp_value && VerifyBlindValueProof(*output.amount, output.m_value_commitment, output.m_blind_value_proof, output.m_asset_commitment); |
| 159 | } |
| 160 | if (exp_value) { |
| 161 | txout.nValue.SetToAmount(*output.amount); |
| 162 | } else { |
| 163 | txout.nValue = output.m_value_commitment; |
| 164 | txoutwit.vchRangeproof = output.m_value_rangeproof; |
| 165 | } |