<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ブロックチェーン | PathLog</title>
	<atom:link href="https://pathlog.jp/tag/%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%83%81%E3%82%A7%E3%83%BC%E3%83%B3/feed/" rel="self" type="application/rss+xml" />
	<link>https://pathlog.jp</link>
	<description>A Log of Computing and Learning</description>
	<lastBuildDate>Mon, 09 Feb 2026 08:13:02 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>

<image>
	<url>https://pathlog.jp/wp-content/uploads/2025/07/cropped-blogfab2-32x32.png</url>
	<title>ブロックチェーン | PathLog</title>
	<link>https://pathlog.jp</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>自作PoWブロックチェーンでdifficultyとattemptsを実験する</title>
		<link>https://pathlog.jp/2026/02/03/%e8%87%aa%e4%bd%9cpow%e3%83%96%e3%83%ad%e3%83%83%e3%82%af%e3%83%81%e3%82%a7%e3%83%bc%e3%83%b3%e3%81%a7difficulty%e3%81%a8attempts%e3%82%92%e5%ae%9f%e9%a8%93%e3%81%99%e3%82%8b/</link>
					<comments>https://pathlog.jp/2026/02/03/%e8%87%aa%e4%bd%9cpow%e3%83%96%e3%83%ad%e3%83%83%e3%82%af%e3%83%81%e3%82%a7%e3%83%bc%e3%83%b3%e3%81%a7difficulty%e3%81%a8attempts%e3%82%92%e5%ae%9f%e9%a8%93%e3%81%99%e3%82%8b/#respond</comments>
		
		<dc:creator><![CDATA[Ryo]]></dc:creator>
		<pubDate>Tue, 03 Feb 2026 14:42:15 +0000</pubDate>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Learning Notes (JP)]]></category>
		<category><![CDATA[Blockchain]]></category>
		<category><![CDATA[PoW]]></category>
		<category><![CDATA[コーディング]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[ブロックチェーン]]></category>
		<category><![CDATA[研究]]></category>
		<guid isPermaLink="false">https://pathlog.jp/?p=290</guid>

					<description><![CDATA[前回、PoWを入れたブロックチェーンの簡易モデルを作成しました。 今回はそれを使って、difficulty（先頭の0の個数）とattempts（ナンスの生成 …]]></description>
										<content:encoded><![CDATA[
<p>前回、PoWを入れたブロックチェーンの簡易モデルを作成しました。</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-pathlog wp-block-embed-pathlog"><div class="wp-block-embed__wrapper">
		<div class="ystdb-card is-horizon" >
			<div class="ystdb-card__container is-horizon has-image-align-">
									<figure class="ystdb-card__image is-fit is-size--normal">
						<img fetchpriority="high" decoding="async" width="800" height="450" src="https://pathlog.jp/wp-content/uploads/2026/02/blockchain2-1024x576.jpg" class="attachment-large size-large wp-post-image" alt="PoWを使った簡易ブロックチェーンをpythonで実装" srcset="https://pathlog.jp/wp-content/uploads/2026/02/blockchain2-1024x576.jpg 1024w, https://pathlog.jp/wp-content/uploads/2026/02/blockchain2-300x169.jpg 300w, https://pathlog.jp/wp-content/uploads/2026/02/blockchain2-768x432.jpg 768w, https://pathlog.jp/wp-content/uploads/2026/02/blockchain2-1536x864.jpg 1536w, https://pathlog.jp/wp-content/uploads/2026/02/blockchain2-2048x1152.jpg 2048w" sizes="(max-width: 800px) 100vw, 800px" />					</figure>
								<div class="ystdb-card__text">
					<div class="ystdb-card__title">
						<a class="ystdb-card__link" href="https://pathlog.jp/2026/02/03/pow%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%9f%e7%b0%a1%e6%98%93%e3%83%96%e3%83%ad%e3%83%83%e3%82%af%e3%83%81%e3%82%a7%e3%83%bc%e3%83%b3%e3%82%92python%e3%81%a7%e5%ae%9f%e8%a3%85/">PoWを使った簡易ブロックチェーンをpythonで実装</a>
					</div>
											<div class="ystdb-card__dscr">
							前回は非常にシンプルな、２つのブロックをハッシュ値でつなぐブロックチェーンを作りました。Pythonのクラスやインスタンス（オブジェクト指向）の復習にもなるので&hellip;						</div>
																<div class="ystdb-card__domain">pathlog.jp</div>
									</div>
			</div>
		</div>
		
</div></figure>



<p>今回はそれを使って、difficulty（先頭の0の個数）とattempts（ナンスの生成回数）の関係を調べていきたいと思います。</p>



<h1 class="wp-block-heading">使用するコード</h1>



<p>使用するコードは以下のものです。</p>



<pre class="wp-block-code"><code>import hashlib
import time

class Block:
    def __init__(self, data, previous_hash, nonce, hash, timestamp):
        self.data = data
        self.previous_hash = previous_hash
        self.nonce = nonce
        self.hash = hash
        self.time = timestamp

    def calculate_hash(self):
        content = self.data + self.previous_hash + str(self.nonce) + str(self.time)
        hash = hashlib.sha256(content.encode()).hexdigest()
        return hash
    
    
class Blockchain:
    def __init__(self):
        self.chain = &#091;]
        self.difficulty = int(input("Difficulty: "))
        self.max_block = int(input("Number of blocks: "))
        print(f"\n--------------------\n")

        self.total_attempts = 0　#合計試行回数の変数
        genesis_block = self.create_genesis_block()
        self.chain.append(genesis_block)
        for i in range(1, self.max_block + 1):
            self.add_block(f"block {i}")
        


    def hash_block(self, data, previous_hash, nonce, timestamp):
        content = data + previous_hash + str(nonce) + str(timestamp)
        hash = hashlib.sha256(content.encode()).hexdigest()
        return hash

    def create_genesis_block(self):
        genesis = self.mine_block("genesis", "0")
        return Block("genesis", "0", genesis&#091;"nonce"], genesis&#091;"hash"], genesis&#091;"timestamp"])
    
    def mine_block(self, data, previous_hash):
        nonce = 0
        attempts = 0
        target = '0' * self.difficulty
        start_time = time.time()
        timestamp = time.time()
        while True: 
            attempts += 1
            self.total_attempts += 1 #合計試行回数をインクリメント
            block_hash = self.hash_block(data, previous_hash, nonce, timestamp)
            if block_hash.startswith(target):
                break
            nonce += 1
        
        end_time = time.time()
        elapsed_time = end_time - start_time

        result = {
            "nonce": nonce,
            "hash": block_hash,
            "timestamp":  timestamp,
            "elapsed_time": elapsed_time,
            "attempts": attempts
        }
        return result        

    
    def add_block(self, data):
        previous_hash = self.chain&#091;-1].hash
        mine_result = self.mine_block(data, previous_hash)
        block_number = len(self.chain)
        nonce = mine_result&#091;"nonce"]
        hash = mine_result&#091;"hash"]
        timestamp = mine_result&#091;"timestamp"]
        elapsed_time = mine_result&#091;"elapsed_time"]
        attempts = mine_result&#091;"attempts"]
        new_block = Block(data, previous_hash, nonce, hash, timestamp)
        self.chain.append(new_block)

        print(f"&#091;Block {block_number} mined]\ndata: {data}\nnonce: {nonce}\nhash: {hash}\ntimestamp: {time.ctime(timestamp)}\ntime: {elapsed_time}\nattempts: {attempts}\n")
        print(f"--------------------\n")

    def is_chain_valid(self):
        for i in range(1, len(self.chain)):
            current_block = self.chain&#091;i]#現在のBlock
            previous_block = self.chain&#091;i-1]#一つ前のBlock
            if current_block.previous_hash == previous_block.hash:

                if (previous_block.time &lt;= current_block.time) and (current_block.time &lt;= previous_block.time + 100):
                    
                    if current_block.hash == current_block.calculate_hash():
                        target = '0' * self.difficulty

                        if current_block.calculate_hash().startswith(target):
                            continue
                        else:
                             return False
                    else:
                        return False
                else:
                    return False
            else:
                return False
        return True
            
bc = Blockchain()
print("total attempts:", bc.total_attempts)
print("initial chain valid?:", bc.is_chain_valid())</code></pre>



<p>ハッシュ値の最初に並ぶ0の個数が多いほど難しいので、それをdifficultyとしてinputします。<br>また、生成するブロックの個数もinputで入力します。</p>



<p>そうするとPoWを使ってブロックが作成されて、結果が表示されます。<br>difficultyが5なら、hash: 0000081857826e8f8c5e⋯という感じです。</p>



<p>詳しくは前回の記事をご覧ください。</p>



<p>今回見るのは、最後のtotal attempts: 〇〇の部分です。</p>



<h1 class="wp-block-heading">仮説</h1>



<p>attemptsの回数は、difficultyに対して指数関数的に増加する。</p>



<p>SHA-256は2進数に基づいているので、2のn乗で増えていくのではないか。</p>



<h1 class="wp-block-heading">検証</h1>



<h2 class="wp-block-heading">具体的な方法</h2>



<p>number of blocks を100で固定、difficultyを1,2,3,4,5に変えて、それぞれ五回ずつ試行します。<br>その100ブロックの生成にかかったトータルのナンス試行回数を記録していきます。</p>



<p>それぞれ実行すると、以下のような画面になります。</p>



<figure class="wp-block-video"><video height="784" style="aspect-ratio: 1002 / 784;" width="1002" controls src="https://pathlog.jp/wp-content/uploads/2026/02/a19c5637346d6fe30112c2398c452b76.mov"></video><figcaption class="wp-element-caption">difficultyが4のとき</figcaption></figure>



<p>difficultyが4のときは割と一瞬ですが、それが5になると明らかに遅くなるのがわかります↓。</p>



<figure class="wp-block-video"><video height="784" style="aspect-ratio: 1002 / 784;" width="1002" controls src="https://pathlog.jp/wp-content/uploads/2026/02/389bf00193aea9395fcd5a08a0162c03.mov"></video><figcaption class="wp-element-caption">difficultyが5のとき</figcaption></figure>



<h2 class="wp-block-heading">実行結果</h2>



<p>これをそれぞれ5回ずつ試行した結果は以下のようになりました。</p>



<figure class="wp-block-table alignwide"><table><tbody><tr><td></td><td class="has-text-align-center" data-align="center">1回目</td><td class="has-text-align-center" data-align="center">2回目</td><td class="has-text-align-center" data-align="center">3回目</td><td class="has-text-align-center" data-align="center">4回目</td><td class="has-text-align-center" data-align="center">5回目</td><td class="has-text-align-center" data-align="center">合計</td><td class="has-text-align-center" data-align="center">平均</td></tr><tr><td class="has-text-align-center" data-align="center">difficulty: 1</td><td class="has-text-align-right" data-align="right">1429</td><td class="has-text-align-right" data-align="right">1653</td><td class="has-text-align-right" data-align="right">1345</td><td class="has-text-align-right" data-align="right">1649</td><td class="has-text-align-right" data-align="right">1933</td><td class="has-text-align-right" data-align="right">8009</td><td class="has-text-align-right" data-align="right">1601.8</td></tr><tr><td class="has-text-align-center" data-align="center">difficulty: 2</td><td class="has-text-align-right" data-align="right">19793</td><td class="has-text-align-right" data-align="right">25012</td><td class="has-text-align-right" data-align="right">28280</td><td class="has-text-align-right" data-align="right">26274</td><td class="has-text-align-right" data-align="right">24055</td><td class="has-text-align-right" data-align="right">123414</td><td class="has-text-align-right" data-align="right">24682.8</td></tr><tr><td class="has-text-align-center" data-align="center">difficulty: 3</td><td class="has-text-align-right" data-align="right">454264</td><td class="has-text-align-right" data-align="right">392845</td><td class="has-text-align-right" data-align="right">436734</td><td class="has-text-align-right" data-align="right">405510</td><td class="has-text-align-right" data-align="right">387373</td><td class="has-text-align-right" data-align="right">2076726</td><td class="has-text-align-right" data-align="right">415345.2</td></tr><tr><td class="has-text-align-center" data-align="center">difficulty: 4</td><td class="has-text-align-right" data-align="right">7489576</td><td class="has-text-align-right" data-align="right">5879442</td><td class="has-text-align-right" data-align="right">6768334</td><td class="has-text-align-right" data-align="right">6350231</td><td class="has-text-align-right" data-align="right">6003080</td><td class="has-text-align-right" data-align="right">32490663</td><td class="has-text-align-right" data-align="right">6498132.6</td></tr><tr><td class="has-text-align-center" data-align="center">difficulty: 5</td><td class="has-text-align-right" data-align="right">116463528</td><td class="has-text-align-right" data-align="right">116373275</td><td class="has-text-align-right" data-align="right">110700796</td><td class="has-text-align-right" data-align="right">104932554</td><td class="has-text-align-right" data-align="right">105451373</td><td class="has-text-align-right" data-align="right">553921526</td><td class="has-text-align-right" data-align="right">110784305.2</td></tr></tbody></table></figure>



<p>このうち、平均のナンス試行回数のみを見てみます。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">difficulty</td><td class="has-text-align-center" data-align="center">平均</td></tr><tr><td class="has-text-align-center" data-align="center">difficulty: 1</td><td class="has-text-align-right" data-align="right"><strong>1601.8</strong></td></tr><tr><td class="has-text-align-center" data-align="center">difficulty: 2</td><td class="has-text-align-right" data-align="right"><strong>24682.8</strong></td></tr><tr><td class="has-text-align-center" data-align="center">difficulty: 3</td><td class="has-text-align-right" data-align="right"><strong>415345.2</strong></td></tr><tr><td class="has-text-align-center" data-align="center">difficulty: 4</td><td class="has-text-align-right" data-align="right"><strong>6498132.6</strong></td></tr><tr><td class="has-text-align-center" data-align="center">difficulty: 5</td><td class="has-text-align-right" data-align="right"><strong>110784305.2</strong></td></tr></tbody></table></figure>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="630" src="https://pathlog.jp/wp-content/uploads/2026/02/a55d27568054fa94f7b3a0c69ce8608c-1024x630.png" alt="" class="wp-image-298" srcset="https://pathlog.jp/wp-content/uploads/2026/02/a55d27568054fa94f7b3a0c69ce8608c-1024x630.png 1024w, https://pathlog.jp/wp-content/uploads/2026/02/a55d27568054fa94f7b3a0c69ce8608c-300x185.png 300w, https://pathlog.jp/wp-content/uploads/2026/02/a55d27568054fa94f7b3a0c69ce8608c-768x473.png 768w, https://pathlog.jp/wp-content/uploads/2026/02/a55d27568054fa94f7b3a0c69ce8608c.png 1492w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">考察</h2>



<p>上の結果を見ると、difficultyが1増えるごとに、試行回数が<strong>約16倍</strong>になっていることがわかります。</p>



<p>difficulty1のときの値が約1600であることを考えると、</p>



<p>1のとき100*16^1<br>2のとき100*16^2<br>3のとき100*16^3<br>4のとき100*16^4<br>5のとき100*16^5</p>



<p>に近い値が出ていることがわかります。</p>



<p>これらの値と、今回測定した値を比較してみます</p>



<figure class="wp-block-table alignwide"><table><tbody><tr><td class="has-text-align-center" data-align="center">difficulty</td><td class="has-text-align-center" data-align="center">予想</td><td class="has-text-align-center" data-align="center">実測値</td><td class="has-text-align-center" data-align="center">理論値</td><td class="has-text-align-center" data-align="center">差</td><td class="has-text-align-center" data-align="center">相対誤差(%)</td></tr><tr><td class="has-text-align-center" data-align="center">difficulty: 1</td><td class="has-text-align-right" data-align="right">100*16^1</td><td class="has-text-align-right" data-align="right">1601.8</td><td class="has-text-align-right" data-align="right">1600</td><td class="has-text-align-right" data-align="right">1.8</td><td class="has-text-align-right" data-align="right"><strong>0.1125</strong></td></tr><tr><td class="has-text-align-center" data-align="center">difficulty: 2</td><td class="has-text-align-right" data-align="right">100*16^2</td><td class="has-text-align-right" data-align="right">24682.8</td><td class="has-text-align-right" data-align="right">25600</td><td class="has-text-align-right" data-align="right">-917.2</td><td class="has-text-align-right" data-align="right"><strong>3.5828125</strong></td></tr><tr><td class="has-text-align-center" data-align="center">difficulty: 3</td><td class="has-text-align-right" data-align="right">100*16^3</td><td class="has-text-align-right" data-align="right">415345.2</td><td class="has-text-align-right" data-align="right">409600</td><td class="has-text-align-right" data-align="right">5745.2</td><td class="has-text-align-right" data-align="right"><strong>1.402636719</strong></td></tr><tr><td class="has-text-align-center" data-align="center">difficulty: 4</td><td class="has-text-align-right" data-align="right">100*16^4</td><td class="has-text-align-right" data-align="right">6498132.6</td><td class="has-text-align-right" data-align="right">6553600</td><td class="has-text-align-right" data-align="right">-55467.4</td><td class="has-text-align-right" data-align="right"><strong>0.8463653564</strong></td></tr><tr><td class="has-text-align-center" data-align="center">difficulty: 5</td><td class="has-text-align-right" data-align="right">100*16^5</td><td class="has-text-align-right" data-align="right">110784305.2</td><td class="has-text-align-right" data-align="right">104857600</td><td class="has-text-align-right" data-align="right">5926705.2</td><td class="has-text-align-right" data-align="right"><strong>5.65214653</strong></td></tr></tbody></table></figure>



<p>誤差は一番多いdifficulty5のときでも6%に収まっています。</p>



<p>と、それぞれ5回しか試行していないにも関わらず、かなりの精度の値が出てきました。</p>



<h2 class="wp-block-heading">こうなる理由</h2>



<p>このような結果になる理由として、SHA-256の仕組みと、今回のPoWの条件が関係しています。</p>



<hr class="wp-block-separator has-text-color has-ys-gray-color has-alpha-channel-opacity has-ys-gray-background-color has-background"/>



<p>今回用いたSHA-256は16進数で表記されています。</p>



<pre class="wp-block-code"><code>0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f</code></pre>



<p>の16種類が用いられます。</p>



<p>ですから、文字は16通りからランダムに選ばれるといえるでしょう。</p>



<p></p>



<p>difficultyをnに設定するとき、それは、ハッシュ値の先頭に0がn個並ぶということです。</p>



<p>一桁目が0になる確率は、1/16です。<br>よって、先頭n桁が0になる確率は、(1/16)^nということになります。</p>



<p>0を1個ふやすごとに、確率が1/16倍になるので、計算の手間は16倍になるのです。</p>



<p></p>



<hr class="wp-block-separator has-text-color has-ys-gray-color has-alpha-channel-opacity has-ys-gray-background-color has-background"/>



<p>今回の実験では、ブロックの作成個数が100だったので、</p>



<p>1ブロックあたりの期待試行回数：16^difficulty<br>ブロック数：100</p>



<p>なので、理論的な総試行回数は：</p>



<pre class="wp-block-code"><code>100 × 16^difficulty</code></pre>



<p>となります。</p>



<p>したがって、logスケールで見れば、ほぼ一直線に並んでいることが確認できます。</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img decoding="async" width="1024" height="634" src="https://pathlog.jp/wp-content/uploads/2026/02/d9dc3b32f3bfa68f84071534944aac10-1024x634.png" alt="" class="wp-image-314" srcset="https://pathlog.jp/wp-content/uploads/2026/02/d9dc3b32f3bfa68f84071534944aac10-1024x634.png 1024w, https://pathlog.jp/wp-content/uploads/2026/02/d9dc3b32f3bfa68f84071534944aac10-300x186.png 300w, https://pathlog.jp/wp-content/uploads/2026/02/d9dc3b32f3bfa68f84071534944aac10-768x475.png 768w, https://pathlog.jp/wp-content/uploads/2026/02/d9dc3b32f3bfa68f84071534944aac10.png 1496w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p>対数スケールでは指数関数的な増加は直線としてグラフに現れます。<br>このグラフからわかるのは、attemptsがdifficultyに対して指数関数的に増加しているということです。</p>



<p>実測値がこの値に非常に近いのは、PoW が単純な確率試行の繰り返しであることと、<br>ブロック数を100とったことで十分に平均化できたためです。</p>



<h2 class="wp-block-heading">なぜ多少の誤差が出るのか</h2>



<p>誤差が生じる理由は以下の通りです。</p>



<p>PoWは本質的に確率過程<br>試行回数が大きくなるほど分散も大きくなる</p>



<p>特に<strong>difficultyが高くなるにつれて、一部のブロックで極端に早く成功するまたは逆に非常に遅くなるブロックが出るということが発生します。</strong></p>



<p>つまり値の揺らぎが出るのです。</p>



<p>それでも difficulty = 5 で誤差が6%未満に収まっているのは、<br>100ブロック×5試行というサンプル数が十分に大きいためだと考えられます。</p>



<p>足りないかと思っていましたが、以外にもいい結果になりました。</p>



<hr class="wp-block-separator has-text-color has-ys-gray-color has-alpha-channel-opacity has-ys-gray-background-color has-background"/>



<p>仮説では、2のn乗で増えていくのではないかと異なる予想していました。無意識にbitで考えていた勘違いでした。</p>



<p>SHA-256は内部的には<strong>2進数</strong>で動作していますが、今回difficultyの判定に使っているのは<strong>16進表記の文字列</strong>です。</p>



<p>もし先頭のn個のビットが0かという基準で判定していた場合、2^nになりますが、今回は先頭 n hex digitが0かなので、</p>



<pre class="wp-block-code"><code>16^n = (2^4)^n = 2^(4n)</code></pre>



<p>という増加になります。</p>



<p>この違いは、<strong>difficultyの定義の仕方の違い</strong>によるものです。</p>



<h1 class="wp-block-heading">まとめ</h1>



<p>今回の検証により、PoW における attempts は確率試行の結果であり、difficultyを 1 増やすごとに期待試行回数は約16倍になることを確認することができました。</p>



<p>実測値は理論値と高い精度で一致し、自作モデルでも PoW の本質的性質が確認できました。</p>



<p>今後の展望として、nonceをランダムにしたり、生成時間を調べたり、チェーンが長い方を採用する仕組みなどを入れたりして、パワーアップさせていきたいと思います。</p>



<p>ご覧いただきありがとうございました。</p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://pathlog.jp/2026/02/03/%e8%87%aa%e4%bd%9cpow%e3%83%96%e3%83%ad%e3%83%83%e3%82%af%e3%83%81%e3%82%a7%e3%83%bc%e3%83%b3%e3%81%a7difficulty%e3%81%a8attempts%e3%82%92%e5%ae%9f%e9%a8%93%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		<enclosure url="https://pathlog.jp/wp-content/uploads/2026/02/a19c5637346d6fe30112c2398c452b76.mov" length="0" type="video/quicktime" />
<enclosure url="https://pathlog.jp/wp-content/uploads/2026/02/389bf00193aea9395fcd5a08a0162c03.mov" length="0" type="video/quicktime" />

			</item>
		<item>
		<title>PoWを使った簡易ブロックチェーンをpythonで実装</title>
		<link>https://pathlog.jp/2026/02/03/pow%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%9f%e7%b0%a1%e6%98%93%e3%83%96%e3%83%ad%e3%83%83%e3%82%af%e3%83%81%e3%82%a7%e3%83%bc%e3%83%b3%e3%82%92python%e3%81%a7%e5%ae%9f%e8%a3%85/</link>
					<comments>https://pathlog.jp/2026/02/03/pow%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%9f%e7%b0%a1%e6%98%93%e3%83%96%e3%83%ad%e3%83%83%e3%82%af%e3%83%81%e3%82%a7%e3%83%bc%e3%83%b3%e3%82%92python%e3%81%a7%e5%ae%9f%e8%a3%85/#respond</comments>
		
		<dc:creator><![CDATA[Ryo]]></dc:creator>
		<pubDate>Tue, 03 Feb 2026 01:24:54 +0000</pubDate>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Learning Notes (JP)]]></category>
		<category><![CDATA[Blockchain]]></category>
		<category><![CDATA[コーディング]]></category>
		<category><![CDATA[ビットコイン]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[ブロックチェーン]]></category>
		<category><![CDATA[実装]]></category>
		<category><![CDATA[研究]]></category>
		<guid isPermaLink="false">https://pathlog.jp/?p=277</guid>

					<description><![CDATA[前回は非常にシンプルな、２つのブロックをハッシュ値でつなぐブロックチェーンを作りました。Pythonのクラスやインスタンス（オブジェクト指向）の復習にもなる …]]></description>
										<content:encoded><![CDATA[
<p>前回は非常にシンプルな、２つのブロックをハッシュ値でつなぐブロックチェーンを作りました。<br>Pythonのクラスやインスタンス（オブジェクト指向）の復習にもなるので、ぜひ見てみてください。</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-pathlog wp-block-embed-pathlog"><div class="wp-block-embed__wrapper">
		<div class="ystdb-card is-horizon" >
			<div class="ystdb-card__container is-horizon has-image-align-">
									<figure class="ystdb-card__image is-fit is-size--normal">
						<img loading="lazy" decoding="async" width="800" height="450" src="https://pathlog.jp/wp-content/uploads/2026/02/blockchain2-1024x576.jpg" class="attachment-large size-large wp-post-image" alt="ブロックチェーンをpythonで1から書いてみた" srcset="https://pathlog.jp/wp-content/uploads/2026/02/blockchain2-1024x576.jpg 1024w, https://pathlog.jp/wp-content/uploads/2026/02/blockchain2-300x169.jpg 300w, https://pathlog.jp/wp-content/uploads/2026/02/blockchain2-768x432.jpg 768w, https://pathlog.jp/wp-content/uploads/2026/02/blockchain2-1536x864.jpg 1536w, https://pathlog.jp/wp-content/uploads/2026/02/blockchain2-2048x1152.jpg 2048w" sizes="auto, (max-width: 800px) 100vw, 800px" />					</figure>
								<div class="ystdb-card__text">
					<div class="ystdb-card__title">
						<a class="ystdb-card__link" href="https://pathlog.jp/2026/02/01/%e3%83%96%e3%83%ad%e3%83%83%e3%82%af%e3%83%81%e3%82%a7%e3%83%bc%e3%83%b3%e3%82%92python%e3%81%a71%e3%81%8b%e3%82%89%e6%9b%b8%e3%81%84%e3%81%a6%e3%81%bf%e3%81%9f/">ブロックチェーンをpythonで1から書いてみた</a>
					</div>
											<div class="ystdb-card__dscr">
							最近ふと、ブロックチェーンへの興味がより一層深まってきて、自分でコードを書きたくなりました。 ブロックチェーンは何かを、文章としての説明では理解していたつもりで&hellip;						</div>
																<div class="ystdb-card__domain">pathlog.jp</div>
									</div>
			</div>
		</div>
		
</div></figure>



<p>ですが、さすがにこれだけではブロックチェーンとは呼べませんので、<strong>今回は Proof of Work（PoW）を実装し</strong>、<strong>なぜブロックの改ざんが困難になるのかをコードレベルで確認</strong>していきます。</p>



<p>また、それに伴って、マイニングやタイムスタンプ、その他もろもろ（ハッシュの難易度調整、個数調整）を追加しました。</p>



<h1 class="wp-block-heading">完成品コード</h1>



<p>以下が、今回の実装をすべて含んだ完成形のコードです。</p>



<pre class="wp-block-code"><code>import hashlib
import time

class Block:
    def __init__(self, data, previous_hash, nonce, hash, timestamp):
        self.data = data
        self.previous_hash = previous_hash
        self.nonce = nonce
        self.hash = hash
        self.time = timestamp

    def calculate_hash(self):
        content = self.data + self.previous_hash + str(self.nonce) + str(self.time)
        hash = hashlib.sha256(content.encode()).hexdigest()
        return hash
    
    
class Blockchain:
    def __init__(self):
        self.chain = &#091;]
        self.difficulty = int(input("Difficulty: "))
        self.max_block = int(input("Number of blocks: "))
        print(f"\n--------------------\n")
        genesis_block = self.create_genesis_block()
        self.chain.append(genesis_block)
        for i in range(1, self.max_block + 1):
            self.add_block(f"block {i}")
        
    #ハッシュ関数
    def hash_block(self, data, previous_hash, nonce, timestamp):
        content = data + previous_hash + str(nonce) + str(timestamp)
        hash = hashlib.sha256(content.encode()).hexdigest()
        return hash

    #ジェネシスブロックの作成
    def create_genesis_block(self):
        genesis = self.mine_block("genesis", "0")
        return Block("genesis", "0", genesis&#091;"nonce"], genesis&#091;"hash"], genesis&#091;"timestamp"])
    
    #マイニング作業
    def mine_block(self, data, previous_hash):
        nonce = 0
        attempts = 0
        target = '0' * self.difficulty
        start_time = time.time()
        timestamp = time.time()
        while True: 
            attempts += 1
            hash = self.hash_block(data, previous_hash, nonce, timestamp)
            if hash.startswith(target):
                break
            nonce += 1
        
        end_time = time.time()
        elapsed_time = end_time - start_time

        result = {
            "nonce": nonce,
            "hash": hash,
            "timestamp":  timestamp,
            "elapsed_time": elapsed_time,
            "attempts": attempts
        }
        return result        

    #２つ目以降のブロック追加
    def add_block(self, data):
        previous_hash = self.chain&#091;-1].hash
        mine_result = self.mine_block(data, previous_hash)
        block_number = len(self.chain)
        nonce = mine_result&#091;"nonce"]
        hash = mine_result&#091;"hash"]
        timestamp = mine_result&#091;"timestamp"]
        elapsed_time = mine_result&#091;"elapsed_time"]
        attempts = mine_result&#091;"attempts"]

        new_block = Block(data, previous_hash, nonce, hash, timestamp)
        self.chain.append(new_block)

        print(f"&#091;Block {block_number} mined]\ndata: {data}\nnonce: {nonce}\nhash: {hash}\ntimestamp: {time.ctime(timestamp)}\ntime: {elapsed_time}\nattempts: {attempts}\n")
        print(f"--------------------\n")


    #チェーン検証
    def is_chain_valid(self):
        for i in range(1, len(self.chain)):
            current_block = self.chain&#091;i]#現在のBlock
            previous_block = self.chain&#091;i-1]#一つ前のBlock
            if current_block.previous_hash == previous_block.hash:

                if (previous_block.time &lt;= current_block.time) and (current_block.time &lt;= previous_block.time + 100):
                    
                    if current_block.hash == current_block.calculate_hash():
                        target = '0' * self.difficulty

                        if current_block.calculate_hash().startswith(target):
                            continue
                        else:
                             return False
                    else:
                        return False
                else:
                    return False
            else:
                return False
        return True
            
bc = Blockchain()
print("initial chain valid?:", bc.is_chain_valid())</code></pre>



<p>だいぶ「ブロックチェーン」になってきたのではないでしょうか！</p>



<h1 class="wp-block-heading">解説</h1>



<p>このコードは、ざっくり見ると以下のような構成になっています。</p>



<pre class="wp-block-code"><code>class Block
    def __init__
    def calculate_hash

class Blockchain
    def __init___
    def hash_block
    def create_genesis_block
    def mine_block
    def add_block
    def is_chain_valid
</code></pre>



<p>それぞれ見ていきましょう。</p>



<p></p>



<p>とその前に、まずはハッシュ関数と、時間のライブラリをインポートします。</p>



<pre class="wp-block-code"><code>import hashlib
import time</code></pre>



<h2 class="wp-block-heading">Blockクラス</h2>



<p>このクラスで、一つのブロックのインスタンスを作成できるようにします。</p>



<p>基本的には、やっていることはシンプルで、情報の保存だけです。</p>



<p>インスタンス作成時に、引数としてデータや一つ前のブロックのハッシュ値、ナンス、自らのハッシュ値、タイムスタンプを受け取り、それらを保存します。</p>



<pre class="wp-block-code"><code>class Block:
    def __init__(self, data, previous_hash, nonce, hash, timestamp):
        self.data = data
        self.previous_hash = previous_hash
        self.nonce = nonce
        self.hash = hash
        self.time = timestamp</code></pre>



<p>それに加えて、後で楽になるので、こいつ自身にもハッシュする関数を入れておきます。</p>



<pre class="wp-block-code"><code>def calculate_hash(self):
    content = self.data + self.previous_hash + str(self.nonce) + str(self.time)
    hash = hashlib.sha256(content.encode()).hexdigest()
    return hash</code></pre>



<p>これだけになります。</p>



<p>メインはすべてBlockchainクラスに入っています。</p>



<h2 class="wp-block-heading">Blockchainクラス</h2>



<p>まず、それぞれがどのような役割を分担しているのか確認しましょう。</p>



<pre class="wp-block-code"><code>class Blockchain
    def __init___　
        #チェーンのリストの作成・ハッシュ難易度と個数調整・ブロックを作る司令を出す。

    def hash_block 
        #メインで使うハッシュ関数

    def create_genesis_block 
        #ジェネシスブロックの作成(mine_blockを使用)

    def mine_block 
        #マイニング機構▶条件にあうハッシュ値になるまでナンスを探索する

    def add_block 
        #二回目以降のブロックの作成・追加(mine_blockを使用)、結果の表示

    def is_chain_valid 
        #前後ハッシュ値の照合、時間をチェック、ハッシュの再計算によるチェック</code></pre>



<p>このようになっております。</p>



<h3 class="wp-block-heading">__init__とハッシュ関数</h3>



<p>まず、Blockchainインスタンスが作成されたら、self.chainというリストを作ります。ここにブロックを入れていきます。</p>



<p>それから難易度（ハッシュ値の最初に0が何個並ぶか）と生成するブロックの個数をinputで取得します。</p>



<pre class="wp-block-code"><code>def __init__(self):
    self.chain = &#091;]
    self.difficulty = int(input("Difficulty: "))
    self.max_block = int(input("Number of blocks: "))
    print(f"\n--------------------\n")

    genesis_block = self.create_genesis_block()
    self.chain.append(genesis_block)

    for i in range(1, self.max_block + 1):
        self.add_block(f"block {i}")

def hash_block(self, data, previous_hash, nonce, timestamp):
    content = data + previous_hash + str(nonce) + str(timestamp)
    hash = hashlib.sha256(content.encode()).hexdigest()
    return hash</code></pre>



<p>そのあとは、create_genesis_blockを呼び出して、genesis_blockを作成します。それを先程のリストに入れます。</p>



<p>これが最初のブロックです。</p>



<p>そのあとは、最初のinputの値に応じて、forループでブロックを追加していきます。</p>



<p>二回目以降は、データとしてf&#8221;block {i}:を使用しています。つまり3つめのブロックなら、&#8221;block 3&#8243;ですね。</p>



<p></p>



<p>hash_block関数は、データ、一つ前のハッシュ値、ナンス、タイムスタンプ（ブロック生成時のもの）を引数として受け取ります。</p>



<p>それらをstringとして足し合わせて、SHA-256でハッシュした値を返します。</p>



<h3 class="wp-block-heading">ジェネシスブロック(create_genesis_block)</h3>



<p>次に、ジェネシスブロックの生成の関数があります。</p>



<pre class="wp-block-code"><code>def create_genesis_block(self):
    genesis = self.mine_block("genesis", "0")
    return Block("genesis", "0", genesis&#091;"nonce"], genesis&#091;"hash"], genesis&#091;"timestamp"])</code></pre>



<p>これは、まず呼び出されたときにデータを&#8221;genesis&#8221;、previous_hashを0としてself.mine_block関数に渡して、マイニングしてもらいます。</p>



<p>見つかった結果をgenesisとして保存します。</p>



<p>これは以下のような辞書形式で返ってきます。</p>



<pre class="wp-block-code"><code>result = {
    "nonce": nonce,
    "hash": hash,
    "timestamp":  timestamp,
    "elapsed_time": elapsed_time,
    "attempts": attempts
}</code></pre>



<p>上から見つかったナンス（調整値）、ハッシュ値、タイムスタンプ（エポック秒）、経過時間、試行回数です。</p>



<p></p>



<p>Blockインスタンスの作成にはdata, previous_hash, nonce, hash, timestampがそれぞれ必要ですから、</p>



<pre class="wp-block-code"><code>Block("genesis", "0", genesis&#091;"nonce"], genesis&#091;"hash"], genesis&#091;"timestamp"])</code></pre>



<p>のようにして、ジェネシスブロックを作成します。</p>



<p>データは&#8221;genesis&#8221;、前のブロックのハッシュ値は0、ナンス、ハッシュ値、タイムスタンプを渡します。<br>そうして得られたBlockを返します。</p>



<p>こうして得られた値を、__init__で、リストに追加します。</p>



<pre class="wp-block-code"><code>self.chain.append(genesis_block)</code></pre>



<p>これで、ジェネシスブロックの完成です！</p>



<h3 class="wp-block-heading">マイニング(mine_block)</h3>



<p>次に、今回追加した、Proof of Work（PoW）を使ったマイニングを行う関数です。</p>



<p>ここはとても楽しいところです。</p>



<p>そもそもPoWとは、データにナンスと呼ばれる任意の数字を加えて、それをハッシュした値の先頭に指定された個数の0が並べば、それが認められるというものです。</p>



<p>この関数は、その条件に合ったときのナンスやハッシュ値、時間などを辞書形式にし、返します。</p>



<p>ナンスはnonce、指定する先頭の0の個数がdifficultyです。</p>



<pre class="wp-block-code"><code>def mine_block(self, data, previous_hash):
    nonce = 0
    attempts = 0
    target = '0' * self.difficulty
    start_time = time.time()
    timestamp = time.time()
    while True: 
        attempts += 1
        hash = self.hash_block(data, previous_hash, nonce, timestamp)
        if hash.startswith(target):
            break
        nonce += 1
    
    end_time = time.time()
    elapsed_time = end_time - start_time

    result = {
        "nonce": nonce,
        "hash": hash,
        "timestamp":  timestamp,
        "elapsed_time": elapsed_time,
        "attempts": attempts
    }
    return result  </code></pre>



<p>ナンスを0、試行回数を0に初期化します。</p>



<p>targetは、0をdifficulty個かけたものです。difficultyが5ならば&#8221;00000&#8243;です。<br>ナンスを加えてハッシュした結果が、targetで始まれば、そのナンスで決定です。</p>



<p>経過時間計測用のstart_timeと、timestampも定義します。</p>



<p>ここから、マイニングの作業を定義していきます。</p>



<pre class="wp-block-code"><code>while True: 
    hash = self.hash_block(data, previous_hash, nonce, timestamp)
    if hash.startswith(target):
        break
    nonce += 1
    attempts += 1</code></pre>



<p>whileループを用いて、ハッシュを何度も何度も試行します。</p>



<p>ナンス=0から始めて、だめなら+1して再挑戦、だめなら+1して再挑戦を繰り返します。(attemptsも、この回数を記録します）</p>



<p>そして、多くの試行を経て条件に合うものが見つかったら、breakします。</p>



<p>その後は以下のように処理されます。</p>



<pre class="wp-block-code"><code>end_time = time.time()
elapsed_time = end_time - start_time

result = {
    "nonce": nonce,
    "hash": hash,
    "timestamp":  timestamp,
    "elapsed_time": elapsed_time,
    "attempts": attempts
}
return result      </code></pre>



<p>終了時間を記録し、終了時間から開始時間を引くことで、処理にかかった時間を算出します。</p>



<p>resultという辞書にまとめてこれらの結果を入れ、それを返します。</p>



<p><strong>今回は実際のBitcoinのブロックチェーンに基づいて、時間もハッシュの対象に含めています</strong>。<br>これにより（取引）<strong>時間も改ざん不可能</strong>となりました。</p>



<p><strong>各ブロックは timestamp を含む完全再計算可能な hash を持つ</strong>のです。</p>



<p></p>



<p>以上が簡易的ですが、マイニングの実装になります。</p>



<h3 class="wp-block-heading">ブロックの追加(add_block)</h3>



<p>ここでは、ジェネシスブロックを除いた、ブロックの追加作業を行っていきます。</p>



<p>具体的には、まずマイニングの指令を先程のマイニング関数に出して、必要な情報をかき集めて、それを使ってBlockのインスタンスを作成します。</p>



<p>完成形は以下のようになります。</p>



<pre class="wp-block-code"><code>def add_block(self, data):
    previous_hash = self.chain&#091;-1].hash
    block_number = len(self.chain)

    #マイニングを行う
    mine_result = self.mine_block(data, previous_hash)

    #マイニングの結果より
    nonce = mine_result&#091;"nonce"]
    hash = mine_result&#091;"hash"]
    timestamp = mine_result&#091;"timestamp"]
    elapsed_time = mine_result&#091;"elapsed_time"]
    attempts = mine_result&#091;"attempts"]

    #ブロック作成
    new_block = Block(data, previous_hash, nonce, hash, timestamp)
    self.chain.append(new_block)

    #作成されたブロックの内容をprint
    print(f"&#091;Block {block_number} mined]\ndata: {data}\nnonce: {nonce}\nhash: {hash}\ntimestamp: {time.ctime(timestamp)}\ntime: {elapsed_time}\nattempts: {attempts}\n")
    print(f"--------------------\n")</code></pre>



<p>マイニングに必要なのはデータと一つ前のブロックのハッシュ値ですから、</p>



<pre class="wp-block-code"><code>mine_result = self.mine_block(data, previous_hash)</code></pre>



<p>のようにすることで、マイニングの結果（辞書）を取得することができます。</p>



<p>それらをわかりやすくするために変数に代入し、↓</p>



<pre class="wp-block-code"><code>nonce = mine_result&#091;"nonce"]
hash = mine_result&#091;"hash"]
timestamp = mine_result&#091;"timestamp"]
elapsed_time = mine_result&#091;"elapsed_time"]
attempts = mine_result&#091;"attempts"]</code></pre>



<p>ブロックを作成してチェーンリストに追加します。</p>



<pre class="wp-block-code"><code>new_block = Block(data, previous_hash, nonce, hash, timestamp)
self.chain.append(new_block)</code></pre>



<p>あとは結果をわかりやすく表示すれば完成です。<br>このような形式でターミナルに表示されます。</p>



<pre class="wp-block-code"><code>--------------------

&#091;Block 1 mined]
data: block 1
nonce: 1375971
hash: 000005c808a2a8cfc9d1707c4511d2db4467efaebb371af15e901b8645f613d3
timestamp: Mon Feb  2 21:47:30 2026
time: 1.0131967067718506
attempts: 1375971

--------------------</code></pre>



<p>これで肝心な動く部分は完成です！</p>



<h3 class="wp-block-heading">チェーン検証(is_chain_valid)</h3>



<p>ここでは以下３つの観点から、ブロックチェーンの正しさをチェックしています。</p>



<ul class="wp-block-list">
<li><strong>ブロック同士のハッシュの繋がり</strong></li>



<li><strong>タイムスタンプの関係</strong></li>



<li><strong>PoWにおけるナンスも含めたハッシュ値の整合</strong></li>
</ul>



<p>この３点です。</p>



<p>これを一段階具体的なロジックにすると、(4段階)</p>



<ol class="wp-block-list">
<li><strong>現在のブロックに保存されている「一つ前のブロックのハッシュ値」と、一つ前のブロックのハッシュ値が同値である</strong></li>



<li><strong>現在のブロックの作成された時間が、一つ前のブロックの作成された時間よりも遅い<br>かつ</strong><br><strong>現在のブロックの作成された時間が、一つ前のブロックが作成されてから〇〇秒以内になっている</strong></li>



<li><strong>保存された現在のブロックのハッシュ値が、計算した結果と同値である</strong></li>



<li><strong>現在のブロックのハッシュ値を計算し、それが指定された数の0で始まる</strong></li>
</ol>



<p>ということになります。</p>



<p>本実装では簡略化のため、ブロック生成間隔の上限を100秒とハードコードします。</p>



<p>擬似コードにすると、</p>



<pre class="wp-block-code"><code>もしcurrent_block.previous_hash == previous_block.hashならOK
↓次に進む

もし(previous_block.time &lt;= current_block.time) and (current_block.time &lt;= previous_block.time + 100)ならOK
↓次に進む

もしcurrent_block.hash == current_block.calculate_hash()ならOK
↓次に進む

target = '0' * self.difficulty
もしcurrent_block.calculate_hash().startswith(target)ならOK
↓

完了</code></pre>



<p>となります。</p>



<p>これをブロックごとにループで回しますので、最終的にコードは以下のようになります。</p>



<pre class="wp-block-code"><code>def is_chain_valid(self):
    #ブロックごとにループ
    for i in range(1, len(self.chain)):

        current_block = self.chain&#091;i] #現在のBlock
        previous_block = self.chain&#091;i-1] #一つ前のBlock

        #①
        if current_block.previous_hash == previous_block.hash:

            #②
            if (previous_block.time &lt;= current_block.time) and (current_block.time &lt;= previous_block.time + 100):
                
                #③
                if current_block.hash == current_block.calculate_hash():
                    target = '0' * self.difficulty

                    #④
                    if current_block.calculate_hash().startswith(target):
                        continue
                    else:
                            return False
                else:
                    return False
            else:
                return False
        else:
            return False
    return True</code></pre>



<p>ここで、Blockクラス自身のハッシュ関数を使っています。</p>



<p>チェーンがうまくいっていれば、Trueを返します。</p>



<h3 class="wp-block-heading">実行</h3>



<pre class="wp-block-code"><code>bc = Blockchain()
print("initial chain valid?:", bc.is_chain_valid())</code></pre>



<p>bcというBlockchainクラスのインスタンスを作成します。<br>is_chain_validの結果を表示するようにします。</p>



<p>実行結果は以下のようになります。</p>



<p>難易度6のブロック個数5と入力しました。</p>



<pre class="wp-block-code"><code>Difficulty: 6
Number of blocks: 5

--------------------

&#091;Block 1 mined]
data: block 1
nonce: 19045810
hash: 000000bc15dfaf59dbc8f62eb688b20e4edcfa53bc092687fd6c2512c29f0f95
timestamp: Tue Feb  3 10:09:02 2026
time: 13.969925880432129
attempts: 19045811

--------------------

&#091;Block 2 mined]
data: block 2
nonce: 19282913
hash: 0000008c88f0dab0ae6430d842fc4fff208e6b36c3bf513c3497c9d8fc9ea61e
timestamp: Tue Feb  3 10:09:16 2026
time: 14.559286117553711
attempts: 19282914

--------------------

&#091;Block 3 mined]
data: block 3
nonce: 29935602
hash: 0000003c8c2aa0014275ed9e559d7fb9856769a679c2f95ca3aa9df81dffbfc0
timestamp: Tue Feb  3 10:09:30 2026
time: 22.947882890701294
attempts: 29935603

--------------------

&#091;Block 4 mined]
data: block 4
nonce: 1030480
hash: 0000000dc1d9be902c11fb8c2938585a44e036548c65594eb62161a529eea927
timestamp: Tue Feb  3 10:09:53 2026
time: 0.8383839130401611
attempts: 1030481

--------------------

&#091;Block 5 mined]
data: block 5
nonce: 10172800
hash: 0000003659f70afdf16476c33731135c8e29ba4b98aed737ecb3c36d79d7b08c
timestamp: Tue Feb  3 10:09:54 2026
time: 7.655301094055176
attempts: 10172801

--------------------

initial chain valid?: True</code></pre>



<p>以上で完成です！お疲れ様でした。</p>



<h1 class="wp-block-heading">おわりに</h1>



<p>自分でブロックチェーンを書いて、着々と仕組みを深く理解していくのが、本当に楽しくなってきました。</p>



<p>ここまで自力で書ける自分にも驚いています。<br>時間を忘れてやってしまいます笑</p>



<p>次はこの愛着のある自作ブロックチェーンを使って、数値をいじくって観察したいと思います。</p>



<p>今後はこの実装を使って、以下のような実験を行う予定です。</p>



<ol class="wp-block-list">
<li>difficulty と attempts の関係の統計分析</li>



<li>ブロック生成時間の分布の可視化</li>



<li>nonce をランダム初期化した場合の偏り検証</li>



<li>difficulty を途中で変更した場合の fork 実験</li>
</ol>



<p>以上です！</p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://pathlog.jp/2026/02/03/pow%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%9f%e7%b0%a1%e6%98%93%e3%83%96%e3%83%ad%e3%83%83%e3%82%af%e3%83%81%e3%82%a7%e3%83%bc%e3%83%b3%e3%82%92python%e3%81%a7%e5%ae%9f%e8%a3%85/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
