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