へなちょこプログラマー

CS 会計 司法試験 英語 bitcoin などいろいろなことを勉強してます

オブジェクト指向について

C++の基本的な機能は理解したので、オブジェクト指向のもっと深い理解を得るために、オブジェクト指向入門をよんでます。

オブジェクト指向入門 第2版 原則・コンセプト (IT Architect’Archive クラシックモダン・コンピューティング)

オブジェクト指向入門 第2版 原則・コンセプト (IT Architect’Archive クラシックモダン・コンピューティング)

オブジェクト指向入門 第2版 方法論・実践 (IT Architects' Archiveクラシックモダン・コンピューティング)

オブジェクト指向入門 第2版 方法論・実践 (IT Architects' Archiveクラシックモダン・コンピューティング)

分厚いですが、わかりやすいのでそんなに苦労せずに読めると思います。


最近は、データ構造をある程度理解して、いろいろな概念がわかるようになってきたので、だんだんコードが読めるようになってきました。

もっと勉強しないといけません

Bitcoin CAmount について

ソースコードを読んでいて、CAmount ってなんだったっけ? てよくなるので、メモ

amount.h

#ifndef BITCOIN_AMOUNT_H
#define BITCOIN_AMOUNT_H

#include <stdint.h>

/** Amount in satoshis (Can be negative) */
typedef int64_t CAmount;

// 1BTC = 100000000satoshi
// 1BTC = 1 * COIN
static const CAmount COIN = 100000000; 
static const CAmount CENT = 1000000;   

/** No amount larger than this (in satoshi) is valid.
 *
 * Note that this constant is *not* the total money supply, which in Bitcoin
 * currently happens to be less than 21,000,000 BTC for various reasons, but
 * rather a sanity check. As this sanity check is used by consensus-critical
 * validation code, the exact value of the MAX_MONEY constant is consensus
 * critical; in unusual circumstances like a(nother) overflow bug that allowed
 * for the creation of coins out of thin air modification could lead to a fork.
 * */

// 発行量 の最大量 
static const CAmount MAX_MONEY = 21000000 * COIN;
//  0 <= 発行量 <= MAX_MONEY
inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }

#endif //  BITCOIN_AMOUNT_H

CAmount は int_64_t です。

Bitcoinの総発行量については、以下を参考に。
www.neuralsparrow.com

暗号技術 参考書 まとめ

暗号を学ぶ上で、オススメの書籍をまとめてみます。

暗号技術入門 第3版

暗号技術入門 第3版

暗号技術入門は、暗号技術全般がうまくまとまっていて、非常にオススメです。とりあえず、この本を読めば対称鍵暗号、公開鍵暗号、ハッシュ関数、電子署名からMACまで基礎は理解できると思います。

Javaで作って学ぶ暗号技術 - RSA,AES,SHAの基礎からSSLまで

Javaで作って学ぶ暗号技術 - RSA,AES,SHAの基礎からSSLまで

こちらは、javaで実装しながら理解できます。こちらはARS,SHA2,AESのアルゴリズムがするする理解できます。やはり実際にコードでアルゴリズムを実装するのが、一番いいと思います。

暗号理論と楕円曲線

暗号理論と楕円曲線

  • 作者: 辻井重男,笠原正雄,有田正剛,境隆一,只木孝太郎,趙晋輝,松尾和人
  • 出版社/メーカー: 森北出版
  • 発売日: 2008/08/01
  • メディア: 単行本(ソフトカバー)
  • 購入: 1人 クリック: 11回
  • この商品を含むブログ (1件) を見る

楕円曲線もしっかりと理解しておきましょう。この本は、数式もわかりやすく説明されているので、普通に理解できると思います。

楕円曲線はビットコインでも使われています。

暗号解読〈上〉 (新潮文庫)

暗号解読〈上〉 (新潮文庫)

暗号解読(下)(新潮文庫)

暗号解読(下)(新潮文庫)

名著です。

暗号の歴史がわかります。シーザー暗号から、アントワネットとかいろいろな話が合って面白いです。

読みましょう。



C++ STLの技術書まとめ

C++の基本的な機能をある程度おさえたので、STL、標準テンプレートライブラリ、の勉強も本格的に始めました。

とりあえず、2冊手に入れて、勉強しております。

STL―標準テンプレートライブラリによるC++プログラミング 第2版

STL―標準テンプレートライブラリによるC++プログラミング 第2版

  • 作者: ディビッド・R.マッサー,アトゥルサイニ,ギルマー・J.ダージ,David R. Musser,Atul Saini,Gillmer J. Derge,滝沢徹,牧野祐子
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2001/12
  • メディア: 単行本
  • 購入: 5人 クリック: 74回
  • この商品を含むブログ (18件) を見る

入門としては最適だと思います。この本をやってからeffective STL をやるといいかと。

Effective STL―STLを効果的に使いこなす50の鉄則

Effective STL―STLを効果的に使いこなす50の鉄則

  • 作者: スコットメイヤーズ,Scott Meyers,細谷昭
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2002/01
  • メディア: 単行本
  • 購入: 9人 クリック: 155回
  • この商品を含むブログ (95件) を見る

effective シリーズは手に入るだけ全て読むべきでしょう。


まあC++はある程度理解できてきたので、暗号とP2Pの勉強にシフトしていきたいと思います。

とりあえず,BitcoinとEthereumのソースコードを今年中に理解できるように頑張ります。

pybitcointools を使った鍵操作 Bitcoin

pybitcointoolsについては、

github.com

で見てください。ちなみにブテリンはEthereumの創業者です。

import pybitcointools as bitcoin # learn more: https://python.org/pypi/pybitcointools

# 秘密鍵を作成
valid_private_key = False
while not valid_private_key:
    private_key = bitcoin.random_key()
    decoded_private_key = bitcoin.decode_privkey(private_key, 'hex')
    valid_private_key = 0 < decoded_private_key < bitcoin.N

# 秘密鍵を表示    
print "Private Key (hex) is: ", private_key
print "Private Key (decimal) is: ", decoded_private_key

# Wallet Import Format (Base58形式) での表示
wif_encoded_private_key = bitcoin.encode_privkey(decoded_private_key, 'wif')
print "Private Key (WIF) is: ", wif_encoded_private_key

compressd_private_key = private_key + '01'
print "Private Key Compressed (hex) is: ", compressd_private_key

# 圧縮 WIF
wif_compressed_private_key = bitcoin.encode_privkey(
    bitcoin.decode_privkey(compressd_private_key, 'hex'), 'wif')
print "Private Key (WIF-Compressed) is: ", wif_compressed_private_key

# 公開鍵を求める
public_key = bitcoin.fast_multiply(bitcoin.G, decoded_private_key)
print "Public Key (hex) is: ", public_key

hex_encoded_public_key = bitcoin.encode_pubkey(public_key, 'hex')
print "Public Key (hex) is: ", hex_encoded_public_key

# 圧縮公開鍵
(public_key_x, public_key_y) = public_key
if(public_key_y % 2) == 0:
    compressed_prefix = '02'
else:
    compressed_prefix = '03'
hex_compressed_public_key = compressed_prefix + bitcoin.encode(public_key_x, 16)
print "Compressed Public Key (hex) is: ", hex_compressed_public_key

# ビットコインアドレスの表示
print "Bitcoin Address (b58check) is:", bitcoin.pubkey_to_address(public_key)

# 圧縮ビットコインアドレスの表示
print "Compressed Bitcoin Address (Base58Check) is :", \
    bitcoin.pubkey_to_address(hex_compressed_public_key)

ビットコイン difficulty target と retargeting 

difficulty target は係数部/指数部形式で表す。

指数部(exponent),係数部(coefficient)で

target = coefficient * 2^(8 * (exponent - 3))

^はXORです。

またDifficultyはブロックの生成期間を10分に保つように動的に変化します。

Difficultyは2016ブロックごとにretargetされます。

ActualTimespan は 最後の2016ブロックが生成されるのにかかった時間です。

式にすると

New Difficulty = Old Difficulty * (Actual Time of Last 2016 Blocks / 2016 minutes)

ソースコードは

unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
{
    if (params.fPowNoRetargeting)
        return pindexLast->nBits;

    // Limit adjustment step
    int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
    
    // difficultyが動きすぎないように、もし調整が 4倍 or 4/1 以上動く場合
    // 最大でも4、最小でも4/1になるようになっている。
    if (nActualTimespan < params.nPowTargetTimespan/4)
        nActualTimespan = params.nPowTargetTimespan/4;
    if (nActualTimespan > params.nPowTargetTimespan*4)
        nActualTimespan = params.nPowTargetTimespan*4;
    // Retarget
    const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
    arith_uint256 bnNew;
    bnNew.SetCompact(pindexLast->nBits);
    bnNew *= nActualTimespan;
    bnNew /= params.nPowTargetTimespan;

    if (bnNew > bnPowLimit)
        bnNew = bnPowLimit;

    return bnNew.GetCompact();
}

のようになります。

ビットコイン マイニング報酬のソースコードリーディング

ビットコインのマイニング報酬のコードを見ていきます。

マイニング報酬は、トランザクション手数料の総額 + coinbase報酬

coinbase報酬(BlockSubsidy)は50bitcoinから始まって、210000ブロックごとに半減していきます。

以下のコードでcoinbase報酬を出します。

// Subsidy は 報酬という意味
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
{
    // nHeightは現在のブロック高.
    // nSubsidyHalvingIntervalは半減ブロック間隔 = 210000
    // ブロック高を半減ブロック間隔で割ることで半減回数を求めている.
    int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
    
    // 半減数の回数最大で64.それを超えたら報酬は0.
    if(halvings >= 64)
        return 0;
        
    // COIN定数は 100,000,000satoshi で,50 * COIN は50億satoshi
    // 初期報酬(nSubsidy) が 50億satoshi であることがわかる。
    CAmount nSubsidy = 50 * COIN;
    
    // 報酬は210000ブロックごとに半減.約4年
    // 右シフト演算子を使って報酬(nSubsidy)を割っている
    nSubsidy >>= halvings;
    return nSubsidy;
}

この後、nSubsidy と トランザクション手数料(nFees)を足したものがマイニングの報酬となります。

Copyright © 2016 へなちょこプログラマー All rights reserved.