世界円周率の日のための OKX の秘密鍵パズル賞品を解読する方法 (完全なコード付き)

作成日:: 2023-03-14 23:25:45, 更新日:: 2024-11-29 18:57:29
comments   6
hits   1558

世界円周率の日のための OKX の秘密鍵パズル賞品を解読する方法 (完全なコード付き)

隣の専門家グループでOKXが世界円周率の日謎解きイベントを開催しているのを見ました。テーマは次のとおりです。

世界円周率の日のための OKX の秘密鍵パズル賞品を解読する方法 (完全なコード付き)

上級プログラマーの私は、そのニュースを見て口角が少し上がり、何も言わずにMacBook Proを開いて作業を始めました。

分析する

当局は、円周率と重なる部分には61ビットの鍵があると述べた。周知のとおり、秘密鍵の長さは32バイトで、16進数に換算すると64ビットに0xプレフィックスが加わる。合計66ビット、61ビットはすでに存在しています。一見すると、図の最初の行の「0X」は明らかに円周率ではなく、秘密鍵のプレフィックスです。次に、5桁の数字(0123456789ABCDEF)があります。これらの文字をランダムに並べます。ブルートフォース実行には問題がないので、始めましょう

Macの内蔵ツールを使って、シャープネスや色調整を簡単に行えます

世界円周率の日のための OKX の秘密鍵パズル賞品を解読する方法 (完全なコード付き)

こんな感じです。Mac は画像上の文字を自動的に認識できます。直接コピーしてみましょう。

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

これは絶対に使えません。手動で修正しましょう。画像に隠れている未確認のものを*いいえ、わかりません。後で教えます 画像に遮られているものは、他のフォントのストロークの形状を観察することで判断できます。このとき、Pythonを使用して2つの違いを計算します。同じものが使用されます_‘は、異なる

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))

実行結果は次のとおりです。

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

不確かな数字が 3 つ余分にあります。それを取り除いて試してみましょう。それを取り除いた後、残りの 61 桁はすべて正しいからです。 最も確実な違いだけが保持され、最終的な接頭辞は次のようになります

0X1DA69425E13DB04099ED428B32D22990EFC3F937317D9E7A37BEEA92744

次に、Pythonを使用してOKチェーンの残高を激しく登り、どの秘密鍵に残高があるかを比較する必要があります。実際には、最初に314USDT転送の公開鍵を選択することもできます。これはより高速です。公式サイトによるとガスは残っています。残高を直接確認してください。コードが乱雑です。

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()
    

1048576 回走査する必要があることがわかります。マルチスレッドを使用すると、はるかに高速になります。私のサーバーの 1 つで実行してください。

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
以下省略......

ワクワクしながら待ってます〜〜~~、残念なことに、戦略が終了する前に結果はありません。表示されるのはすべて「なし」です

突然の出来事

そんなはずはない。私には理解できなかった。Twitterでみんなの議論を読み始めたところ、みんなが私と同じような手順を踏んでいることがわかった。しかし奇妙なことに、誰も復号化が成功したとは言っていなかった。 、公式からはまだ発表されていませんでした。正しい最初の61桁。このとき、真ん中に違いがあったため、奇妙な返信が目に留まりました。D2299異論はないと思いますが、彼は非常に自信があるようにも見えます。

世界円周率の日のための OKX の秘密鍵パズル賞品を解読する方法 (完全なコード付き)

しかし、この人が教えてくれた61桁目はD2290です。彼はまた、慎重に調べたとも言っていました。それは問題ではありません。運試しをしてみましょう。どうせ電気の無駄です。

世界円周率の日のための OKX の秘密鍵パズル賞品を解読する方法 (完全なコード付き)

頑張って探してみると、61人を見つけたというメッセージを残した人が何人かいて、みんなとても自信があるようでした。

世界円周率の日のための OKX の秘密鍵パズル賞品を解読する方法 (完全なコード付き)

コメントエリアで見つかったプレフィックスをすべて収集し、以前のコードでトラバースしました。基本的なコードはあまり変わっていないので、再度貼り付けません。

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

実は新しいコメントが増えています。ある兄弟のPI値が私と違います。すごいですね。 まずはこれを実行してみましょう。信じられないくらいです。実際に動作します。これは、上記のプレフィックスの 1 つが正しいことを意味します。これは科学的ではありません。秘密鍵は次のとおりです。

1DA69425E13DB04099ED428B32D2290EFC3F9373177D9E7A37BEEA92744C8155

彼のは D229 ですが、写真では明らかに D2299 で、731 の後に 7 がありますが、彼のは 2 つあります。 しかし、正しい61桁であることが判明しました。彼がどのように計算したのかはわかりません。非常に興味がありますが、自分の操作を疑っていません。コメントで、公式カスタマーサービスが別のものがあると言っていたのを見ました円周率のバージョン。私は無知です。人類が学んだ知識と現在の宇宙の理解によれば、無理数円周率は宇宙の無限大を表すことができ、その小数部は決して繰り返されたり終わったりすることはありません。あなたがいる宇宙の UUID。他のバージョンがある場合は、おそらくパラレルワールドからのバージョンです。

これは、別のビッグブラザーが疑問を表明した後のカスタマーサービスの応答です。

世界円周率の日のための OKX の秘密鍵パズル賞品を解読する方法 (完全なコード付き)

それは知識の増加です。

Web3 コイン転送コード

最後に、ボーナスを転送するためのコードです。今回はFMZプラットフォームのWeb3機能を直接使用しました。チェーンアドレスをOKCに設定するだけです。取引所に秘密鍵を追加するときは、とにかく問題ありません。 2行でできます。デバッガーモードで実行します

世界円周率の日のための OKX の秘密鍵パズル賞品を解読する方法 (完全なコード付き)

証明する

クラックされた公開鍵アドレス

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

リンクを表示: https://www.okx.com/cn/explorer/okc/address/0x0bd08825e05e540c9508961a32e58d14da47275a

取り除いた後の TX: https://www.okx.com/cn/explorer/okc/tx/0x4211418b09571011417257201aaf10fc3c5d638809a9456eb5aba5fe8c5d4e2c

受信者のアドレスは

0x25f0a126be95f437ee71d7c4de725567c5f6c731

世界円周率の日のための OKX の秘密鍵パズル賞品を解読する方法 (完全なコード付き)

このアドレスが私のものであることを証明するために、受信者のアドレスを使用してブラックホールアドレスに送金しました。

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

ブラックホールのアドレスは 0x0000000000000000005757572e464d5a2e434f4d

このブラックホールアドレスにはURLが含まれており、デコードすると

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

あとがき

これで終わりです。振り返ってみると、長年の知識の蓄積に感謝しています。そうでなければ、クラッキングの速度はそれほど速くなく、他の人が私より先に進んでいたでしょう。 公式の図には間違いがあるはずです。いずれにしても、公開される前に答えを解明できたのは幸運でした。次回 OKX が同様のイベントを開催するときは、より厳格に実施されることを期待します。