<p>The answer is simple: <a href="https://github.com/bitcoin/bitcoin/issues/888" rel="nofollow">big-endian architectures are not supported</a>.</p>

CC BY-SA 3.0
2014-10-01T08:19:59.870Z
This is correct. There have been a few attempts where people wanted to fix this, but as far as I know, nobody succeeded. Reason? It's awfully hard to find actual hardware to test this on, and even harder to find people who actually care :)
Pieter Wuille
CC BY-SA 3.0
2014-10-01T08:23:10.770Z
@PieterWuille It may be possible to use a QEMU VM for testing, so the problem is that nobody cares.
abacabadabacaba
CC BY-SA 3.0
2014-10-01T20:55:00.067Z
Everything is possible. The point is that so few people care or are actually affected by this (almost no new hardware is big-endian these days), that it doesn't make much sense to prioritize this. Nobody will argue that being endian-neutral would be a bad thing, but someone still has to do it.
Pieter Wuille
CC BY-SA 3.0
2014-10-04T02:14:45.103Z
@abacabadabacaba I've been wondering why there's inconsistencies in Endianess in transactions and mining protocol. I'm only just getting the hang of the concept of Endianess (to me it makes *no sense* to write bytes right to left). Why on Earth isn't there consistency (ELI5 if possible!)
Wizard Of Ozzie
CC BY-SA 3.0
2014-10-01T05:24:39.560Z
2014-10-01T05:24:39.560Z
abacabadabacaba
<p>I'm looking through the source code of the satoshi client, particularly into how transactions are serialized and sent through the network or stored to the disk.</p>

<p>The <code>CTransaction</code> class has this block:</p>

<pre><code>IMPLEMENT_SERIALIZE
(
    READWRITE(this-&gt;nVersion);
    nVersion = this-&gt;nVersion;
    READWRITE(vin);
    READWRITE(vout);
    READWRITE(nLockTime);
)
</code></pre>

<p>If I'm not mistaken, the serialize part of <code>IMPLEMENT_SERIALIZE</code> expands to:</p>

<pre><code>template&lt;typename Stream&gt;                   
void Serialize(Stream&amp; s, int nType, int nVersion) const  
{                                           
    CSerActionSerialize ser_action;         
    const bool fGetSize = false;            
    const bool fWrite = true;               
    const bool fRead = false;               
    unsigned int nSerSize = 0;              
    assert(fGetSize||fWrite||fRead); /* suppress warning */
    {
        (nSerSize += ::SerReadWrite(s, (this-&gt;nVersion), nType, nVersion, ser_action))
        nVersion = this-&gt;nVersion;
        (nSerSize += ::SerReadWrite(s, (vin), nType, nVersion, ser_action))
        (nSerSize += ::SerReadWrite(s, (vout), nType, nVersion, ser_action))
        (nSerSize += ::SerReadWrite(s, (nLockTime), nType, nVersion, ser_action))
    }
}                                           
</code></pre>

<p>Let's focus on <code>nLockTime</code> for now, which is an <code>unsigned int</code>. <code>SerReadWrite</code> is defined as:</p>

<pre><code>template&lt;typename Stream, typename T&gt;
inline unsigned int SerReadWrite(Stream&amp; s, const T&amp; obj, int nType, int nVersion, CSerActionSerialize ser_action)
{
    ::Serialize(s, obj, nType, nVersion);
    return 0;
}
</code></pre>

<p>The <code>Serialize</code> function, for <code>unsigned int</code>s is defined as:</p>

<pre><code>template&lt;typename Stream&gt; 
inline void Serialize(Stream&amp; s, unsigned int a, int, int=0) { 
    WRITEDATA(s, a); 
}
</code></pre>

<p>Which expands to:</p>

<pre><code>template&lt;typename Stream&gt; 
inline void Serialize(Stream&amp; s, unsigned int a, int, int=0) { 
    s.write((char*)&amp;(a), sizeof(a))
}
</code></pre>

<p>So, this converts the 4-byte <code>unsigned int</code> to a <code>char*</code> and then writes it to the stream.</p>

<p>However, won't this have a different result on big-endian vs. little-endian machines? How does the client handle this? Or is the protocol defined in terms of little-endian, and on the machines the satoshi client is built on, it ends up just working out?</p>

CC BY-SA 3.0
2014-03-07T20:48:13.010Z
For purposes of storing to disk, it shouldn't matter because the disk files are probably not  intended to be portable. Are you sure this same code is used to send data on the network? Ignoring endianness for network data would be rather a rookie mistake.
Nate Eldredge
CC BY-SA 3.0
2014-03-07T20:53:15.337Z
@NateEldredge: yep for storing disk, it shouldn't matter. `nType` is one of `SER_NETWORK`, `SER_DISK`, and `SER_GETHASH`, so I think this code is used for that as well. (it's the 3rd parameter to `Serialize`, not it isn't named because it's not used). It does seem like a rookie mistake, which is why I'm asking!
Claudiu
CC BY-SA 3.0
2014-03-08T09:09:34.907Z
"satoshi client" Do you mean [Bitcoin-Qt](https://en.bitcoin.it/wiki/Bitcoin-Qt)?
Peter Mortensen
CC BY-SA 3.0
2014-03-08T09:59:05.290Z
@PeterMortensen: yep!
Claudiu
<client><protocol><bitcoin-core><network><endianness>
How does the satoshi client handle endianness?
Claudiu
# How does the satoshi client handle endianness?

(Asked by: username_0 on 2014-03-07)

I'm looking through the source code of the satoshi client, particularly into how transactions are serialized and sent through the network or stored to the disk.

The `CTransaction` class has this block:

```
IMPLEMENT_SERIALIZE
(
    READWRITE(this->nVersion);
    nVersion = this->nVersion;
    READWRITE(vin);
    READWRITE(vout);
    READWRITE(nLockTime);
)

```

If I'm not mistaken, the serialize part of `IMPLEMENT_SERIALIZE` expands to:

```
template<typename Stream>                   
void Serialize(Stream& s, int nType, int nVersion) const  
{                                           
    CSerActionSerialize ser_action;         
    const bool fGetSize = false;            
    const bool fWrite = true;               
    const bool fRead = false;               
    unsigned int nSerSize = 0;              
    assert(fGetSize||fWrite||fRead); /* suppress warning */
    {
        (nSerSize += ::SerReadWrite(s, (this->nVersion), nType, nVersion, ser_action))
        nVersion = this->nVersion;
        (nSerSize += ::SerReadWrite(s, (vin), nType, nVersion, ser_action))
        (nSerSize += ::SerReadWrite(s, (vout), nType, nVersion, ser_action))
        (nSerSize += ::SerReadWrite(s, (nLockTime), nType, nVersion, ser_action))
    }
}                                           

```

Let's focus on `nLockTime` for now, which is an `unsigned int`. `SerReadWrite` is defined as:

```
template<typename Stream, typename T>
inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
{
    ::Serialize(s, obj, nType, nVersion);
    return 0;
}

```

The `Serialize` function, for `unsigned int`s is defined as:

```
template<typename Stream> 
inline void Serialize(Stream& s, unsigned int a, int, int=0) { 
    WRITEDATA(s, a); 
}

```

Which expands to:

```
template<typename Stream> 
inline void Serialize(Stream& s, unsigned int a, int, int=0) { 
    s.write((char*)&(a), sizeof(a))
}

```

So, this converts the 4-byte `unsigned int` to a `char*` and then writes it to the stream.

However, won't this have a different result on big-endian vs. little-endian machines? How does the client handle this? Or is the protocol defined in terms of little-endian, and on the machines the satoshi client is built on, it ends up just working out?

**Tags:** client, protocol, bitcoin-core, network, endianness

> **Comments:**
> **username_1**: For purposes of storing to disk, it shouldn't matter because the disk files are probably not  intended to be portable. Are you sure this same code is used to send data on the network? Ignoring endianness for network data would be rather a rookie mistake.  
> **username_0**: @username_1: yep for storing disk, it shouldn't matter. `nType` is one of `SER_NETWORK`, `SER_DISK`, and `SER_GETHASH`, so I think this code is used for that as well. (it's the 3rd parameter to `Serialize`, not it isn't named because it's not used). It does seem like a rookie mistake, which is why I'm asking!  
> **username_2**: "satoshi client" Do you mean [Bitcoin-Qt](https://en.bitcoin.it/wiki/Bitcoin-Qt)?  
> **username_0**: @username_2: yep!  

---

## 1 answers

### Answer by username_3 on 2014-10-01. Score: 3

The answer is simple: [big-endian architectures are not supported](https://github.com/bitcoin/bitcoin/issues/888).

> **Comments:**
> **username_4**: This is correct. There have been a few attempts where people wanted to fix this, but as far as I know, nobody succeeded. Reason? It's awfully hard to find actual hardware to test this on, and even harder to find people who actually care :)  
> **username_3**: @username_4 It may be possible to use a QEMU VM for testing, so the problem is that nobody cares.  
> **username_4**: Everything is possible. The point is that so few people care or are actually affected by this (almost no new hardware is big-endian these days), that it doesn't make much sense to prioritize this. Nobody will argue that being endian-neutral would be a bad thing, but someone still has to do it.  
> **username_5**: @username_3 I've been wondering why there's inconsistencies in Endianess in transactions and mining protocol. I'm only just getting the hang of the concept of Endianess (to me it makes *no sense* to write bytes right to left). Why on Earth isn't there consistency (ELI5 if possible!)  

---

