Here is the algorythm without the code:
createrawtransaction
with amount
that you want to send assuming that fees are 0
fundrawtransaction
to let your bitcoind construct final transaction, put your change
address (on where you get change from unspent transaction - very important!) AND to caclulate fees
that will be taken of your account for this transaction.
Substract caclulated fees
from initial amount
Repeat steps 1-2 with new lowered amount.
Profit.
And here is the PHP code.
We will need function to create and fund new transaction
function prepareRawTransaction($amountToSend, $addressToSendTo) {
$bitcoin = new Bitcoin('bitcoinrpc', 'xxx');
$collectedAmount = 0;
$sendToArray = [];
$sendToArray[$addressToSendTo] = $amountToSend;
$unspentTransactions = $bitcoin->listunspent(); //First we find out all our unspent transactions from where we can withdraw
$collectedTransactions = [];
foreach ($unspentTransactions as $unspentTransaction) {
if ($collectedAmount < $amountToSend) {
$collectedTransactions[] = [
'txid' => $unspentTransaction['txid'],
'vout' => $unspentTransaction['vout'],
];
$collectedAmount += $unspentTransaction['amount'];
} else {
break;
}
}
//Now we create raw transactions
$rawTransaction = $bitcoin->createrawtransaction($collectedTransactions, $sendToArray);
//And fund it
$newTransaction = $bitcoin->fundrawtransaction($rawTransaction);
return $newTransaction;
}
Now we can use that function to go on algorythm
$bitcoin = new Bitcoin('bitcoinrpc', 'xxx');
$amountToSend = 0.09999556; //That's exact amount that we want to send INCLUDING commission
$addressToSendTo = '2N8hwP1WmJrFF5QWABn38y63uYLhnJYJYTF';
//createrawtransaction with amount that you want to send assuming that fees are 0
$transactionWithoutCommission = prepareRawTransaction($amountToSend, $addressToSendTo);
$decoded = $bitcoin->decoderawtransaction($transactionWithoutCommission['hex']);
print_r($decoded); //You can see that fees now set up
//Substract caclulated fees from initial amount
$amountToSend = $amountToSend - $transactionWithoutCommission['fee'];
//Repeat steps 1-2 with new lowered amount
$transactionWithCommission = prepareRawTransaction($amountToSend, $addressToSendTo);
$decoded = $bitcoin->decoderawtransaction($transactionWithCommission['hex']);
print_r($decoded); //Here you can see that total amount + commission equal needed amount
$signed = $bitcoin->signrawtransaction($transactionWithCommission['hex']);
print_r($signed); //should say complete:1 if everything was correctly put
$published = $bitcoin->sendrawtransaction($signed['hex']);
print_r($published); //will output you tx id
And profit: you have sent exactly the amount you wanted INCLUDING the commission