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:

    nVersion = this->nVersion;

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 ints 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?

  • 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 Mar 7 '14 at 20:48
  • @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 Mar 7 '14 at 20:53
  • "satoshi client" Do you mean Bitcoin-Qt? – Peter Mortensen Mar 8 '14 at 9:09
  • @PeterMortensen: yep! – Claudiu Mar 8 '14 at 9:59

The answer is simple: big-endian architectures are not supported.

  • 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 Oct 1 '14 at 8:19
  • @PieterWuille It may be possible to use a QEMU VM for testing, so the problem is that nobody cares. – abacabadabacaba Oct 1 '14 at 8:23
  • 1
    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 Oct 1 '14 at 20:55
  • @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 Oct 4 '14 at 2:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.