Información de contexto
Estoy creando una aplicación que requiere la capacidad de consultar cualquier nodo completo de bitcoin (desde un script de python usando sockets tcp sin procesar) para leer el valor OP_Return que figura en la siguiente transacción ( https://live.blockcypher.com/btc- testnet/tx/2599dbe540a583ede3512fef9a0f26be718c039ffd4d04d85ff3b339f40e73b1/ )
Lo que he hecho hasta la fecha
Logré establecer con éxito la versión + verack, sin embargo, me enfrenté a dos problemas.
getdata
para la transacción necesaria, Idit no devuelve el resultado. Identifiqué que esto se debe a que mis suposiciones iniciales de que getdata devuelve los datos necesarios eran incorrectas y, en cambio, solo devolverá datos de transacciones para las transacciones que aún están en mempool.Esto me llevó a mi problema principal, esperaba replicar la descarga del bloque inicial en mi secuencia de comandos de python, comenzando desde el bloque que contiene la transacción que me interesa. Sin embargo, cuando lo hago / no importa lo que parezca poner en getblocks
el getheaders
hash filter obtengo un volcado de 500 (o 2000) bloques/encabezados. A continuación se muestra un volcado hexadecimal de las solicitudes que estoy realizando (solo el marco del protocolo bitcoin):
getblocks 0b110907676574626c6f636b00000000450000002a0af9950100000001000000000000592589e55cda6e8a093998e8356ea770d4aaeb7c0f5439b147d7000000000000017a09017d52db538d7a9ddcc48311866d7e5fdbbbec7d0faad5
getheaders 0b110907676574686561646572730000450000002a0af9950100000001000000000000592589e55cda6e8a093998e8356ea770d4aaeb7c0f5439b147d7000000000000017a09017d52db538d7a9ddcc48311866d7e5fdbbbec7d0faad5
Busco la siguiente ayuda:
getdata
mensaje?EDITAR (5/4/20) El requisito implícito que no quedó claro aquí fue que necesitábamos hacerlo de manera descentralizada utilizando la API RPC de blockchain o equivalente.
No veo ningún punto final para obtener la transacción completa en la documentación de la API Blockcypher, así que utilicé la API blockstream.info:
>https://blockstream.info/testnet/api/tx/2599dbe540a583ede3512fef9a0f26be718c039ffd4d04d85ff3b339f40e73b1
{
"txid":"2599dbe540a583ede3512fef9a0f26be718c039ffd4d04d85ff3b339f40e73b1",
"version":2,
"locktime":0,
"vin":[
{
"txid":"382bda6ee2bac22afd051104af16146436895ecca382a76c2d66535a837254bc",
"vout":1,
"prevout":{
"scriptpubkey":"00144ecdb2867150ff16c7d6e3258adca9ed8bac3ac1",
"scriptpubkey_asm":"OP_0 OP_PUSHBYTES_20 4ecdb2867150ff16c7d6e3258adca9ed8bac3ac1",
"scriptpubkey_type":"v0_p2wpkh",
"scriptpubkey_address":"tb1qfmxm9pn32rl3d37kuvjc4h9fak96cwkpjyyjmk",
"value":2948920
},
"scriptsig":"",
"scriptsig_asm":"",
"witness":[
"304402205e9b17758d1daf2a501a1fabe06bdbf15adaadfcf6ff80c4cfb34176bd988c0c02207450185bde5c20e06270b3b7e681e0042072c6af25fc10c62430df0f04ec5bf201",
"023532fa6b866f37729719a3615ef3a776407048989736ac2b7fafa5678a519df3"
],
"is_coinbase":false,
"sequence":4294967295
}
],
"vout":[
{
"scriptpubkey":"6a0e3132372e302e302e313a38313831",
"scriptpubkey_asm":"OP_RETURN OP_PUSHBYTES_14 3132372e302e302e313a38313831",
"scriptpubkey_type":"op_return",
"value":0
},
{
"scriptpubkey":"a914171f697fe358f7d7238b6128930bb1fa7363b44d87",
"scriptpubkey_asm":"OP_HASH160 OP_PUSHBYTES_20 171f697fe358f7d7238b6128930bb1fa7363b44d OP_EQUAL",
"scriptpubkey_type":"p2sh",
"scriptpubkey_address":"2MuMVAFK2gbTDNVBhLtpZfA4Xi62mWh6bU5",
"value":948920
},
{
"scriptpubkey":"0014af8abd63a00c40ad75e47870b1b0a1ddb2ba7e66",
"scriptpubkey_asm":"OP_0 OP_PUSHBYTES_20 af8abd63a00c40ad75e47870b1b0a1ddb2ba7e66",
"scriptpubkey_type":"v0_p2wpkh",
"scriptpubkey_address":"tb1q479t6caqp3q26a0y0pctrv9pmket5lnx24twcx",
"value":1500000
}
],
"size":248,
"weight":665,
"fee":500000,
"status":{
"confirmed":true,
"block_height":1612110,
"block_hash":"000000000000592589e55cda6e8a093998e8356ea770d4aaeb7c0f5439b147d7",
"block_time":1576024567
}
}
Puede ver aquí que la primera salida tiene los datos 3132372e302e302e313a38313831
, cuya decodificación a caracteres ASCII parece una URL local:
hex = '3132372e302e302e313a38313831'
decoded = binascii.unhexlify(hex).decode('ascii')
print(decoded)
Huellas dactilares:127.0.0.1:8181
EDITAR:
Para obtener la transacción que le interesa sin usar ninguna API externa, deberá ejecutar un nodo de bitcoin completo con la txindex=1
opción. Si su billetera rastrea esta transacción, un nodo podado sería suficiente. Luego puede obtener la información sobre la transacción con este comando:
>bitcoin-cli getrawtransaction 2599dbe540a583ede3512fef9a0f26be718c039ffd4d04d85ff3b339f40e73b1 true
Debería obtener algo muy similar a la respuesta de la API de Blockstream que pegué arriba
El protocolo p2p de bitcoin no permite realizar búsquedas de transacciones directamente de esta manera. Tal vez un poco de filtrado de floración minimizaría la huella, pero aún es relativamente complejo de implementar.
Los servidores Electrum son quizás la siguiente mejor opción: admiten las búsquedas que desea, pero están menos descentralizados, y si su aplicación está haciendo cosas malas, podrían confabularse y manipular solo sus resultados.
¿Cómo obtengo mi respuesta de bloque o encabezados para que solo contenga 1 elemento inv en lugar de 500/5000?
No creo que pueda limitar los resultados de los encabezados (debe conocer todos los encabezados para hacerlo) Pero una vez que tenga la cadena de encabezados, puede enviar un localizador de bloques con inicio: HASH (n) fin: HASH (n + 1) y puedes descargar un solo bloque.
Vuelva a filtrar, si encuentra nodos con el bit BLOOM_SERVICE, puede decirles su filtro, y los datos del bloque solo contienen sus txs y los falsos positivos permitidos por su filtro.
Resultó que el problema principal con el código anterior era que el endianness en python estaba por defecto en mi carga útil hexadecimal mezclada. Simplemente necesitaba corregir el orden de la carga útil. El código correcto se puede ver aquí: https://github.com/dummytree/blockchain-botnet-poc/blob/master/MalwareManager.py#L284-L299
claris
dimitree
claris
dimitree
pieter wuille
dimitree
dimitree