Bitcoin Forum
October 20, 2026, 12:52:10 PM *
News: Latest Bitcoin Core release: 31.1 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Looking for proof OP_RETURN isn't part of witness data  (Read 138 times)
ABCbits (OP)
Legendary
*
Offline

Activity: 3766
Merit: 10443



View Profile
October 17, 2026, 10:08:06 AM
Merited by DireWolfM14 (1), stwenhao (1), athanred (1)
 #1

I'm looking for proof(s) which prove or disprove OP_RETURN isn't part or categorized as witness data (which imply OP_RETURN doesn't benefit from witness discount). The proof can be from either Bitcoin Core source code, relevant BIP or any credible source.

P.S. I know how to use AI, chatbot and AI agent to analyze source code. Do not copy-paste AI answer, unless you've verified it.

athanred
Full Member
***
Offline

Activity: 203
Merit: 382


View Profile
October 17, 2026, 11:49:19 AM
Last edit: October 17, 2026, 01:04:03 PM by athanred
Merited by ABCbits (5), vapourminer (4), pooya87 (3), DireWolfM14 (1)
 #2

Here you are: https://github.com/bitcoin/bitcoin/pull/2738

It existed before Segwit, since 2013, so it is not a part of witness data.

Another way to see it, is to run any pre-Segwit node, and check, if it can recognize OP_RETURN or not. Because these nodes never store any witness data at all.

Edit: Another example: a non-Segwit transaction, which used OP_RETURN: https://mempool.space/tx/6dfb16dd580698242bcfd8e433d557ed8c642272a368894de27292a8844a4e75

It happened in 2014, before Segwit, so there is no witness discount of any kind, and OP_RETURN is still there.
pooya87
Legendary
*
Offline

Activity: 4256
Merit: 12671



View Profile
October 17, 2026, 05:54:47 PM
Merited by ABCbits (5), vapourminer (1), nc50lc (1), stwenhao (1), athanred (1)
 #3

OP_RETURN is an OP code and OP codes aren't part of anything, they can exist anywhere even in a witness stack (last I checked it could exist in an unexecuted OP_IF branch). So if you put it there, it can be part of the witness data.

But I guess what you meant to ask was an OP_RETURN output which are provably unspendable and people use to insert a messages into the chain; in which case the question answers itself (the proof is in the question itself)! An "output" is not part of the witness data. It is an output so its size is calculated like before without the "witness discount".
Witness data is part of the input, the scripts or rather the stack items that were part of the signature (scriptsig) are placed in the witness.

▄▄████████████████████▄▄
▄███████▀▀██████▀▀███████▄
█████▀██████████████▀█████
████████▄▄██████▄▄████▀███

██████████████████████████
██▄▄██████████████▄▄██████
██▀▀██████████████████▄▄██
██████▀▀██████████████▀▀██
██████████████████████████
███▄████▀▀██████▀▀████████
█████▄██████████████▄█████
▀███████▄▄██████▄▄███████▀
▀▀████████████████████▀▀
 
 DΞX.fo 
▄▄██████
█████████
██████████
██████████
██████████
█████████
▀▀██████

▄███████
▄██████████
████████████
█████████████
█████████████
|
▄▄█
▄████▀
▄███▀█▄
▄██▀█▄██
█████▀▀█
████████
████████
▀██▄████
▄████▄▄█
▄█████▀███
▄█████▀████▀
█████▀███████
▀██▀█████████
|..BTC......XMR...
..USDT.....LTC...
....Fees  0.8%.....
athanred
Full Member
***
Offline

Activity: 203
Merit: 382


View Profile
October 17, 2026, 07:57:16 PM
Merited by pooya87 (5), ABCbits (2)
 #4

Quote
last I checked it could exist in an unexecuted OP_IF branch
Challenge accepted, OP_RETURN in witness, behind some unexecuted OP_IF: https://mempool.space/signet/tx/2e393804096c2d1efd0b0f43230b2ec307182fb2456da83845bfdeebf6b66f3f

However, in this case, OP_RETURN can be entirely skipped, and any user of this scheme can save one byte by actually not using OP_RETURN at all.
Danish Ali
Member
**
Offline

Activity: 98
Merit: 177


View Profile
October 17, 2026, 08:15:51 PM
Merited by ABCbits (1)
 #5

The proof is in Bitcoin Core's transaction serialization code and BIP141.

In src/primitives/transaction.h, CTxOut contains nValue and scriptPubKey. The serialization code shows that transaction outputs and witness stacks are serialized separately:

Code:
s << tx.vin;
s << tx.vout;
if (flags & 1) {
for (size_t i = 0; i < tx.vin.size(); i++) {
s << tx.vin[i].scriptWitness.stack;
}
}
s << tx.nLockTime;

Here, tx.vout contains the transaction outputs, while scriptWitness.stack contains the witness data. The witness stacks are serialized separately when the witness flag is set.

Bitcoin Core calculates transaction weight using the serialized sizes with and without witness data:

Code:
return ::GetSerializeSize(TX_NO_WITNESS(tx)) * (WITNESS_SCALE_FACTOR - 1)
+ ::GetSerializeSize(TX_WITH_WITNESS(tx));

According to BIP141 base transaction size is defined as the transaction serialized without witness data. This means that any OP_RETURN scripts are part of tx.vout, which means they are included in base transaction size, rather than the witness data. As such, they do not get the witness discount.
ABCbits (OP)
Legendary
*
Offline

Activity: 3766
Merit: 10443



View Profile
October 18, 2026, 08:58:17 AM
Merited by stwenhao (1)
 #6

Edit: Another example: a non-Segwit transaction, which used OP_RETURN: https://mempool.space/tx/6dfb16dd580698242bcfd8e433d557ed8c642272a368894de27292a8844a4e75

It happened in 2014, before Segwit, so there is no witness discount of any kind, and OP_RETURN is still there.

It's good and straightforward example. If OP_RETURN output or any other part of the TX counted as witness data, value of size, virtual size and adjusted vsize should be different.

OP_RETURN is an OP code and OP codes aren't part of anything, they can exist anywhere even in a witness stack (last I checked it could exist in an unexecuted OP_IF branch). So if you put it there, it can be part of the witness data.

But I guess what you meant to ask was an OP_RETURN output which are provably unspendable and people use to insert a messages into the chain; in which case the question answers itself (the proof is in the question itself)! An "output" is not part of the witness data. It is an output so its size is calculated like before without the "witness discount".
Witness data is part of the input, the scripts or rather the stack items that were part of the signature (scriptsig) are placed in the witness.

Yeah, i actually asked about OP_RETURN output. But it's good reminder it could also exist as part of input. Although i wonder if there's any past TX on Bitcoin mainnet that intentionally use OP_RETURN on input.

nc50lc
Legendary
*
Offline

Activity: 3304
Merit: 9292


Self-proclaimed Genius


View Profile
October 19, 2026, 01:44:56 PM
Merited by ABCbits (2), vapourminer (1)
 #7

I'm looking for proof(s) which prove or disprove OP_RETURN isn't part or categorized as witness data (which imply OP_RETURN doesn't benefit from witness discount).
Since you know that witness data is 1WU per Byte and legacy is 4WU,
Calculating the total weight of a SegWit transaction that has an OP_RETURN output should prove this as a real-world example.

e.g.: this txn (testnet4): 59b0931a2f0d54c3db56972ed0525197352de5a2c33f9922ec24f3faf348193d (637WU)

Raw transaction (witness data marked teal, OP_RETURN marked yellow):
0200000000010156f66edf736f695e5f70bd636d05292d80bc0793fbfff627a071690468a2e3e00100000000fdf fffff0300000000000000000a6a082042414e414e4120a08601000000000016001461d99b994912795e1567637f24f5ba9c990c1f3be9e71400000000001 600148ca40ed6c5a4101516f4d7f85993a5b09c3fe65b0247304402200ea5873a1bf27d555025b9f280be548eb2c29d303c210007f26544806318f7a8022 013236ad0b90ad6f6b21572ead4879c80218902f42a446bddde39ae4c59056b1b012102faa6e115 19f20f7771f9c2c41f70a4fb4317c5b4916ce459d6b7c4f615f83f5a64650200

So, by simply calculating the marked and unmarked parts' weights, you can check if it matches the calculated weight by nodes.

Assuming OP_RETURN isn't witness:
02000000 4Bytes 16WU
0001 2Bytes 2WU
0156f66edf736f695e5f70bd636d05292d80bc0793fbfff627a071690468a2e3e00100000000fdf fffff0300000000000000000a6a082042414e414e4120a08601000000000016001461d99b994912795e1567637f24f5ba9c990c1f3be9e71400000000001 600148ca40ed6c5a4101516f4d7f85993a5b09c3fe65b
124Bytes 496WU
0247304402200ea5873a1bf27d555025b9f280be548eb2c29d303c210007f26544806318f7a8022 013236ad0b90ad6f6b21572ead4879c80218902f42a446bddde39ae4c59056b1b012102faa6e115 19f20f7771f9c2c41f70a4fb4317c5b4916ce459d6b7c4f615f83f5a
107Bytes 107WU
64650200 4Bytes 16WU

The total weight unit is: 16+2+496+107+16= 637WU (matches the size on Blockexplorers)

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!