Estoy revisando el código fuente del cliente satoshi, particularmente cómo se serializan y envían las transacciones a través de la red o se almacenan en el disco.
La CTransaction
clase tiene este bloque:
IMPLEMENT_SERIALIZE
(
READWRITE(this->nVersion);
nVersion = this->nVersion;
READWRITE(vin);
READWRITE(vout);
READWRITE(nLockTime);
)
Si no me equivoco, la parte serializada de IMPLEMENT_SERIALIZE
se expande a:
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))
}
}
Centrémonos nLockTime
por ahora, que es un unsigned int
. SerReadWrite
Se define como:
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;
}
La Serialize
función, para unsigned int
s se define como:
template<typename Stream>
inline void Serialize(Stream& s, unsigned int a, int, int=0) {
WRITEDATA(s, a);
}
Que se expande a:
template<typename Stream>
inline void Serialize(Stream& s, unsigned int a, int, int=0) {
s.write((char*)&(a), sizeof(a))
}
Entonces, esto convierte los 4 bytes unsigned int
en a char*
y luego los escribe en la secuencia.
Sin embargo, ¿no tendrá esto un resultado diferente en las máquinas big-endian frente a las máquinas little-endian? ¿Cómo maneja esto el cliente? ¿O el protocolo está definido en términos de little-endian, y en las máquinas en las que se basa el cliente satoshi, termina funcionando?
La respuesta es simple: las arquitecturas big-endian no son compatibles .
Nate Eldredge
claudio
nType
es uno deSER_NETWORK
,SER_DISK
ySER_GETHASH
, así que creo que este código también se usa para eso. (es el tercer parámetro deSerialize
, no se nombra porque no se usa). Parece un error de novato, ¡por eso pregunto!Pedro Mortensen
claudio