def serializar(self): '''Devuelve una serialización en bytes del input de la transacción''' # serializar tx_previa, little endian res = self.tx_previa[::-1] # serializa indice_previo, 4 bytes, little endian res += int_a_little_endian(self.indice_previo, 4) # serializa el script_sig res += self.script_sig.serializar() # serializa sequence, 4 bytes, little endian res += int_a_little_endian(self.sequence, 4) return res
def filtrocarga(self, flag=1): '''Devuelve la carga que va en un mensaje filtrocarga''' # comienza con el tamaño del filtro en bytes carga = codificar_varint(self.tamaño) # luego súmale el filtro a bytes carga += self.filtro_bytes() # la función contador es 4 bytes little endian carga += int_a_little_endian(self.función_contador, 4) # ajuste is 4 bytes little endian carga += int_a_little_endian(self.ajuste, 4) # flag es 1 byte little endian carga += int_a_little_endian(flag, 1) return carga
def serializar(self): '''Serializa este mensaje para enviarlo a la red''' # versión es 4 bytes little endian res = int_a_little_endian(self.versión, 4) # servicios tiene 8 bytes little endian res += int_a_little_endian(self.servicios, 8) # timestamp es 8 bytes little endian res += int_a_little_endian(self.timestamp, 8) # servicios receptor son 8 bytes little endian res += int_a_little_endian(self.servicios_receptor, 8) # IPV4 es 10 00 bytes y 2 ff bytes después ip receptor res += b'\x00' * 10 + b'\xff\xff' + self.ip_receptor # puerto receptor son 2 bytes, little endian debería ser 0 res += int_a_little_endian(self.puerto_receptor, 2) # servicios emisor son 8 bytes little endian res += int_a_little_endian(self.servicios_emisor, 8) # IPV4 son los bytes 10 00 y 2 ff bytes luego ip emisor res += b'\x00' * 10 + b'\xff\xff' + self.ip_emisor # puerto emisor son 2 bytes, little endian debería ser 0 res += int_a_little_endian(self.puerto_emisor, 2) # nonce deberían ser 8 bytes res += self.nonce # agente usuario es una cadena variable, así que varint primero res += codificar_varint(len(self.agente_usuario)) res += self.agente_usuario # el último bloque son 4 bytes little endian res += int_a_little_endian(self.último_bloque, 4) # retransmisión es 00 si es falso, 01 si es verdadero if self.retransmisión: res += b'\x01' else: res += b'\x00' return res
def serializar(self): '''Devuelve la cabecera del bloque de 80''' # versión - 4 bytes, little endian res = int_a_little_endian(self.versión, 4) # bloque_previo - 32 bytes, little endian res += self.bloque_previo[::-1] # raíz_merkle - 32 bytes, little endian res += self.raíz_merkle[::-1] # timestamp - 4 bytes, little endian res += int_a_little_endian(self.timestamp, 4) # bits - 4 bytes res += self.bits # nonce - 4 bytes res += self.nonce return res
def serializar(self): '''Devuelve la serialización en bytes del input de la transacción''' # serializa tx_previa, little endian res = self.tx_previa[::-1] # serializa indice_previo, 4 bytes, little endian res += int_a_little_endian(self.indice_previo, 4) # ten el scriptSig preparado (usa self.script_sig.serializar()) script_sig_bruto = self.script_sig.serializar() # haz encode_varint en la longitud del scriptSig res += encode_varint(len(script_sig_bruto)) # añade el scriptSig res += script_sig_bruto # serializa sequence, 4 bytes, little endian res += int_a_little_endian(self.sequence, 4) return res
def __init__(self, versión=70015, servicios=0, timestamp=None, servicios_receptor=0, ip_receptor=b'\x00\x00\x00\x00', puerto_receptor=8333, servicios_emisor=0, ip_emisor=b'\x00\x00\x00\x00', puerto_emisor=8333, nonce=None, agente_usuario=b'/programmingbloquechain:0.1/', último_bloque=0, retransmisión=True): self.versión = versión self.servicios = servicios if timestamp is None: self.timestamp = int(time.time()) else: self.timestamp = timestamp self.servicios_receptor = servicios_receptor self.ip_receptor = ip_receptor self.puerto_receptor = puerto_receptor self.servicios_emisor = servicios_emisor self.ip_emisor = ip_emisor self.puerto_emisor = puerto_emisor if nonce is None: self.nonce = int_a_little_endian(randint(0, 2**64), 8) else: self.nonce = nonce self.agente_usuario = agente_usuario self.último_bloque = último_bloque self.retransmisión = retransmisión
def serializar(self): '''Devuelve la serialización en bytes del output de la transacción''' # serializa cantidad, 8 bytes, little endian res = int_a_little_endian(self.cantidad, 8) # serializa el script_pubkey res += self.script_pubkey.serializar() return res
def sig_hash(self, indice_input, tipo_hash): '''Devuelve la representación entera del hash que necesitas firmar para el índice indice_input''' # crea una nueva serie de tx_ins (alt_tx_ins) alt_tx_ins = [] # itera sobre self.tx_ins for tx_in in self.tx_ins: # crea un nuevo TxIn que tenga un script_sig (b'') en blanco y añáde a alt_tx_ins alt_tx_ins.append( TxIn( tx_previa=tx_in.tx_previa, indice_previo=tx_in.indice_previo, script_sig=Script([]), sequence=tx_in.sequence, )) # obtén el input en el indice_input input_firmante = alt_tx_ins[indice_input] # obtén el script_pubkey del input script_pubkey = input_firmante.script_pubkey(self.testnet) # el script_sig del input_firmante debería ser script_pubkey input_firmante.script_sig = script_pubkey # crea una transacción alternativa con las tx_ins modificadas alt_tx = self.__class__(versión=self.versión, tx_ins=alt_tx_ins, tx_outs=self.tx_outs, locktime=self.locktime) # añade el tipo_hash entero 4 bytes, little endian res = alt_tx.serializar() + int_a_little_endian(tipo_hash, 4) # obtén el doble_sha256 de la serialización de la tx s256 = doble_sha256(res) # convierte esto a un entero big-endian usando int.from_bytes(x, 'big') return int.from_bytes(s256, 'big')
def sig_hash(self, índice_input, tipo_hash): '''Devuelve la representación entera del hash que debe ser firmado para índice índice_input''' # crea una nueva serie de tx_ins (alt_tx_ins) alt_tx_ins = [] # itera sobre self.tx_ins for tx_in in self.tx_ins: # crea una nueva TxIn que tenga un script_sig en blanco (b'') y añádela a alt_tx_ins alt_tx_ins.append(TxIn( tx_previa=tx_in.tx_previa, índice_previo=tx_in.índice_previo, script_sig=Script([]), sequence=tx_in.sequence, )) # grab the input at the índice_input firmaring_input = alt_tx_ins[índice_input] # grab the script_pubkey of the input script_pubkey = firmaring_input.script_pubkey(self.testnet) # the script_sig of the firmaring_input should be script_pubkey firmaring_input.script_sig = script_pubkey # create an alternate transaction with the modified tx_ins alt_tx = self.__class__( versión=self.versión, tx_ins=alt_tx_ins, tx_outs=self.tx_outs, locktime=self.locktime) # añade el tipo_hash int 4 bytes, little endian res = alt_tx.serializar() + int_a_little_endian(tipo_hash, 4) # obtén el doble_sha256 de la serializacón de la tx s256 = doble_sha256(res) # convierte esto a big-endian entero usando int.from_bytes(x, 'big') return int.from_bytes(s256, 'big')
def serializar(self): # comienza con el número de cosas como un varint res = codificar_varint(len(self.data)) for tipo_datos, identificador in self.data: # tipo de datos es 4 bytes little endian res += int_a_little_endian(tipo_datos, 4) # identificador necesita estar en little endian res += identificador[::-1] return res
def serializar(self): '''Devuelve la serialización en bytes de la transacción''' # serializa versión (4 bytes, little endian) res = int_a_little_endian(self.versión, 4) # codificar_varint en el número de inputs res += codificar_varint(len(self.tx_ins)) # itera los inputs for tx_in in self.tx_ins: # serializa cada input res += tx_in.serializar() # codificar_varint sobre el número de outputs res += codificar_varint(len(self.tx_outs)) # itera outputs for tx_out in self.tx_outs: # serializa cada output res += tx_out.serializar() # serializa locktime (4 bytes, little endian) res += int_a_little_endian(self.locktime, 4) return res
def serializar(self): '''Serializa este mensaje para enviarlo a la red''' # la versión del protocolo es 4 bytes little-endian res = int_a_little_endian(self.versión, 4) # el número de hashes es un varint res += codificar_varint(self.num_hashes) # el bloque inicial es en little-endian res += self.bloque_inicial[::-1] # el bloque final es también en little-endian res += self.bloque_final[::-1] return res
def serializar(self): '''Devuelve la serialización en bytes del output de la transacción''' # serializa la cantidad, 8 bytes, little endian res = int_a_little_endian(self.cantidad, 8) # get the scriptPubkey ready (use self.script_pubkey.serializar()) script_pubkey_bruto = self.script_pubkey.serializar() # usa encode_varint sobre la longitud del scriptPubkey res += encode_varint(len(script_pubkey_bruto)) # añade el scriptPubKey res += script_pubkey_bruto return res
def serializar(self): # inicializa lo que enviaremos de vuelta res = b'' # ve a través de cada cosa for cosa in self.cosas: # si la cosa es un entero, es un op code if type(cosa) == int: # convierte la cosa en un único byte entero usando int_a_little_endian res += int_a_little_endian(cosa, 1) else: # en otro caso, esto es un elemento # obtén la longitud en bytes longitud = len(cosa) # convierte la longitud en un único byte entero usando int_a_little_endian prefijo = int_a_little_endian(longitud, 1) # añade al resultado tanto la longitud como la cosa res += prefijo + cosa # obtén la longitud de todo total = len(res) # codificar_varint la longitud total de res y anteponlo return codificar_varint(total) + res
def serializar(self): '''Devuelve la serialización en bytes del mensaje de red completo''' # añade la magia de red res = self.magia # comando 12 bytes # rellénalo con 0's res += self.comando + b'\x00' * (12 - len(self.comando)) # la longitud de carga son 4 bytes, little endian res += int_a_little_endian(len(self.carga), 4) # checksum 4 bytes, los primeros cuatro de doble_sha256 de carga res += doble_sha256(self.carga)[:4] # carga res += self.carga return res