Bitcoin Forum
April 16, 2024, 08:23:43 PM *
News: Latest Bitcoin Core release: 26.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Are block/Tx versions signed or unsigned? Why?  (Read 264 times)
Coding Enthusiast (OP)
Legendary
*
Offline Offline

Activity: 1039
Merit: 2783


Bitcoin and C♯ Enthusiast


View Profile WWW
December 07, 2018, 01:09:52 PM
Merited by ABCbits (1)
 #1

Bitcoin under the hood has a tendency of surprising me!
The latest one which I can't find anything about is why is block version and transaction versions defined as signed integers instead of being unsigned integers like any other 4 byte "numbers" that exists in them?

While we are on the subject, developer's reference is saying data type is uint32_t for transaction version. I wanted to open a PR but I thought maybe I am missing something since my C++ understanding is limited! (bitcoin core code?)

Projects List+Suggestion box
Donate: 1Q9s or bc1q
|
|
|
FinderOuter(0.19.1)Ann-git
Denovo(0.7.0)Ann-git
Bitcoin.Net(0.26.0)Ann-git
|
|
|
BitcoinTransactionTool(0.11.0)Ann-git
WatchOnlyBitcoinWallet(3.2.1)Ann-git
SharpPusher(0.12.0)Ann-git
1713299023
Hero Member
*
Offline Offline

Posts: 1713299023

View Profile Personal Message (Offline)

Ignore
1713299023
Reply with quote  #2

1713299023
Report to moderator
1713299023
Hero Member
*
Offline Offline

Posts: 1713299023

View Profile Personal Message (Offline)

Ignore
1713299023
Reply with quote  #2

1713299023
Report to moderator
According to NIST and ECRYPT II, the cryptographic algorithms used in Bitcoin are expected to be strong until at least 2030. (After that, it will not be too difficult to transition to different algorithms.)
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1713299023
Hero Member
*
Offline Offline

Posts: 1713299023

View Profile Personal Message (Offline)

Ignore
1713299023
Reply with quote  #2

1713299023
Report to moderator
achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 3360
Merit: 6505


Just writing some code


View Profile WWW
December 07, 2018, 06:18:40 PM
Merited by suchmoon (4), ABCbits (1), Coding Enthusiast (1)
 #2

Both version numbers are signed. In most cases, whether the version number is signed or not doesn't really matter. The same applies for almost every other integer used in Bitcoin.

As for why, it's because satoshi chose to use an int instead of an unsigned int in the original code, so the signedness has stuck around since then.

The only number that changed signedness was nLocktime which was originally an int. At some point, satoshi changed this to an unsigned int.

aliashraf
Legendary
*
Offline Offline

Activity: 1456
Merit: 1174

Always remember the cause!


View Profile WWW
December 08, 2018, 11:22:46 AM
 #3

As for why, it's because satoshi chose to use an int instead of an unsigned int in the original code, so the signedness has stuck around since then.

I could find no history of or a reason for either fields, tx/block version number, to be used as a signed integer, hence there would be no side-effect in case of declaring them as unsigned in the code, Right?

That said, I don't understand how would it make any difference at all? As of my understanding of the client code, they are used neither as signed nor as unsigned integer right now.  I mean, we could just declare them as char[4], Couldn't we?
Coding Enthusiast (OP)
Legendary
*
Offline Offline

Activity: 1039
Merit: 2783


Bitcoin and C♯ Enthusiast


View Profile WWW
December 08, 2018, 04:15:01 PM
Merited by achow101 (3), ABCbits (1)
 #4

As for why, it's because satoshi chose to use an int instead of an unsigned int in the original code, so the signedness has stuck around since then.

I could find no history of or a reason for either fields, tx/block version number, to be used as a signed integer, hence there would be no side-effect in case of declaring them as unsigned in the code, Right?

That said, I don't understand how would it make any difference at all? As of my understanding of the client code, they are used neither as signed nor as unsigned integer right now.  I mean, we could just declare them as char[4], Couldn't we?


In short whether you implement it as uint or Int you will be compatible with bitcoin core implementation until version 2147483647!

But technically it should never matter as long as nobody sets the last byte bigger than 127 because that is where Int32 and UInt32 start to differ. A signed integer uses the highest bit of the last byte for its sign. For example {255, 255, 255, 255} is 4294967295 as uint but is -1 if interpreted as Int.

Projects List+Suggestion box
Donate: 1Q9s or bc1q
|
|
|
FinderOuter(0.19.1)Ann-git
Denovo(0.7.0)Ann-git
Bitcoin.Net(0.26.0)Ann-git
|
|
|
BitcoinTransactionTool(0.11.0)Ann-git
WatchOnlyBitcoinWallet(3.2.1)Ann-git
SharpPusher(0.12.0)Ann-git
aliashraf
Legendary
*
Offline Offline

Activity: 1456
Merit: 1174

Always remember the cause!


View Profile WWW
December 08, 2018, 05:33:14 PM
 #5

As for why, it's because satoshi chose to use an int instead of an unsigned int in the original code, so the signedness has stuck around since then.

I could find no history of or a reason for either fields, tx/block version number, to be used as a signed integer, hence there would be no side-effect in case of declaring them as unsigned in the code, Right?

That said, I don't understand how would it make any difference at all? As of my understanding of the client code, they are used neither as signed nor as unsigned integer right now.  I mean, we could just declare them as char[4], Couldn't we?


In short whether you implement it as uint or Int you will be compatible with bitcoin core implementation until version 2147483647!

But technically it should never matter as long as nobody sets the last byte bigger than 127 because that is where Int32 and UInt32 start to differ. A signed integer uses the highest bit of the last byte for its sign. For example {255, 255, 255, 255} is 4294967295 as uint but is -1 if interpreted as Int.

Actually nobody uses those fields as a meaningful number, they are just 4 consecutive bytes.
achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 3360
Merit: 6505


Just writing some code


View Profile WWW
December 08, 2018, 05:59:55 PM
 #6

Actually nobody uses those fields as a meaningful number, they are just 4 consecutive bytes.
Incorrect.

For the block version number, due to BIP 34 style soft fork deployments, the block version number must be greater than or equal to 4. This check is always done because of those soft forks. Furthermore, because it is signed, this requirement means that the highest bit cannot be set For this reason, BIP 9 specifies that the highest most bit must be a 0.

For the transaction version number, the version number is always interpreted as a meaningful number. A standard transaction must have a version number between 1 and the maximum version number inclusive. At this time, the maximum is 2.

aliashraf
Legendary
*
Offline Offline

Activity: 1456
Merit: 1174

Always remember the cause!


View Profile WWW
December 08, 2018, 07:11:26 PM
 #7

Actually nobody uses those fields as a meaningful number, they are just 4 consecutive bytes.
Incorrect.

For the block version number, due to BIP 34 style soft fork deployments, the block version number must be greater than or equal to 4. This check is always done because of those soft forks. Furthermore, because it is signed, this requirement means that the highest bit cannot be set For this reason, BIP 9 specifies that the highest most bit must be a 0.

For the transaction version number, the version number is always interpreted as a meaningful number. A standard transaction must have a version number between 1 and the maximum version number inclusive. At this time, the maximum is 2.
ُStill, they are not meaningful numbers. We use int or unsigned int data types when we are dealing with quantities in respected ranges or there is any possibility for such a use case in future.

In block version number case and BIP 34 we are using least significant byte to signal a compatibility level and in txn it is always set to 1 for compatibility purposes and AFAIK occasionally Shipshift sets it to 2. again sort of signaling.

Suppose we declare txn version number as char[4], then we would assert txnVN[3] should be set to a value between 1 and the highest version number.
Coding Enthusiast (OP)
Legendary
*
Offline Offline

Activity: 1039
Merit: 2783


Bitcoin and C♯ Enthusiast


View Profile WWW
December 09, 2018, 03:24:34 AM
 #8

Still, they are not meaningful numbers. We use int or unsigned int data types when we are dealing with quantities in respected ranges or there is any possibility for such a use case in future.

In block version number case and BIP 34 we are using least significant byte to signal a compatibility level and in txn it is always set to 1 for compatibility purposes and AFAIK occasionally Shipshift sets it to 2. again sort of signaling.

Suppose we declare txn version number as char[4], then we would assert txnVN[3] should be set to a value between 1 and the highest version number.

If you think that way then everything else can only be interpreted as an array of bytes instead of a variable type. But setting the 4 bytes as an int makes things easier. For instance when you get a block and deserialize its transactions it is easier to put the first 4 bytes in an int instead of a byte array and then in the verification process you just say if version<2 && has OP_CHECKSEQUENCEVERIFY then reject as invalid rather than saying if byte[0]<2 && byte[1]==0 && byte[2]==0 && byte[3]==0 && hash OP_.....
And transaction version does have a meaning. Check BIP68.

Projects List+Suggestion box
Donate: 1Q9s or bc1q
|
|
|
FinderOuter(0.19.1)Ann-git
Denovo(0.7.0)Ann-git
Bitcoin.Net(0.26.0)Ann-git
|
|
|
BitcoinTransactionTool(0.11.0)Ann-git
WatchOnlyBitcoinWallet(3.2.1)Ann-git
SharpPusher(0.12.0)Ann-git
aliashraf
Legendary
*
Offline Offline

Activity: 1456
Merit: 1174

Always remember the cause!


View Profile WWW
December 09, 2018, 06:27:39 PM
Last edit: December 09, 2018, 06:48:40 PM by aliashraf
 #9

Still, they are not meaningful numbers. We use int or unsigned int data types when we are dealing with quantities in respected ranges or there is any possibility for such a use case in future.

In block version number case and BIP 34 we are using least significant byte to signal a compatibility level and in txn it is always set to 1 for compatibility purposes and AFAIK occasionally Shipshift sets it to 2. again sort of signaling.

Suppose we declare txn version number as char[4], then we would assert txnVN[3] should be set to a value between 1 and the highest version number.

If you think that way then everything else can only be interpreted as an array of bytes instead of a variable type. But setting the 4 bytes as an int makes things easier. For instance when you get a block and deserialize its transactions it is easier to put the first 4 bytes in an int instead of a byte array and then in the verification process you just say if version<2 && has OP_CHECKSEQUENCEVERIFY then reject as invalid rather than saying if byte[0]<2 && byte[1]==0 && byte[2]==0 && byte[3]==0 && hash OP_.....
And transaction version does have a meaning. Check BIP68.
I'm not discussing generally  Cheesy
You don't need to check other bytes, just byte[3] < 2 suffices (it is little endian AFAIK). The point is,  for the fields under discussion there is no signed or unsigned int use case ever.
Block version number is mostly used in ASIC Boost implementation for anthropy purposes, it is no int.
This is worse for txn version notto be confused with sequence number) , it is mostly set to 1 with very rare exceptions that are set to 2 by some wallets. again it is no int.
I personally don't like such a style in using integer data type when it comes to encoding I prefer to use properly sized byte arrays and int for quantization.
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!