Ich sehe mir den Quellcode des Satoshi-Clients an, insbesondere wie Transaktionen serialisiert und über das Netzwerk gesendet oder auf der Festplatte gespeichert werden.
Die CTransaction
Klasse hat diesen Block:
IMPLEMENT_SERIALIZE
(
READWRITE(this->nVersion);
nVersion = this->nVersion;
READWRITE(vin);
READWRITE(vout);
READWRITE(nLockTime);
)
Wenn ich mich nicht irre, IMPLEMENT_SERIALIZE
erweitert sich der Serialisierungsteil von zu:
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))
}
}
Konzentrieren wir uns nLockTime
zunächst darauf, was eine unsigned int
. SerReadWrite
ist definiert als:
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;
}
Die Serialize
Funktion für unsigned int
s ist definiert als:
template<typename Stream>
inline void Serialize(Stream& s, unsigned int a, int, int=0) {
WRITEDATA(s, a);
}
Was sich erweitert zu:
template<typename Stream>
inline void Serialize(Stream& s, unsigned int a, int, int=0) {
s.write((char*)&(a), sizeof(a))
}
Dies wandelt also die 4-Byte unsigned int
in a um char*
und schreibt sie dann in den Stream.
Wird dies jedoch auf Big-Endian- und Little-Endian-Maschinen nicht zu unterschiedlichen Ergebnissen führen? Wie geht der Kunde damit um? Oder ist das Protokoll in Little-Endian definiert, und auf den Maschinen, auf denen der Satoshi-Client aufgebaut ist, funktioniert es am Ende einfach?
Die Antwort ist einfach: Big-Endian-Architekturen werden nicht unterstützt .
Nate Eldredge
Claudius
nType
ist einer vonSER_NETWORK
,SER_DISK
, undSER_GETHASH
, also denke ich, dass dieser Code auch dafür verwendet wird. (Es ist der 3. Parameter vonSerialize
, nicht er wird nicht benannt, weil er nicht verwendet wird). Es scheint ein Anfängerfehler zu sein, weshalb ich frage!Peter Mortensen
Claudius