Exemple #1
0
 def parsear(cls, s):
     '''Toma un stream de bytes y parsea el bloque merkle. Devuelve un objeto Bloque Merkle'''
     # s.read(n) leerá n bytes desde el stream
     # versión - 4 bytes, little endian, interpretalo como int
     versión = little_endian_a_int(s.read(4))
     # bloque_previo - 32 bytes, little endian (usa [::-1] para darle la vuelta)
     bloque_previo = s.read(32)[::-1]
     # raíz_merkle - 32 bytes, little endian (usa [::-1] para darle la vuelta)
     raíz_merkle = s.read(32)[::-1]
     # timestamp - 4 bytes, little endian, interpretalo como int
     timestamp = little_endian_a_int(s.read(4))
     # bits - 4 bytes
     bits = s.read(4)
     # nonce - 4 bytes
     nonce = s.read(4)
     # número total de transacciones (4 bytes, little endian)
     total = little_endian_a_int(s.read(4))
     # el número de hashes es un varint
     num_txs = read_varint(s)
     # inicializa el array de hashes
     hashes = []
     # haz un bucle tantas veces como el número de hashes
     for _ in range(num_txs):
         # cada hash es 32 bytes, little endian
         hashes.append(s.read(32)[::-1])
     # obtén la longitud del campo flags como un varint
     longitud_flags = read_varint(s)
     # lee el campo flags
     flags = s.read(longitud_flags)
     # inicializa la clase
     return cls(versión, bloque_previo, raíz_merkle, timestamp, bits, nonce,
                total, hashes, flags)
Exemple #2
0
 def prueba_parsear(self):
     hex_bloque_merkle = '00000020df3b053dc46f162a9b00c7f0d5124e2676d47bbe7c5d0793a500000000000000ef445fef2ed495c275892206ca533e7411907971013ab83e3b47bd0d692d14d4dc7c835b67d8001ac157e670bf0d00000aba412a0d1480e370173072c9562becffe87aa661c1e4a6dbc305d38ec5dc088a7cf92e6458aca7b32edae818f9c2c98c37e06bf72ae0ce80649a38655ee1e27d34d9421d940b16732f24b94023e9d572a7f9ab8023434a4feb532d2adfc8c2c2158785d1bd04eb99df2e86c54bc13e139862897217400def5d72c280222c4cbaee7261831e1550dbb8fa82853e9fe506fc5fda3f7b919d8fe74b6282f92763cef8e625f977af7c8619c32a369b832bc2d051ecd9c73c51e76370ceabd4f25097c256597fa898d404ed53425de608ac6bfe426f6e2bb457f1c554866eb69dcb8d6bf6f880e9a59b3cd053e6c7060eeacaacf4dac6697dac20e4bd3f38a2ea2543d1ab7953e3430790a9f81e1c67f5b58c825acf46bd02848384eebe9af917274cdfbb1a28a5d58a23a17977def0de10d644258d9c54f886d47d293a411cb6226103b55635'
     mb = BloqueMerkle.parsear(BytesIO(bytes.fromhex(hex_bloque_merkle)))
     versión = 0x20000000
     self.assertEqual(mb.versión, versión)
     hex_raíz_merkle = 'ef445fef2ed495c275892206ca533e7411907971013ab83e3b47bd0d692d14d4'
     raíz_merkle = bytes.fromhex(hex_raíz_merkle)[::-1]
     self.assertEqual(mb.raíz_merkle, raíz_merkle)
     bloque_previo_hex = 'df3b053dc46f162a9b00c7f0d5124e2676d47bbe7c5d0793a500000000000000'
     bloque_previo = bytes.fromhex(bloque_previo_hex)[::-1]
     self.assertEqual(mb.bloque_previo, bloque_previo)
     timestamp = little_endian_a_int(bytes.fromhex('dc7c835b'))
     self.assertEqual(mb.timestamp, timestamp)
     bits = bytes.fromhex('67d8001a')
     self.assertEqual(mb.bits, bits)
     nonce = bytes.fromhex('c157e670')
     self.assertEqual(mb.nonce, nonce)
     total = little_endian_a_int(bytes.fromhex('bf0d0000'))
     self.assertEqual(mb.total, total)
     hex_hashes = [
         'ba412a0d1480e370173072c9562becffe87aa661c1e4a6dbc305d38ec5dc088a',
         '7cf92e6458aca7b32edae818f9c2c98c37e06bf72ae0ce80649a38655ee1e27d',
         '34d9421d940b16732f24b94023e9d572a7f9ab8023434a4feb532d2adfc8c2c2',
         '158785d1bd04eb99df2e86c54bc13e139862897217400def5d72c280222c4cba',
         'ee7261831e1550dbb8fa82853e9fe506fc5fda3f7b919d8fe74b6282f92763ce',
         'f8e625f977af7c8619c32a369b832bc2d051ecd9c73c51e76370ceabd4f25097',
         'c256597fa898d404ed53425de608ac6bfe426f6e2bb457f1c554866eb69dcb8d',
         '6bf6f880e9a59b3cd053e6c7060eeacaacf4dac6697dac20e4bd3f38a2ea2543',
         'd1ab7953e3430790a9f81e1c67f5b58c825acf46bd02848384eebe9af917274c',
         'dfbb1a28a5d58a23a17977def0de10d644258d9c54f886d47d293a411cb62261',
     ]
     hashes = [bytes.fromhex(h)[::-1] for h in hex_hashes]
     self.assertEqual(mb.hashes, hashes)
     flags = bytes.fromhex('b55635')
     self.assertEqual(mb.flags, flags)
Exemple #3
0
 def parsear(cls, s, testnet=False):
     '''Toma un stream y crea un NetworkEnvelope'''
     # comprueba la magia de red
     magia = s.read(4)
     if magia == b'':
         raise RuntimeError('Conexión reseteada!')
     if testnet:
         magia_esperada = MAGIA_RED_TESTNET
     else:
         magia_esperada = MAGIA_RED
     if magia != magia_esperada:
         raise RuntimeError('magia no es correcta {} vs {}'.format(
             magia.hex(), magia_esperada.hex()))
     # comando 12 bytes
     comando = s.read(12)
     # quita los 0's arrastrados
     comando = comando.strip(b'\x00')
     # longitud de carga 4 bytes, little endian
     longitud_carga = little_endian_a_int(s.read(4))
     # checksum es 4 bytes, los primeros cuatro del doble_sha256 de carga
     checksum = s.read(4)
     # carga es de longitud longitud_carga
     carga = s.read(longitud_carga)
     # verificar checksum
     checksum_calculada = doble_sha256(carga)[:4]
     if checksum_calculada != checksum:
         raise RuntimeError('checksum no es correcta')
     return cls(comando, carga, testnet=testnet)
 def parsear(cls, s):
     '''Toma un stream de bytes y parsea el tx_input al principio
     devuelve un objeto TxIn
     '''
     # s.read(n) devolverá n bytes
     # tx_previa es 32 bytes, little endian
     tx_previa = s.read(32)[::-1]
     # indice_previo es 4 bytes, little endian, interpretalo como int
     indice_previo = little_endian_a_int(s.read(4))
     # script_sig es un campo variable (longitud seguida de los datos)
     # puedes usar Script.parsear para obtener el script real
     script_sig = Script.parsear(s)
     # sequence es 4 bytes, little-endian, interpretalo como entero
     sequence = little_endian_a_int(s.read(4))
     # devuelve una instancia de la clase (cls(...))
     return cls(tx_previa, indice_previo, script_sig, sequence)
 def parsear(cls, s):
     '''Toma un stream de bytes y parsea un bloque. Devuelve un objeto Bloque'''
     # s.read(n) leerá n bytes desde el stream
     # versión - 4 bytes, little endian, interpretalo como int
     versión = little_endian_a_int(s.read(4))
     # bloque_previo - 32 bytes, little endian (usa [::-1] para darle la vuelta)
     bloque_previo = s.read(32)[::-1]
     # raíz_merkle - 32 bytes, little endian (usa [::-1] para darle la vuelta)
     raíz_merkle = s.read(32)[::-1]
     # timestamp - 4 bytes, little endian, interpret as int
     timestamp = little_endian_a_int(s.read(4))
     # bits - 4 bytes
     bits = s.read(4)
     # nonce - 4 bytes
     nonce = s.read(4)
     # inicializa la clase
     return cls(versión, bloque_previo, raíz_merkle, timestamp, bits, nonce)
 def comprobar_pow(self):
     '''Devuelve si este bloque satisface la prueba de trabajo'''
     # obtén el doble_sha256 de la serialización de este bloque
     sha = doble_sha256(self.serializar())
     # interpreta este hash como un número little-endian
     prueba = little_endian_a_int(sha)
     # devuelve si este entero es menos que el target
     return prueba < self.target()
 def parsear(cls, s):
     '''Toma un byte stream y parsea el tx_input al comienzo
     devuelve un objeto TxIn
     '''
     # s.read(n) devolverá n bytes
     # tx_previa es 32 bytes, little endian
     tx_previa = s.read(32)[::-1]
     # indice_previo es 4 bytes, little endian, interpreta como int
     indice_previo = little_endian_a_int(s.read(4))
     # script_sig es un campo variable (longitud seguida de los datos)
     # obtén la longitud usando read_varint(s)
     script_sig_longitud = read_varint(s)
     script_sig = s.read(script_sig_longitud)
     # sequence es 4 bytes, little-endian, interprétalo como int
     sequence = little_endian_a_int(s.read(4))
     # devuelve una instancia de la clase (cls(...))
     return cls(tx_previa, indice_previo, script_sig, sequence)
Exemple #8
0
 def parsear(cls, s):
     '''Toma un stream de bytes y parsea el tx_input al comienzo
     devuelve un objeto TxIn
     '''
     # s.read(n) devolverá n bytes
     # prev_tx es 32 bytes, little endian
     prev_tx = s.read(32)[::-1]
     # prev_index es 4 bytes, little endian, interprétalo como int
     prev_index = little_endian_a_int(s.read(4))
     # script_sig es un campo variable (longitud seguida de los datos)
     # obtén la longitud usando read_varint(s)
     script_sig_longitud = read_varint(s)
     script_sig = s.read(script_sig_longitud)
     # sequence tiene 4 bytes, little-endian, interprétalo como int
     sequence = little_endian_a_int(s.read(4))
     # devuelve una instancia de la clase (cls(...))
     return cls(prev_tx, prev_index, script_sig, sequence)
 def comprobar_pow(self):
     '''Devuelve si este Bloque satisface la prueba de trabajo'''
     # obtén el doble_sha256 de la serialización de este Bloque
     sha = doble_sha256(self.serializar())
     # interpreta este hash como un número little-endian
     prueba = little_endian_a_int(sha)
     # return whether this integer is less than the target
     return prueba < self.target()
 def target(self):
     '''Devuelve el target de la prueba-de-trabajo basado en los bits'''
     # el últiom byte es el exponentee
     exponente = self.bits[-1]
     # los primeros 3 bytes son el coeficiente en little endian
     coeficiente = little_endian_a_int(self.bits[:-1])
     # la fórmula es:
     # coeficiente * 256**(exponente-3)
     return coeficiente * 256**(exponente - 3)
Exemple #11
0
 def target(self):
     '''Devuelve el objetivo de la prueba de trabajo basándose en los bits'''
     # el último byte es el exponente
     exponente = self.bits[-1]
     # los primeros 3 bytes son el coeficiente en little endian
     coeficiente = little_endian_a_int(self.bits[:-1])
     # la fórmula es:
     # coeficiente * 256**(exponente-3)
     return coeficiente * 256**(exponente - 3)
Exemple #12
0
 def parsear(cls, s):
     '''Toma un stream de bytes y parsea el tx_output al comienzo
     devuelve un objeto TxOut
     '''
     # s.read(n) devolverá n bytes
     # cantidad es 8 bytes, little endian, interpretalo como entero
     cantidad = little_endian_a_int(s.read(8))
     # script_pubkey es un campo variable (la longitud seguida de los datos)
     # puedes usar Script.parsear para obtener el script real
     script_pubkey = Script.parsear(s)
     # devolverá una instancia de la clase (cls(...))
     return cls(cantidad, script_pubkey)
Exemple #13
0
 def parsear(cls, s):
     '''Toma un stream de bytes y parsea el tx_output al comienzo
     devuelve un objeto TxOut
     '''
     # s.read(n) devolverá n bytes
     # la cantidad es 8 bytes, little endian, interprétalo como int
     cantidad = little_endian_a_int(s.read(8))
     # script_pubkey es un campo variable (la longitud seguida de la fecha)
     # obtén la longitud usando read_varint(s)
     script_pubkey_longitud = read_varint(s)
     script_pubkey = s.read(script_pubkey_longitud)
     # devuelve una instancia de la clase (cls(...))
     return cls(cantidad, script_pubkey)
Exemple #14
0
 def altura_coinbase(self):
     '''Devuelve la altura del bloque en que está transacción coinbase está
     Devuelve None si esta transacción no es coinbase
     '''
     # si no es una transacción coinbase, devuelve None
     if not self.es_coinbase():
         return None
     # obtén el primer input
     primer_input = self.tx_ins[0]
     # obtén el primer elemento del script_sig (.script_sig.cosas[0])
     primer_elemento = primer_input.script_sig.cosas[0]
     # convierte el primer elemento desde little endian a int
     return little_endian_a_int(primer_elemento)
Exemple #15
0
 def parsear(cls, s, testnet=False):
     '''Toma un stream de bytes y parsea la transacción al comienzo
     devuelve un objeto Tx
     '''
     # s.read(n) devolverá n bytes
     # la versión tiene 4 bytes, little-endian, interprétalo como int
     versión = little_endian_a_int(s.read(4))
     # num_inputs es un varint, usa read_varint(s)
     num_inputs = read_varint(s)
     # cada input necesita parseo
     inputs = []
     for _ in range(num_inputs):
         inputs.append(TxIn.parsear(s))
     # num_outputs es un varint, usa read_varint(s)
     num_outputs = read_varint(s)
     # cada output necesita parseo
     outputs = []
     for _ in range(num_outputs):
         outputs.append(TxOut.parsear(s))
     # locktime es 4 bytes, little-endian
     locktime = little_endian_a_int(s.read(4))
     # devuelve una instancia de la clase (cls(...))
     return cls(versión, inputs, outputs, locktime, testnet=testnet)
Exemple #16
0
 def parsear(cls, s):
     '''Toma un stream de bytes y parsea la transacción al principio
     devuelve un objeto Tx
     '''
     # s.read(n) devolverá n bytes
     # la version tiene 4 bytes, little-endian, interprétalo como int
     version = little_endian_a_int(s.read(4))
     # num_inputs es un varint, usa read_varint(s)
     num_inputs = read_varint(s)
     # cada input necesita parseo
     inputs = []
     for _ in range(num_inputs):
         inputs.append(TxIn.parsear(s))
     # num_outputs es un varint, usa read_varint(s)
     num_outputs = read_varint(s)
     # cada output necesita ser parseado
     outputs = []
     for _ in range(num_outputs):
         outputs.append(TxOut.parsear(s))
     # locktime is 4 bytes, little-endian
     locktime = little_endian_a_int(s.read(4))
     # return an instance of the class (cls(...))
     return cls(version, inputs, outputs, locktime)