いつか役に立つかもしれないchatGPTを使ったシードフレーズクラックbot
はじめに
はじめまして。タルミケイです。BCGにお金を入れながら、勝てば投資、負ければゲームと言い張って勝率100%をキープしています。
本記事は仮想通貨botter Advent Calendar 2023シリーズ2の8日目に掲載させてもらっています。
普段はあまりbotを組んだりしないんですが、面白そうなイベントがあった時にbotで参戦することがあります。今回はつい先日行われたGasHeroというBCGのシードフレーズクラックイベントについてです。
イベント概要
GasHeroはSTEPNの運営がつくっているゲームで、バブルへの期待からアセットがバブってきています。
イベントの景品は、30,000GMT(120万円)とかで取引されているGenesisHeroのクーポン。運営が出したヒントをもとに、12単語のシードフレーズを当て、景品が入っているウォレットからGenesisHeroを盗み出せ!というもの。豪華すぎる。
ちなみにヒントはこんな感じで詩的。言語の壁がキツイ。
これを手動で攻略していくのは無理ゲーなので、botやらAIやらに頼ろうという流れになります。
botとAIにやらせよう
普通にやろうとすると、ヒントから予想される英単語を12個並べて、ウォレットを復元できるかどうかトライ→もしできたらヒーローが入っているかチェック!という流れ。しかし、言語の壁が立ち塞がる我々は、ここにChatGPTという一手間が入るかと思います。
とてもじゃないけど面倒なのでbotにやらせようということになります。手動を自動化させるだけなので、こんな感じ。
ヒントから連想されるワードをchatGPTに選んでもらう。
単語を12個選んで並べる
シードフレーズからアドレスを復元
アドレスにヒーローが入っているかチェック
実装とか
シードフレーズはBIP39という2048語の単語から選ばれます。単語リストはここからゲットできます。いつか役に立つかもしれない知識ですね。
運営が出す詩的なヒントだけでは誰も答えられないので、しばらく待っていると文字数と頭文字が追加のヒントとして出てきます。単語リストを読み込んで、文字数と頭文字が一致する単語の配列を返すコードをつくります。
def get_words_list(n, x=''):
# nが文字数、xが頭文字
file_path = '/content/english.txt'
with open(file_path, 'r') as file:
# ファイルの内容を行ごとに読み込む
lines = file.readlines()
# 各行の単語を""で囲む
words_list = ['{}'.format(word.strip()) for word in lines]
return [word for word in words_list if len(word) == n and word.startswith(x)]
次は文字数と頭文字が一致する単語配列をchatGPTになげて、詩的ヒントに関連する単語に絞り込んでもらいます。
# APIkeyを読み込ませる
client = OpenAI(
api_key = "YOUR_API_KEY"
)
# 単語リストを取得し、chatGPTに単語を絞り込んでもらう
def find_associated_words(hint, n, x=''):
# 単語リストの取得
words_list = get_words_list(n, x)
# ChatGPTに送る質問を作成
prompt = f"以下のワードリストの中から、「{hint}」から連想されるワードを選択して文字列の配列として出力してください。{words_list}"
# ChatGPT APIを使用してレスポンスを取得
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}],
)
# レスポンスから関連する単語を抽出して返す
return response.choices[0].message.content
例えば、ヒントが「Magnetic extremities」、4文字で頭文字がpと引数を設定してchatGPTに聞くと正解の「pole」が返ってきました!いい感じですね。
次はシードフレーズの復元部分です。シードフレーズからのアドレス復元はeth_keysを使うとできます。これもいつか使うかもしれない知識。
def restore_wallet_from_seed(seed_phrase):
# シードフレーズからプライベートキーを生成
priv_key = eth_keys.keys.PrivateKey(eth_keys.datatypes.keccak(seed_phrase.encode()))
# プライベートキーからアカウントを生成
account = Account.from_key(priv_key)
return account.address
アドレスにヒーローが入っているかどうかのチェックは、PolygonscanのAPIを使ってもできるんですが、アドレス生成のたびにAPI叩いてると遅いので、先にホルダーリストを取得しておいて、生成されたアドレスが含まれているか、リストを参照するのが早いです。
ホルダーリストの取得もAPIでやってもいいんですが、時間勝負のイベントだったのでPolygonscanからcsvをダウンロードしました。
def check_seed_phrese(seed_phrese):
# シードフレーズからアドレスを作成
address = restore_wallet_from_seed(seed_phrese).lower()
# address = '0x1632075bd0e0012c9f5386cb14eecc9b8b837957'
# アドレスがホルダーリストに含まれているかをチェック
if address in holders['HolderAddress'].values:
return True
else:
return False
シードフレーズ作成の候補をつくります。自分で絞り込んだところは自分で、怪しいところはchatGPTに聞くスタイル。
words_list = [
["eye"],
["rail"],
find_associated_words("Magnetic extremities.", n=4, x='p'),
["concert", "theater"],
["trek", "hike"],
["journey", "mystery", "explore"],
find_associated_words("Jungle's silent stalker", n=6, x='j'),
["october"],
["ivory"],
["food"],
["taxi"],
["multiply"]
]
最後に全ての組み合わせを試しながら、生成したアドレスがリストにあったら歓喜の叫びと共にシードフレーズが出力される仕様です。
def generate_seed_phrases(words_list):
# すべての組み合わせを生成
for combination in product(*words_list):
seed_phrase = ' '.join(combination)
try:
if check_seed_phrese(seed_phrase):
print('GHC holder!!!!!!!!', seed_phrase)
yield seed_phrase
except Exception as e:
print(e)
continue
def main():
for phrase in generate_seed_phrases(words_list):
continue
main()
おわりに
残念ながらGHC holder!!!!!!!の叫びを見ることはありませんでしたが、chatGPTとかを使いながら急ごしらえのbotで戦うのは楽しかったです。トレーディングbotとは違ってリスクないってのもナイスだと思います。
似たようなイベントが今後ないとも限らないので、いつか役に立つかもしれないbotとして紹介させていただきました。chatGPTを使ってるあたりも面白さとして感じていただけたら嬉しいです。
bot作ってないからエッジのポロリはないけどフォローはこちら。
この記事が気に入ったらサポートをしてみませんか?