11
Seguir
503
Seguidores

Cómo resolver el rompecabezas de clave privada de OKX para el Día Mundial de Pi (con código completo)

Creado el: 2023-03-14 23:25:45, Actualizado el: 2024-11-29 18:57:29
comments   6
hits   1558

Cómo resolver el rompecabezas de clave privada de OKX para el Día Mundial de Pi (con código completo)

Vi en el grupo de expertos de al lado que OKX está organizando un evento de resolución de misterios del Día Mundial Pi, el tema es el siguiente

Cómo resolver el rompecabezas de clave privada de OKX para el Día Mundial de Pi (con código completo)

Como programador senior, después de ver las noticias, las comisuras de mi boca se levantaron ligeramente, abrí mi MacBook Pro y comencé a trabajar sin decir nada.

analizar

Los funcionarios dicen que hay 61 bits de la clave en la parte de la imagen que se superpone con pi. Como todos sabemos, la longitud de la clave privada es de 32 bytes, que se convierte a hexadecimal, que son 64 bits más el prefijo 0x. , un total de 66 bits, 61 bits ya están ahí. A primera vista, el “0X” en la primera línea de la imagen obviamente no es pi, sino el prefijo de la clave privada. Luego hay 5 dígitos (0123456789ABCDEF) de Disposición aleatoria de estos caracteres. No hay problema con la ejecución por fuerza bruta, así que comencemos.

Utilice las herramientas integradas de Mac para enfocar y ajustar el color de manera sencilla.

Cómo resolver el rompecabezas de clave privada de OKX para el Día Mundial de Pi (con código completo)

Parece que es así. Mac puede reconocer automáticamente los caracteres de la imagen. Vamos a copiarlos directamente:

3.141592653589793230X1D64338
А694502884197169399375105820
974925E123078164062862089986
28033DB034211706409914808651
32823066470ED424609550582231
8B3
81284
•探索,
038
永无止境
027
493
05%
0128
4756482337867831731712019091
47D9E56692346034861045432664
8213393607743749141273724587
006606315588174881BEEA209628
2925409192744436789259036001

Esto definitivamente no se puede usar. Vamos a corregirlo manualmente. Los que están bloqueados por la imagen y no están confirmados están marcados como*No, no estoy segura, te lo diré más tarde. Los demás que están bloqueados por la imagen se pueden juzgar observando la forma del trazo de otras fuentes. En este momento, usamos Python para calcular la diferencia entre los dos. Se utiliza el mismo_’ significa que sólo diferentes

img = '''
3.141592653589793230X1D64338
A694502884197169399375105820
974925E123078164062862089986
28033DB034211706409914808651
32823066470ED424609550582231
8B32594081284811174502841027
0193**2*D2299964462294895493
0381960EFC8103F9365933446128
4756482337867831731712019091
47D9E56692346034861045432664
82133936077A3749141273724587
006606315588174881BEEA209628
2925409192744436789259036001
'''
# 真实圆周率
real='''
3.14159265358979323846264338
3279502884197169399375105820
9749445923078164062862089986
2803482534211706798214808651
3282306647093844609550582231
7253594081284811174502841027
0193852110555964462294895493
0381964428810975665933446128
4756482337867831652712019091
4564856692346034861045432664
8213393607260249141273724587
0066063155881748815209209628
2925409171536436789259036001
'''

items = img.strip().split('\n')
diffStr = ''
for pos, line in enumerate(real.strip().split('\n')):
    for i, c in enumerate(line):
        imgLine = list(items[pos])
        if line[i] == imgLine[i]:
            imgLine[i] = '_'
        else:
            diffStr += imgLine[i]
        items[pos] = ''.join(imgLine)
print('\n'.join(items))
print(diffStr, 'Len:', len(diffStr))

Los resultados de la ejecución son los siguientes:

___________________0X1D_____
A694________________________
____25E1____________________
____3DB0________4099________
___________ED42_____________
8B32________________________
____**_*D2299_______________
______0EFC___3F93___________
________________731_________
_7D9E_______________________
__________7A37______________
__________________BEEA______
________92744_______________
0X1DA69425E13DB04099ED428B32***D22990EFC3F937317D9E7A37BEEA92744 Len: 64

Hay 3 dígitos adicionales que son inciertos. Elimínelos y pruebe. Porque después de eliminarlos, los otros 61 dígitos son todos correctos. Solo se conservan las diferencias más ciertas y el prefijo final es el siguiente

0X1DA69425E13DB04099ED428B32D22990EFC3F937317D9E7A37BEEA92744

A continuación, todavía tenemos que usar Python para escalar violentamente el saldo en la cadena OK y comparar qué clave privada tiene el saldo. De hecho, también puede seleccionar primero la clave pública con transferencia 314USDT, que es más rápida. Según el sitio web oficial , queda gas. Solo revisa el saldo directamente. El código es confuso.

import sys
import web3,time,logging
from eth_account import Account
from web3 import Web3
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(message)s')
w3 = Web3(Web3.HTTPProvider("https://exchainrpc.okex.org"))
logging.info(w3.clientVersion)
found = None

def get_balance_gas(key):
    global found
    _counter += 1
    address = Account.from_key(key).address
    logging.info('fetch address %s %s' % (found, address))
    while True:
        try:
            balance = w3.eth.get_balance(address)
            break
        except:
            logging.warning(traceback.format_exc())
            time.sleep(1)
            continue
    if balance != 0:
        found = key
        raise BaseException('Found balance: %s %s' % (address, balance))
    return balance

from concurrent.futures import ThreadPoolExecutor
executor = ThreadPoolExecutor(max_workers=50)
keys = []
prefix = '1DA69425E13DB04099ED428B32D22990EFC3F937317D9E7A37BEEA92744'
# 无所谓优化算法了, 争分夺秒跑密钥
ch = '0123456789ABCDEF'
for a in range(0, 16):
    for b in range(0, 16):
        for c in range(0, 16):
            for d in range(0, 16):
                for e in range(0, 16):
                    keys.append("0x"+prefix+ch[a]+ch[b]+ch[c]+ch[d]+ch[e])
print('all keys:', len(keys))
tasks = [None for t in keys]
for idx, key in enumerate(keys):
    tasks[idx] = executor.submit(get_balance_gas, key)
for t in tasks:
    t.result()
    

Puedes ver que se debe recorrer 1048576 veces. Usar subprocesos múltiples es mucho más rápido. Ejecútalo en uno de mis servidores.

2023-03-15 00:20:19,491 exchain-v1.6.8.5
all keys: 1048576
2023-03-15 00:20:20,372 fetch address None 0xc20C41f06F2428a0FD84ef03Ec6960992F5f8016
2023-03-15 00:20:20,473 fetch address None 0xcFa87ee54bc1c14c09a3AB3f41640bBab5C5480a
2023-03-15 00:20:20,483 fetch address None 0x126E922652f8B276F231D0eCA94d98685a26a45D
以下省略......

Esperando ansiosamente~~~~, malas noticias, no hay ningún resultado antes de que salga la estrategia, todo lo que se muestra es Ninguno

Un giro repentino de los acontecimientos

No debería ser así. No pude entenderlo. Empecé a leer las discusiones de todos en Twitter y descubrí que todos habían seguido pasos similares a los míos. Pero lo extraño fue que nadie había dicho que el descifrado se hubiera realizado correctamente. , y el oficial aún no lo había anunciado. Los primeros 61 dígitos correctos. En ese momento, una respuesta extraña me llamó la atención porque había una diferencia en el medio.D2299No hay ninguna objeción, estoy seguro, pero también parece muy confiado.

Cómo resolver el rompecabezas de clave privada de OKX para el Día Mundial de Pi (con código completo)

Pero el dígito 61 que dio esta persona es D2290. También dijo que lo había comprobado cuidadosamente. No importa. Probemos suerte. De todos modos, es un desperdicio de electricidad.

Cómo resolver el rompecabezas de clave privada de OKX para el Día Mundial de Pi (con código completo)

Con actitud de prueba, encontré a varias otras personas que dejaron mensajes diciendo que habían encontrado a 61 personas, y todos parecían muy confiados.

Cómo resolver el rompecabezas de clave privada de OKX para el Día Mundial de Pi (con código completo)

Recopilé todos los prefijos que encontré en el área de comentarios y los recorrí con el código anterior. El código básico no ha cambiado mucho, por lo que no lo pegaré nuevamente.

prefixs =[
'1DA69425E13DB04099ED428B3202290EFC3F9317317D9E7A37BEEA92744',
'1DA69425E13DB04099ED428B32D2290EFC3F9373177D9E7A37BEEA92744',
'1DA69425E13DB04099ED428B320D2290EFC3F937317D9E7A37BEEA92744',
'1DA694255E3DB040990ED428B3208890EFC3F937317D9E7A37BEEA92744',
'1DA69425E13DB04099ED428B3202299EFC3F9317317D9E7A37BEEA92744',
'1DA69425E13DB01099ED428B3202290EFC3F9317317D9E7A37BEEA92744',
'1DA69425E13DB04099ED428B32D2290EFC3F9317317D9E7A37BEEA92744',
'1DA69425E13DB04099ED428B32D22990EFC3F937317D9E7A37BEEA92744',
]

De hecho, hay más comentarios nuevos. El valor PI de un hermano es diferente al mío. Es sorprendente. Ejecutemos esto primero. No puedo creer lo que veo. Realmente funciona. Esto significa que uno de los prefijos anteriores es correcto. Esto no es científico. La clave privada es:

1DA69425E13DB04099ED428B32D2290EFC3F9373177D9E7A37BEEA92744C8155

El suyo es D229, pero la imagen muestra claramente D2299, y hay un 7 después de 731, pero tiene dos. Pero resultó que eran los 61 dígitos correctos. No sé cómo lo calculó. Tengo mucha curiosidad, pero no dudo de mi operación. Vi en los comentarios que el servicio de atención al cliente oficial dijo que hay otra versión. de pi. Soy ignorante. El conocimiento aprendido y la comprensión actual del universo por parte de los humanos, el número irracional pi puede representar el infinito del universo, y su parte decimal nunca se repetirá ni terminará. Puedes pensar en él como el UUID del universo en el que estás. Si hay otras versiones, tal vez de un mundo paralelo.

Esta es la respuesta del servicio de atención al cliente luego de que otro hermano mayor expresara dudas:

Cómo resolver el rompecabezas de clave privada de OKX para el Día Mundial de Pi (con código completo)

Es un aumento de conocimiento.

Código de transferencia de monedas Web3

Finalmente, aquí está el código para transferir el bono. Esta vez usé directamente la función Web3 de la plataforma FMZ. Simplemente establecí la dirección de la cadena en OKC. Al agregar la clave privada al intercambio, de todos modos no importa. Entonces Puedo hacerlo en dos líneas. Ejecutar en modo depurador.

Cómo resolver el rompecabezas de clave privada de OKX para el Día Mundial de Pi (con código completo)

probar

Dirección de clave pública descifrada

>>> from eth_account import Account
>>> Account.from_key('0x1DA69425E13DB04099ED428B32D2290EFC3F9373177D9E7A37BEEA92744C8155').address
'0x0bd08825e05e540C9508961a32E58D14da47275A'

Ver enlace: https://www.okx.com/cn/explorer/okc/address/0x0bd08825e05e540c9508961a32e58d14da47275a

TX después de que me lo quité: https://www.okx.com/cn/explorer/okc/tx/0x4211418b09571011417257201aaf10fc3c5d638809a9456eb5aba5fe8c5d4e2c

Puedes ver que la dirección del destinatario es

0x25f0a126be95f437ee71d7c4de725567c5f6c731

Cómo resolver el rompecabezas de clave privada de OKX para el Día Mundial de Pi (con código completo)

Para demostrar que esta dirección es mía, utilicé la dirección del destinatario para transferir dinero a una dirección de agujero negro.

https://www.okx.com/cn/explorer/okc/tx/0xc32b5e299064456af3eb67c34a3b153f74a1bd18a31429052e3e3c5614bcdb6e

La dirección del agujero negro es 0x0000000000000000005757572e464d5a2e434f4d

Esta dirección de agujero negro contiene una URL que, después de decodificarla, es

~ % python -c 'print(bytes.fromhex("0000000000000000005757572e464d5a2e434f4d"))'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00WWW.FMZ.COM'

Epílogo

Este es el final. Al mirar atrás, me siento agradecido por el conocimiento que he acumulado a lo largo de los años. De lo contrario, la velocidad de desarrollo no sería tan rápida y otros se me habrían adelantado. Estoy seguro de que hay un error en el diagrama oficial. De todos modos, tengo suerte de haber descifrado la respuesta antes de que se hiciera pública. Espero que OKX sea más riguroso la próxima vez que celebre un evento similar.