Git Commitのハッシュ値の前n桁を0にするProof of Workツールです。
指定されたコミットハッシュに対して、コミットメッセージの末尾にnonceを追加することで、新しいコミットハッシュの前n桁が0になるまで計算を繰り返します。
git-pow <COMMIT_SHA> [OPTIONS]<COMMIT_SHA>: 対象となるコミットのSHA-1ハッシュ値
--difficulty <NUMBER>: 前何桁を0にするか(デフォルト: 7)--initial-nonce <NUMBER>: 初期nonce値(デフォルト: 0)
# HEADコミットの前7桁を0にする
git-pow $(git rev-parse HEAD)
# 前5桁を0にする
git-pow $(git rev-parse HEAD) --difficulty 5
# 初期nonce値を指定
git-pow $(git rev-parse HEAD) --initial-nonce 1000000コマンドは新しいコミットハッシュを標準出力に出力します:
$ git-pow $(git rev-parse HEAD) 2>/dev/null
0000000fd579756514831a4b58a7b978b9f1205現在のHEADを新しいコミットに更新するには、reset, rebase --onto, update-refなどのGitコマンドを使用します:
git reset --hard $(git-pow $(git rev-parse HEAD))コミットハッシュの探索は、コミットメッセージの末尾にnonce値を16進数形式で追加することで行います。
- 指定されたコミットハッシュからGit Objectを読み込む
- コミットメッセージの末尾にnonce値(16桁の16進数)を追加
- 新しいコミットオブジェクトのSHA-1ハッシュを計算
- ハッシュの前n桁が0になるまで、nonce値をインクリメントして繰り返す
--difficultyオプションで指定された値に基づいて、ハッシュの前何桁を0にするかが決まります:
- 指定されたコミットハッシュから
.git/objects/ディレクトリのオブジェクトファイルを読み込む - zlibで圧縮されたGit Objectを解凍・パース
- コミットメッセージの末尾にnonce値を追加してオブジェクトサイズを更新
- SHA-1ハッシュを計算し、難易度条件を満たすまで繰り返す
- 条件を満たすハッシュが見つかったら、新しいコミットオブジェクトを
.git/objects/に保存
- ハッシュ計算の速度のためRustを採用
- SHA-1ハッシュ計算には sha1 クレートを使用
- zlibの解凍には flate2 を使用
- CLIの実装には clap を使用(derive機能付き)
- テストには proptest を使用
- packファイルは対象外
- GPG署名は対象外
Git Objectの全体構造:
object = header + content
header = ASCII("<type> <size>") + NUL(0x00)
type = "commit"
size = contentのバイト数をASCII 10進で表したもの
content = commit本文
commit本文の構造:
content = headers + "\n" + message
headers = 1行以上のheaderLineの連結(各行末は"\n")
message = 任意のバイト列(通常UTF-8テキスト)
このツールではsizeとmessageのみを変更します。