<blockquote>
<p><strong>What is the default endianness of the arith_uint256 type?</strong></p>
</blockquote>
<p><strong>tl;dr:</strong> The one chosen by the libraries and compiler you are using for the processor you targeted? But that's not what you need to know.</p>
<hr />
<p>Endianness is a greater source of confusion in Bitcoin than in any other software project I have encountered.</p>
<h2>CPU</h2>
<p>Some historically popular processors, 68K, SPARC, PowerPC, were big-endian - but these are no longer significant.</p>
<p>Currently, most personal computers that are larger than pocket sized  use processors that are little-endian. Most of those processors have an instruction to efficiently swap between byte orders. For example <code>bswap</code> or <code>rev</code>. This sort of provision normally makes endianness relatively unimportant for efficiency considerations.</p>
<p>Current ARM processor designs are said to be bi-endian. They can work with either endianness with equal efficiency.</p>
<h2>Internet</h2>
<p>Internet standards specify that data transmitted over the Internet should transmit numbers in big-endian order. However Bitcoin does not. This also is a source of confusion.</p>
<h2>Software</h2>
<p>In most of the software development projects I have worked on, including heterogeneous network applications, endianness is not an issue. Developers don't even need to be aware of endianness. The compiler takes care of this for you. Standard software libraries take care of this for you.</p>
<p>Bitcoin core is an exception to this. There are probably many others but it is the only project I recall encountering where this is a big issue that frequently trips people up and causes confusion so often.</p>
<h2>Humans</h2>
<p>Most numbers presented to humans in hexadecimal notation are presented as big-endian. This means the most significant digits are on the left, so that in a left-to-right writing system the offset or position-index is smallest for the most significant digit.</p>
<hr />
<h2>Conclusion</h2>
<p>The order you see in a hexadecimal representation might have been ordered to suit human interpretation or it might be ordered to match, for example, network order. Context should make this apparent.</p>
<hr />

CC BY-SA 4.0
2024-05-23T11:07:44.567Z
Succinctly put. Appreciate the overview. "How to (not) think about endianness in Bitcoin" should have been the question title!
Lee
CC BY-SA 4.0
2024-05-23T09:55:11.013Z
2024-05-23T10:44:57.157Z
2024-05-23T10:44:57.157Z
RedGrittyBrick
<blockquote>
<p>When comparing a candidate block header hash to the target, should we
consider the target as big or little endian?</p>
</blockquote>
<p><code>0x0000000000000000000355f00000000000000000000000000000000000000000</code> should be taken as a number. The byte order/endianness is a property of the computer on which it is stored/used.</p>
<blockquote>
<p>For the above example, what is the maximum block header hash value (in
hexadecimal) that would result in a valid block (assuming hash of
valid block header)</p>
</blockquote>
<p><code>0x0000000000000000000355e00000000000000000000000000000000000000000</code></p>
<blockquote>
<p>and what is its endianness?</p>
</blockquote>
<p>See first answer.</p>
<blockquote>
<p>What is the default endianness of the arith_uint256 type?</p>
</blockquote>
<p>I'm unsure on this.</p>

CC BY-SA 4.0
2024-05-23T09:25:53.143Z
2024-05-23T09:25:53.143Z
Lee
<p>Let's take the latest bits value, at the time of writing:</p>
<pre><code>0x170355f0
</code></pre>
<p>And <a href="https://bitcoin.stackexchange.com/a/36228/34190">convert it to the target</a>:</p>
<pre><code>0x0000000000000000000355f00000000000000000000000000000000000000000
</code></pre>
<p>When comparing a candidate block header hash to the target, should we consider the target as big or little endian? I suppose the important thing is that the block header hash and the target are a consistent way round.</p>
<p>For the above example, what is the maximum block header hash value (in hexadecimal) that would result in a valid block (assuming hash of valid block header) and what is its endianness?</p>
<hr />
<p><em>Update</em>:</p>
<p><strike>Where could I look in the Bitcoin Core source code to be informed about the endianness of the target?</strike></p>
<p>I see that Bitcoin Core's <a href="https://github.com/bitcoin/bitcoin/blob/ef44726918c05e158246cb695ae358db603653e9/src/pow.cpp#L125" rel="nofollow noreferrer">pow.cpp</a> has the following:</p>
<pre class="lang-cpp prettyprint-override"><code>bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&amp; params)
{
    bool fNegative;
    bool fOverflow;
    arith_uint256 bnTarget;

    bnTarget.SetCompact(nBits, &amp;fNegative, &amp;fOverflow);

    // Check range
    if (fNegative || bnTarget == 0 || fOverflow || bnTarget &gt; UintToArith256(params.powLimit))
        return false;

    // Check proof of work matches claimed amount
    if (UintToArith256(hash) &gt; bnTarget)
        return false;

    return true;
}
</code></pre>
<p>I think that <code>(UintToArith256(hash) &gt; bnTarget)</code> is the condition I'm getting at. What is the default endianness of the <code>arith_uint256</code> type?</p>

<bitcoin-core><difficulty><endianness><nbits>
What is the endianness of the target?
Lee
# What is the endianness of the target?

(Asked by: username_0 on 2024-05-23)

Let's take the latest bits value, at the time of writing:

```
0x170355f0

```

And [convert it to the target](https://bitcoin.stackexchange.com/a/36228/34190):

```
0x0000000000000000000355f00000000000000000000000000000000000000000

```

When comparing a candidate block header hash to the target, should we consider the target as big or little endian? I suppose the important thing is that the block header hash and the target are a consistent way round.

For the above example, what is the maximum block header hash value (in hexadecimal) that would result in a valid block (assuming hash of valid block header) and what is its endianness?

---

*Update*:

Where could I look in the Bitcoin Core source code to be informed about the endianness of the target?

I see that Bitcoin Core's [pow.cpp](https://github.com/bitcoin/bitcoin/blob/ef44726918c05e158246cb695ae358db603653e9/src/pow.cpp#L125) has the following:

```cpp
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
{
    bool fNegative;
    bool fOverflow;
    arith_uint256 bnTarget;

    bnTarget.SetCompact(nBits, &fNegative, &fOverflow);

    // Check range
    if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
        return false;

    // Check proof of work matches claimed amount
    if (UintToArith256(hash) > bnTarget)
        return false;

    return true;
}

```

I think that `(UintToArith256(hash) > bnTarget)` is the condition I'm getting at. What is the default endianness of the `arith_uint256` type?

**Tags:** bitcoin-core, difficulty, endianness, nbits


---

## 2 answers

### Answer by username_1 on 2024-05-23. Score: 1 | Accepted answer

> **What is the default endianness of the arith\_uint256 type?**

**tl;dr:** The one chosen by the libraries and compiler you are using for the processor you targeted? But that's not what you need to know.

---

Endianness is a greater source of confusion in Bitcoin than in any other software project I have encountered.

## CPU

Some historically popular processors, 68K, SPARC, PowerPC, were big-endian - but these are no longer significant.

Currently, most personal computers that are larger than pocket sized use processors that are little-endian. Most of those processors have an instruction to efficiently swap between byte orders. For example `bswap` or `rev`. This sort of provision normally makes endianness relatively unimportant for efficiency considerations.

Current ARM processor designs are said to be bi-endian. They can work with either endianness with equal efficiency.

## Internet

Internet standards specify that data transmitted over the Internet should transmit numbers in big-endian order. However Bitcoin does not. This also is a source of confusion.

## Software

In most of the software development projects I have worked on, including heterogeneous network applications, endianness is not an issue. Developers don't even need to be aware of endianness. The compiler takes care of this for you. Standard software libraries take care of this for you.

Bitcoin core is an exception to this. There are probably many others but it is the only project I recall encountering where this is a big issue that frequently trips people up and causes confusion so often.

## Humans

Most numbers presented to humans in hexadecimal notation are presented as big-endian. This means the most significant digits are on the left, so that in a left-to-right writing system the offset or position-index is smallest for the most significant digit.

---

## Conclusion

The order you see in a hexadecimal representation might have been ordered to suit human interpretation or it might be ordered to match, for example, network order. Context should make this apparent.

---

> **Comments:**
> **username_0**: Succinctly put. Appreciate the overview. "How to (not) think about endianness in Bitcoin" should have been the question title!  

---

### Answer by username_0 on 2024-05-23. Score: 0

> When comparing a candidate block header hash to the target, should we
> consider the target as big or little endian?

`0x0000000000000000000355f00000000000000000000000000000000000000000` should be taken as a number. The byte order/endianness is a property of the computer on which it is stored/used.

> For the above example, what is the maximum block header hash value (in
> hexadecimal) that would result in a valid block (assuming hash of
> valid block header)

`0x0000000000000000000355e00000000000000000000000000000000000000000`

> and what is its endianness?

See first answer.

> What is the default endianness of the arith\_uint256 type?

I'm unsure on this.


---

