So I'm in the process of implementing a BTC-based payment module where for every transaction to a non-wallet account a fraction of the amount will end up to a charity account in a external wallet not controlled by this module.
A typical round for that would be:
- The module receives the payment from user
- It forwards the 90% (this percentage is arbitary) of the amount to its final destination (e.g. a merchant)
- It now has to forward the remaining 10% to the charity of the user's choice
In a lower level, the system:
- Receives a transaction
TxFromUser
from the user with an amount ofX
BTC - Waits until it gets 6 confirmations
- Creates a new raw transaction,
TxToMerchant
to forward the payment to the merchant - Creates another raw transaction
TxToCharity
to forward the donation to the charity
Going a bit deeper:
TxToMerchant:
- Create new raw transaction
- Add new input:
TxFromUser
- Add new output: Address:
Merchant's address
, Amount: 0.9 * TxFromUser.Amount - Add new output: Address:
Module's own wallet address
, Amount: 0.1 * TxFromUser.Amount - Calculate the fee for this transaction
- Subtract the fee from the second output's amount
- Create the transaction's hex and sign it with the right key
- Send the transaction and get its id:
TxToMerchant.Id
TxToCharity:
- Wait for the above transaction (TxToMerchant) to get confirmed
- Create a new raw transaction
- Add new input:
TxToMerchant
(this will be the change we asked for above) - Add new output: Address:
Charity's address
, Amount: TxToMerchant.Amount = 0.1 * TxFromUser.Amount - Calculate the fee for this transaction
- Subtract the fee from transaction's output amount
- Create the transaction's hex and sign it with the right key
- Send the transaction and get its id:
TxToCharity.Id
I am aware of the fact that I could merge these two transactions (TxToMerchant and TxToCharity) into a single transaction, however for various reasons (business requirement) let's just say that this is not possible at the moment.
The issue I have with the above implementation is this: waiting for the TxToMerchant
to confirm creates a lag, as I cannot forward the payment to the charity TxToCharity
until TxToMerchant
is confirmed (or can I, without having to worry about transaction malleability etc?).
On top of that, when the time comes to add the TxToCharity
's input I have to keep track of how the change was returned in TxToMerchant
and then get the right unspent transaction (where listunspent.txid = TxToMerchant.Id), is there a more efficient and less error-prone way to do this?
Let's suppose that the user wants to split the payment between 2 merchants (or a merchant and a freight service, which makes more sense), so in the above example there would be 1 more transaction like TxToMerchant
, let's call it TxToFreightService
. Let's say now that TxToMerchant
goes trough well and gets confirmed but TxToFreightService
fails and never gets confirmed because the input used for it was a double-spend regardless the 6 confirmations we got (for its input) before processing it. TxToCharity
depends on TxToFreightService
because the requested change in TxToFreightService
will serve as the input to TxToCharity
. How do I deal with this scenario programmatically without having to perform corrections by hand every single time this happens?