書いて覚えるSwift入門

第30回 SD読者ならわかるブロックチェーン入門

この記事を読むのに必要な時間:およそ 4 分

前号の予告に変えて

前回の記事ではSwiftのSequenceプロトコルを取り上げたうえで,次回はそのSequenceの中でもランダムアクセス可能なCollectionを取り上げる予定でしたが,もう1回ある特殊なSequenceを取り上げることにします。それも,今後のITの世界を一変させる可能性を秘めた,とあるSequenceです。それはSwiftのコードにすれば,

protocol Block {
    associatedtype Signature
    associatedtype Payload
    func isValid(prev:Self)->Bool
}

enum BlockError: Error {
    case Invalid
}

protocol BlockChain : Sequence {
    associatedtype Element:Block
    var last:Element? { get }
    mutating func append(_ block:Element)
throws

}

と表現されるSequenceすなわちブロックチェーンという名のSequenceです。

ブログでも発表したとおり,このたび私,小飼弾は株式会社VALUのリードエンジニアに就任いたしました図1)⁠同社のサービスであるVALUはVAという個人の指標をビットコイン$BTC)で売買する市場を備えたSNSで,その売買手数料が同社の収益源なのですが,それは売上が100%ビットコインだということ。ビットコインあってのVALUなのです。

図1 筆者のVALU

図1 筆者のVALU

そしてそのビットコインは,ブロックチェーン(blockchain)という技術で成り立っています。ビットコインはブロックチェーンの最初にして現時点における最重要のアプリケーションではありますが,ブロックチェーンでできることの氷山の一角に過ぎません。

断言します。ブロックチェーンはWWW以来,最重要のIT(Information Technology)である,と。

本誌の読者であれば,今年中にHTTP(S)やHTMLなみにごく当然のようにわきまえておかねばならない常識になる,と。

と言っても慌てる必要はありません。ブロックチェーンが今後不可欠な基盤技術であることと受け入れられたのはごく最近なのですし,理解と習得に何年もかかるほど難解なものではないのですから。図2のチャートをご覧ください。これは日本国内最大級の交換所,bitFlyer社の2017年08月19日における,ビットコインと日本円の交換レートなのですが,注目していただきたいのは急騰している右上ではなく左下。Nov '16とあります。同社のチャートでさえこれしか歴史がないのです。今から学習しても十分間に合います。

Welcome to the blockchain!

ブロックチェーンとはいったい何か? 刻々と追記されるデータをP2Pネットワークで安全確実に同期する技術。これだけです。どうやってそれを実現しているかを知る前に,まずは「すでに記録が完了したデータをP2Pネットワークで安全確実に同期する」方法をおさらいしておきましょう。

「すでに記録が完了したデータ」と言えば,ファイル。P2Pと聞いて本誌の読者の皆さんが思い出すのは,WinnyやBitTorrentといった,ファイルを取得するためのP2Pではないでしょうか。誰からもらったのかもわからないファイルが改ざんされていないことを,我々はどう確かめたら良いのでしょう? そのファイルに固有の特徴(signature)を見ていますよね。

たとえばOSのインストーライメージであれば,md5やSHA-1やSHA-256といったチェックサム(checksum)が記載されたファイルが必ず配布ディレクトリに配置されています。なのでubuntu-16.04.3-desktop-amd64.iso注1のSHA-256ダイジェストが1384ac8f2c2a6479ba2a9cbe90a585618834560c477a699a4a7ebe7b5345ddc1であることを確かめれば,正体不明の人からそれをもらっても間違いなく正しいファイルであることを確認できるわけです。

ファイルであれば,ファイルそのものは信頼できない経路でもらっても,signatureさえ信頼できる経路でもらえばOKですが,それを「終わりなきデータ」で実現するにはどうしたら良いのでしょうか?

適当にデータがたまったら,それをファイルにして,そのファイルの前のファイルのsignatureをわかるようにしておけばいい。これがブロックチェーンの基本的な考えで,基本はそれだけです。この「すでに記録が完了した」データを,⁠ファイル」ではなく「ブロック」と呼称しているだけです。次は前のブロックのhashvalueを署名とする最も簡単なブロックチェーンの実装です。

struct SimpleBlock<D:Hashable> : Block {
    typealias Signature = Int
    typealias Payload = D
    let prevSign:Signature
    let payload:D
    func isValid(prev:SimpleBlock<D>)->Bool {
        return prev.payload.hashValue == self.prevSign
    }
}

struct SimpleBlockChain<D:Hashable> : BlockChain {
typealias Element = SimpleBlock<D>
    var blocks:[Element]
    var last:Element? {
        return blocks.last
    }
    mutating func append(_ block:Element) throws {
        if blocks.isEmpty ¦¦ block.isValid(prev: last!) {
            blocks.append(block)
        } else {
            throw BlockError.Invalid
        }
    }
    func makeIterator() -> AnyIterator<Element> {
        var count = 0
        return AnyIterator {
            if count == self.blocks.count {
                return nil
            } else {
                defer { count += 1 }
                return self.blocks[count]
            }
        }
    }
}

次の処理結果を見てのとおり,直前のブロックのpayloadhashValueが一致しないとappendに失敗します。

extension SimpleBlockChain {
    init() { blocks = [] }
}

var sbc = SimpleBlockChain<String>()

do {
    try sbc.append( // 最初のブロック
      SimpleBlock(prevSign: 0, payload: "Zero")
    )
    try sbc.append( // 次の不正なブロック
      SimpleBlock(prevSign: 0, payload: "1")
    )
} catch {
    print(error)
}
try sbc.append(
    SimpleBlock(  // 次の正しいブロック
       prevSign: 4799450038612711877,
       payload: "one"
    ) 
  )
for b in sbc {
    print(b.payload)
}

しかしこれだと,あるデータの続きを作るだけなら誰でもできてしまうことになります。前にあるデータのsignatureは誰にでも作れてしまうのですから。つまりデータはフォーク(fork)する可能性があるのです。実際ビットコインも今年8月1日にフォークしたのですが,ブロックチェーンが保証するのはその前までのデータであって,その次以降のデータはその限りではないということは,大事なことなので忘れないようにしておいてください。

しかしそれではフォークだらけになって収拾がつかなくなるのは目に見えています。それを防ぐにはどうしたら良いでしょう? ここで紙の世界を見てみましょう。複数のページからなる契約書があるとします。この契約書がひとつながりの契約書であることをどう保証しているか? 全ページに同じ人が署名するのです。実際には各ページにはイニシャル程度の略式の署名をし,最後のページに本署名するのが現在確立されたスタイルですが,要は誰でも勝手に署名できない形で署名してしまえば,紙であろうがブロックであろうが,それがひとつながりのデータであることは保証できるわけです。

注1)
URL:http://ftp.riken.jp/Linux/ubuntu-releases/16.04/ubuntu-16.04.3-desktop-amd64.iso
URL:http://ftp.riken.jp/Linux/ubuntu-releases/16.04/SHA256SUMS

著者プロフィール

小飼弾(こがいだん)

1969年生まれ,東京都出身。元ライブドア取締役の肩書きよりも,最近はPokemon GOのガチトレーナーのほうが有名になりつつある……かもしれない永遠のエンジニアオヤジ。

活躍の場はIT業界だけでなく,サブカルからアカデミックまで多方面にわたり,ネットからの情報発信は気の向くまま毎日毎秒! https://twitter.com/dankogai,ニコニコチャンネルは,http://ch.nicovideo.jp/dankogai,blogはhttp://blog.livedoor.jp/dankogai/

当社刊行書籍は『小飼弾のアルファギークに逢ってきた』『小飼弾のコードなエッセイ』など。他にも著書多数。

コメント

コメントの記入