1

First, I have simple problem. I want to send customer some bitcoins, but I dont want to pay fees for him. I'd like to substruct fees from payment, so all commissions would be payed by customer.

I thought it should be a simple and common problem for all merchants that making refunds to clients. But I googled for hours and could not find any detailed explanation on how to achieve this feature 'receiver-pays-commissions'.

Here some links that I found usefull, but still they dont have exact answer

How to create raw transaction in bitcoind

How to create raw transaction in PHP

How to calculate transaction size and fee

Simply put. I want to send some bitcoins away so that my account balance will be equal exactly 1.8000000. Now it is slightly higher:

enter image description here

Surprisingly this simple and common problem took hours of googling, so I'm making this question just to share solution with public, since I finally found it.

(Or at least I think I've found it, so critics and comments are very welcome.)

3

Here is the algorythm without the code:

  1. createrawtransaction with amount that you want to send assuming that fees are 0

  2. 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.

  3. Substract caclulated fees from initial amount

  4. Repeat steps 1-2 with new lowered amount.

  5. 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

enter image description here

  • What API/lib your using e.g. easybitcoin.php – zhiyan114 Jan 28 '18 at 3:11
  • easybitcoin, yes – Denis Matafonov Jan 28 '18 at 11:26
  • Ok so does the answer below me helps ? – zhiyan114 Jan 28 '18 at 16:51
0

What you can do is use $txid = $bitcoin- >sendtoaddress("User's bitcoIN address here ","amount of btc to send","comment 1","comment 2", true); // echo $txid; what the true is that it makes sure the fees are already included in the amount you want to set (not sure if the lib is glitches and if it is then the true may not work properly)

  • I suggest you try it on the testnet to see if it works – zhiyan114 Jan 28 '18 at 3:26
  • For bitcoin-cli that supports it, you can type bitcoin-cli "address btc" "amount" "comment 1" "comment 2" true – zhiyan114 Jan 28 '18 at 3:32
  • When using sendtoaddress you will pay commission off the primary account. Say if you want to send me 0.01 BTC, your account totally will be credited to 0.01 BTC PLUS commission for the transaction. That's the main problem. – Denis Matafonov Jan 29 '18 at 17:49
  • I think scheme when sender-pays-commission is more common, since you have to be sure that receiver will get the amount that he expects, not less. But scheme receiver-pays-commission is also needed and it wasnt easy to make it up. – Denis Matafonov Jan 29 '18 at 17:51
  • If it refund depend on your choice – zhiyan114 Jan 29 '18 at 18:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.