Bitcoin Forum
November 18, 2024, 08:05:22 PM *
News: Check out the artwork 1Dq created to commemorate this forum's 15th anniversary
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: bumpfee for transaction with specified changePosition  (Read 217 times)
SacWheeler (OP)
Newbie
*
Offline Offline

Activity: 13
Merit: 16


View Profile
July 06, 2021, 02:31:29 PM
Merited by LoyceV (4), ABCbits (2), BlackHatCoiner (1)
 #1

Hi

To create a transaction with multiple outputs, I am using the command decoderawtransaction and fundrawtransaction with {changePosition} to have my change address as the last output in the list (this is important).

The transaction above is created as RBF. If I use the bumpfee command, the changeaddress gets randomly set in the output list.
How can I bump the fee of such a transaction and ensure the change position is still the last output of the transaction. Or is there a bumpfee command where I can specify the changePosition as in fundrawtransaction?

Running MacOs 11.4 and BitcoinCore 0.21.1
nc50lc
Legendary
*
Offline Offline

Activity: 2604
Merit: 6424


Self-proclaimed Genius


View Profile
July 08, 2021, 02:45:40 AM
Merited by ABCbits (2), hosseinimr93 (1), SacWheeler (1)
 #2

Based from this documentation, bumpfee doesn't have such option: https://bitcoincore.org/en/doc/0.21.0/rpc/wallet/bumpfee/

The only option I know is by using "createrawtransaction" and "decoderawtransaction" to make a replacement for the txn with rbf.
The outputs' positions will follow the arrangement of the outputs array, so include your wallet's own address as the last.

The trick is to spend the one/all input(s) of the to-be-replaced transaction,
you can get it by decoding the to-be-replaced transaction and check the inputs' txid and vout, you may as well need to check the amount of the particular output(s) from that txid(s).
Then use createrawtransaction using that/those as the input(s).

Note: make sure to double-check the the amounts because the excess will be used as fee.

-snip- to have my change address as the last output in the list (this is important).
I can't see why is this important.

I don't know if you have other options.

█▀▀▀











█▄▄▄
▀▀▀▀▀▀▀▀▀▀▀
e
▄▄▄▄▄▄▄▄▄▄▄
█████████████
████████████▄███
██▐███████▄█████▀
█████████▄████▀
███▐████▄███▀
████▐██████▀
█████▀█████
███████████▄
████████████▄
██▄█████▀█████▄
▄█████████▀█████▀
███████████▀██▀
████▀█████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
c.h.
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▀▀▀█











▄▄▄█
▄██████▄▄▄
█████████████▄▄
███████████████
███████████████
███████████████
███████████████
███░░█████████
███▌▐█████████
█████████████
███████████▀
██████████▀
████████▀
▀██▀▀
HCP
Legendary
*
Offline Offline

Activity: 2086
Merit: 4361

<insert witty quote here>


View Profile
July 08, 2021, 03:53:51 AM
 #3

To create a transaction with multiple outputs, I am using the command decoderawtransaction and fundrawtransaction with {changePosition} to have my change address as the last output in the list (this is important).
Can I ask why? I'm Curious to know why the ordering of outputs is important. Is it to simplify the process of identifying the change output and amount for some reason? Huh

█████████████████████████
████▐██▄█████████████████
████▐██████▄▄▄███████████
████▐████▄█████▄▄████████
████▐█████▀▀▀▀▀███▄██████
████▐███▀████████████████
████▐█████████▄█████▌████
████▐██▌█████▀██████▌████
████▐██████████▀████▌████
█████▀███▄█████▄███▀█████
███████▀█████████▀███████
██████████▀███▀██████████
█████████████████████████
.
BC.GAME
▄▄░░░▄▀▀▄████████
▄▄▄
██████████████
█████░░▄▄▄▄████████
▄▄▄▄▄▄▄▄▄██▄██████▄▄▄▄████
▄███▄█▄▄██████████▄████▄████
███████████████████████████▀███
▀████▄██▄██▄░░░░▄████████████
▀▀▀█████▄▄▄███████████▀██
███████████████████▀██
███████████████████▄██
▄███████████████████▄██
█████████████████████▀██
██████████████████████▄
.
..CASINO....SPORTS....RACING..
█░░░░░░█░░░░░░█
▀███▀░░▀███▀░░▀███▀
▀░▀░░░░▀░▀░░░░▀░▀
░░░░░░░░░░░░
▀██████████
░░░░░███░░░░
░░█░░░███▄█░░░
░░██▌░░███░▀░░██▌
░█░██░░███░░░█░██
░█▀▀▀█▌░███░░█▀▀▀█▌
▄█▄░░░██▄███▄█▄░░▄██▄
▄███▄
░░░░▀██▄▀


▄▄████▄▄
▄███▀▀███▄
██████████
▀███▄░▄██▀
▄▄████▄▄░▀█▀▄██▀▄▄████▄▄
▄███▀▀▀████▄▄██▀▄███▀▀███▄
███████▄▄▀▀████▄▄▀▀███████
▀███▄▄███▀░░░▀▀████▄▄▄███▀
▀▀████▀▀████████▀▀████▀▀
SacWheeler (OP)
Newbie
*
Offline Offline

Activity: 13
Merit: 16


View Profile
July 08, 2021, 02:34:20 PM
Last edit: July 08, 2021, 07:22:56 PM by SacWheeler
 #4

To have the change address as the last output is essential because I try to embed some information in a transaction.
The recipient of this transaction can only correctly verify the embedded data if the change address is defined as the last output. Otherwise, the embedded data gets mixed with my change address, and information would be invalid to the recipient.

So, I get a hex string of a rawtransaction (with the embedded information) which I input into a script.
The script handles the "fundrawtransaction", "signrawtransactionwithwallet" and "sendrawtransaction" command.

The goal is that the script automatically bumps the fee of this transaction (e.g., no confirmation over a certain period of time).

I guess it is the right start to use "decoderawtransaction" on my RBF-transaction and recreate it with same input(s) and outputs with "createrawtransaction", as described by @nc50lc.

I never used "creatrawtransaction" before. looks quite complex https://bitcoincore.org/en/doc/0.21.0/rpc/rawtransactions/createrawtransaction/
Not sure yet which information from "decoderawtransaction" I have to input in "creatrawtransaction".
Also, it is not possible to specify a feerate. To bump the fee of my RBF-transaction, I would have to deduct a certain amount from the output to the change address in the process of createrawtransaction" command. Do I get that right?

Not sure yet how to do all these things, but I will study and try it.
HCP
Legendary
*
Offline Offline

Activity: 2086
Merit: 4361

<insert witty quote here>


View Profile
July 08, 2021, 11:56:00 PM
 #5

Correct, you don't specify a feerate using createrawtransaction... the fee is simply the difference between the sum(inputs) and the sum(outputs).

Given that you already have the original raw transaction, and all you're modifying is the value of the change output to conduct an RBF... it should be relatively easy to calculate a given feerate and how much you need to deduct from the change output.

For instance if this was your transaction (I just picked one randomly from unconfirmed transactions, so ignore the fact that it is NOT RBF enabled Tongue):
Code:
getrawtransaction 2c7a86754ea57332533cc0ff8ede520741d9c1028eef9c18ff40b728787f20d9

Code:
02000000000101af29796f82f33b6d04ab2520792bc2f0d67f8b18bd6dd07f007ecc992c23c2e50100000000ffffffff0202ab0400000000001976a914b16dbec6ffec390fc2211b83cc099d2e6897797d88acc224b40000000000160014d9baa78f2412c4a2fa054fa7729bb8da5426564702483045022100fd4a8dbc192a0ba598944e9011fb75e39ebc0b7bd95df3d74b9e51c97bad25e60220787eae71498aa5d8869fc0b9f4f90492402540b793431029fab39d7d5ade25870121023b2567028b6a81e157bf9e3ed084697f9d9c64d27b5a63b1446e1c2d066d050d00000000

Code:
decoderawtransaction 02000000000101af29796f82f33b6d04ab2520792bc2f0d67f8b18bd6dd07f007ecc992c23c2e50100000000ffffffff0202ab0400000000001976a914b16dbec6ffec390fc2211b83cc099d2e6897797d88acc224b40000000000160014d9baa78f2412c4a2fa054fa7729bb8da5426564702483045022100fd4a8dbc192a0ba598944e9011fb75e39ebc0b7bd95df3d74b9e51c97bad25e60220787eae71498aa5d8869fc0b9f4f90492402540b793431029fab39d7d5ade25870121023b2567028b6a81e157bf9e3ed084697f9d9c64d27b5a63b1446e1c2d066d050d00000000

Code:
{
  "txid": "2c7a86754ea57332533cc0ff8ede520741d9c1028eef9c18ff40b728787f20d9",
  "hash": "b579d058ec32a1b7ca9d25f42099eea173e9340ced1357bac882309fd76ddb34",
  "version": 2,
  "size": 226,
  "vsize": 144,
  "weight": 574,
  "locktime": 0,
  "vin": [
    {
      "txid": "e5c2232c99cc7e007fd06dbd188b7fd6f0c22b792025ab046d3bf3826f7929af",
      "vout": 1,
      "scriptSig": {
        "asm": "",
        "hex": ""
      },
      "txinwitness": [
        "3045022100fd4a8dbc192a0ba598944e9011fb75e39ebc0b7bd95df3d74b9e51c97bad25e60220787eae71498aa5d8869fc0b9f4f90492402540b793431029fab39d7d5ade258701",
        "023b2567028b6a81e157bf9e3ed084697f9d9c64d27b5a63b1446e1c2d066d050d"
      ],
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 0.00305922,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 b16dbec6ffec390fc2211b83cc099d2e6897797d OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a914b16dbec6ffec390fc2211b83cc099d2e6897797d88ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "1HBA5Bn828KvTtuePBbj7iZVMcSerLkCoK"
        ]
      }
    },
    {
      "value": 0.11805890,
      "n": 1,
      "scriptPubKey": {
        "asm": "0 d9baa78f2412c4a2fa054fa7729bb8da54265647",
        "hex": "0014d9baa78f2412c4a2fa054fa7729bb8da54265647",
        "reqSigs": 1,
        "type": "witness_v0_keyhash",
        "addresses": [
          "bc1qmxa20reyztz297s9f7nh9xacmf2zv4j8090qj7"
        ]
      }
    }
  ]
}

Total Input = 0.12112148
Total Output = 0.00305922 + 0.11805890

Total fee = 336 sats

As you can see... the vsize is show as 144... so the fee rate of the current transaction was 336/144 = 2.3 sats/vbyte.


To work out how much the total fee (in sats) that you need to pay to achieve a desired fee rate (for your RBF attempt), you multiply the vsize by your desired feerate in sat/vbytes.

So, if you wanted to bump to say 6 sats/vbyte... it would be 6 * 144 = 864 sats. As things currently stand, the total fee is already 336, so we need to spend a further 864 - 336 = 528 sats to achieve our desired fee rate.

This means you would simply recreate the transaction with the same inputs/outputs... but modify the change value so that instead of 0.11805890, you'd use 0.11805362 (0.11805890 - 0.00000528) as the change amount.

This would mean the total fee paid would be 864 sats... and that should result in a fee rate of 6 sats/vbyte.


Obviously, the complicating factor in all this is that the input amounts are not included in the decoded transaction, so you'd need to look those UTXOs up individually to find the value so that you can do the maths. But that's relatively easy using gettxout... note that you'll need to set the "include_mempool" option to false, otherwise it will return null as the UTXO has been "spent" by the transaction that is already in the mempool.

for instance:
Code:
gettxout e5c2232c99cc7e007fd06dbd188b7fd6f0c22b792025ab046d3bf3826f7929af 1 false

█████████████████████████
████▐██▄█████████████████
████▐██████▄▄▄███████████
████▐████▄█████▄▄████████
████▐█████▀▀▀▀▀███▄██████
████▐███▀████████████████
████▐█████████▄█████▌████
████▐██▌█████▀██████▌████
████▐██████████▀████▌████
█████▀███▄█████▄███▀█████
███████▀█████████▀███████
██████████▀███▀██████████
█████████████████████████
.
BC.GAME
▄▄░░░▄▀▀▄████████
▄▄▄
██████████████
█████░░▄▄▄▄████████
▄▄▄▄▄▄▄▄▄██▄██████▄▄▄▄████
▄███▄█▄▄██████████▄████▄████
███████████████████████████▀███
▀████▄██▄██▄░░░░▄████████████
▀▀▀█████▄▄▄███████████▀██
███████████████████▀██
███████████████████▄██
▄███████████████████▄██
█████████████████████▀██
██████████████████████▄
.
..CASINO....SPORTS....RACING..
█░░░░░░█░░░░░░█
▀███▀░░▀███▀░░▀███▀
▀░▀░░░░▀░▀░░░░▀░▀
░░░░░░░░░░░░
▀██████████
░░░░░███░░░░
░░█░░░███▄█░░░
░░██▌░░███░▀░░██▌
░█░██░░███░░░█░██
░█▀▀▀█▌░███░░█▀▀▀█▌
▄█▄░░░██▄███▄█▄░░▄██▄
▄███▄
░░░░▀██▄▀


▄▄████▄▄
▄███▀▀███▄
██████████
▀███▄░▄██▀
▄▄████▄▄░▀█▀▄██▀▄▄████▄▄
▄███▀▀▀████▄▄██▀▄███▀▀███▄
███████▄▄▀▀████▄▄▀▀███████
▀███▄▄███▀░░░▀▀████▄▄▄███▀
▀▀████▀▀████████▀▀████▀▀
nc50lc
Legendary
*
Offline Offline

Activity: 2604
Merit: 6424


Self-proclaimed Genius


View Profile
July 09, 2021, 02:56:26 AM
Merited by ABCbits (3), HCP (2), hosseinimr93 (1)
 #6

I never used "creatrawtransaction" before. looks quite complex https://bitcoincore.org/en/doc/0.21.0/rpc/rawtransactions/createrawtransaction/
-snip-
Also, it is not possible to specify a feerate. To bump the fee of my RBF-transaction, I would have to deduct a certain amount from the output to the change address in the process of createrawtransaction" command. Do I get that right?
Yeah, it's not a wallet RPC so everything that should be inputted is manual.

I forgot to tell you about "getrawtransaction" to get the raw transaction and suggested "decoderawtransaction" right away;
As instructed by HCP, you need to use "getrawtransaction", but instead of using the two commands,
you can just add the optional "true" or "1" flag to get the result decoded.

Try it on HCP's example transaction:
Code:
getrawtransaction 2c7a86754ea57332533cc0ff8ede520741d9c1028eef9c18ff40b728787f20d9 true

Quote from: SacWheeler
Not sure yet which information from "decoderawtransaction" I have to input in "creatrawtransaction".
From the result, you need to take note of the things I've mentioned in my previous post.
Inside the inputs ("vin": under "locktime":): The "txid" and the "output index" under it ("vout":); there may be more than one input.

Sample to-be-replaced txn (with three inputs):
{
  "txid": "1b953d716cade46990479251b33b078bf4ed7331750a0921da4ffa3cc766a7d5",
  "hash": "04c5071e1eb4e11014d5932858f5c8ec79b43233fd09775021b337cea5d688eb",
  "version": 2,
  "size": 518,
  "vsize": 435,
  "weight": 1739,
  "locktime": 0,
 "vin": [
    {
     "txid": "0663168bf247f75b8907179f4ee6d7bf92874f2619933587fc97dc066f74659a",
      "vout": 1,

      "scriptSig": {
        "asm": "",
        "hex": ""
      },
      "txinwitness": [
        "304402206628679c970c5d66bb3d3c9cc8998a98887....."
      ],
      "sequence": 4294967293
    },
    {
     "txid": "97e38ad0eff0977de905febc508c0c5cb722dcfb172435f6092a822dd529dd4a",
      "vout": 0,

      "scriptSig": {
        "asm": "304402205caec4d3f4b4b34343b4ca4269035f.....",
        "hex": "47304402205caec4d3f4b4b34343b4ca426903....."
      },
      "sequence": 4294967293
    },
    {
     "txid": "d1bcbfdd3769b7cdb8b1ed1147f743cf8525b38f425564e72c2612ac3f3ae5b6",
      "vout": 0,

      "scriptSig": {
        "asm": "304402203ba35046f9779385bc20fcd384572d......",
        "hex": "47304402203ba35046f9779385bc20fcd384572....."
      },
      "sequence": 4294967293
    }
 ],
  "vout": [
    {
      "value": 0.08100000,
      "n": 0,
      "scriptPubKey": {
        "asm": "0 993b422c3f321f8abc317ebc260f2bb67891039d",
        "hex": "0014993b422c3f321f8abc317ebc260f2bb67891039d",
        "reqSigs": 1,
        "type": "witness_v0_keyhash",
        "addresses": [
          "bcrt1qnya5ytplxg0c40p3067zvretkeufzquafczmsr"
        ]
      }
    },
    {
      "value": 0.00002143,
      "n": 1,
      "scriptPubKey": {
        "asm": "0 403c394137dcddecbfb76707fb1ebefd65b87d03",
        "hex": "0014403c394137dcddecbfb76707fb1ebefd65b87d03",
        "reqSigs": 1,
        "type": "witness_v0_keyhash",
        "addresses": [
          "bcrt1qgq7rjsfhmnw7e0ahvurlk847l4jmslgr93pdad"
        ]
      }
    }
  ]
}


If you want to completely re-create the txn, just use all the inputs and copy the outputs but reduce the amount of the change by a value enough to cover the additional fee for the replacement txn.
Getting the inputs' amounts is necessary if you'll not use all of them for the replacement txn.

█▀▀▀











█▄▄▄
▀▀▀▀▀▀▀▀▀▀▀
e
▄▄▄▄▄▄▄▄▄▄▄
█████████████
████████████▄███
██▐███████▄█████▀
█████████▄████▀
███▐████▄███▀
████▐██████▀
█████▀█████
███████████▄
████████████▄
██▄█████▀█████▄
▄█████████▀█████▀
███████████▀██▀
████▀█████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
c.h.
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▀▀▀█











▄▄▄█
▄██████▄▄▄
█████████████▄▄
███████████████
███████████████
███████████████
███████████████
███░░█████████
███▌▐█████████
█████████████
███████████▀
██████████▀
████████▀
▀██▀▀
SacWheeler (OP)
Newbie
*
Offline Offline

Activity: 13
Merit: 16


View Profile
August 05, 2021, 10:25:39 AM
Last edit: August 15, 2021, 09:21:09 PM by SacWheeler
 #7

Hi

I am still working (debugging) my python script to recreate my RBF tx to bump the fee.
But I am running into an error with "createrawtransaction".

Error: "-1: JSON value is not a string as expected"

I am using
Code:
createrawtransaction(inputs, outputs, 0, True)
inputs: [
    {
         'tixid': 'c1636efe3d85e3bb7e58663cfa976590ed1a9bb6740e7b851cbb34ab63f52ab9',
         'vout': 2,
         'sequence': 4294967293
    }
]

outputs: [
    {
        'bc1q5q5e95h3z0eymfwasm2whx2jrztqa8sy012345': 0.012345
    },
    {
        'bc1q2gphxxpm7aetec0m7jpd04e342c5hree543210': 0.054321
    }
]

I tried the output value as str() instead of float(). Stille get the error.

What am I missing??
As far as I can tell, my json array is formated as described by https://bitcoincore.org/en/doc/0.21.0/rpc/rawtransactions/createrawtransaction/


*Edit:
is e.g. 'txid' causing the error and should it be "txid"?
running MacOs 11.4 and python 3.9.4

*Edit2:
Could solve the problem. error comes from wrong key value in the input array. I got a typing error: "tixid" instead of "txid"
SacWheeler (OP)
Newbie
*
Offline Offline

Activity: 13
Merit: 16


View Profile
August 05, 2021, 10:41:24 AM
 #8

also.... if I want to recreate a transaction with an op_return output, for example:
[ ...
      {
        "value": 0.00000000,
        "n": 1,
        "scriptPubKey": {
          "asm": "OP_RETURN 44464177010000aaee2c45de4d1b5ca89e1868f0367e3e729fa9d3d735547b72e863bf12cd7dea9 848100026c7b4f347444fe39a465185ebe714f80e4902501cd2c49f58a2ad89c397ab1234567890 a1",
          "hex": "6a4c5044464177010000aaee2c45de4d1b5ca89e1868f0367e3e729fa9d3d735547b72e863bf12c d7dea9848100026c7b4f347444fe39a465185ebe714f80e4902501cd2c49f58a2ad89c397ab1234 567890a1",
          "type": "nulldata"
        },
    ...
]

As described by https://bitcoincore.org/en/doc/0.21.0/rpc/rawtransactions/createrawtransaction/
the key:value pair is =  "data": "hex"

so for the example above: {["scriptPubKey"]["asm"]: ["scriptPubKey"]["hex"]}
I will then insert this in an jason array with other outputs to then use in:
createrawtransaction(inputs, outputs, 0, True)

is this correct to recreate a transaction with op_return ("nulldata") output?
nc50lc
Legendary
*
Offline Offline

Activity: 2604
Merit: 6424


Self-proclaimed Genius


View Profile
August 05, 2021, 02:33:30 PM
Merited by ABCbits (2), SacWheeler (2)
 #9

is this correct to recreate a transaction with op_return ("nulldata") output?
You'll have to include it as a separate output.

Get the hex-encoded data after "OP_RETURN", and use that as a value for "data".
eg.:
Code:
"[{output1},{\"data\": \"44464177010000aaee2c45de4d1b5ca89e1868f0367e3e729fa9d3d735547b72e863bf12cd7dea9848100026c7b4f347444fe39a465185ebe714f80e4902501cd2c49f58a2ad89c397ab1234567890a1\"},{output2}]"

Here's a reference with OP_Return: https://developer.bitcoin.org/reference/rpc/createrawtransaction.html

█▀▀▀











█▄▄▄
▀▀▀▀▀▀▀▀▀▀▀
e
▄▄▄▄▄▄▄▄▄▄▄
█████████████
████████████▄███
██▐███████▄█████▀
█████████▄████▀
███▐████▄███▀
████▐██████▀
█████▀█████
███████████▄
████████████▄
██▄█████▀█████▄
▄█████████▀█████▀
███████████▀██▀
████▀█████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
c.h.
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▀▀▀█











▄▄▄█
▄██████▄▄▄
█████████████▄▄
███████████████
███████████████
███████████████
███████████████
███░░█████████
███▌▐█████████
█████████████
███████████▀
██████████▀
████████▀
▀██▀▀
SacWheeler (OP)
Newbie
*
Offline Offline

Activity: 13
Merit: 16


View Profile
August 08, 2021, 01:24:14 PM
 #10

Thx again @nc50lc for your help and clarification.

Does anyone have an idea for a solution to the problem/error I am running in to with the JSON array (described in reply #7) ?
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!