Upgrade to Pro — share decks privately, control downloads, hide ads and more …

傳說中可以治百病的區塊鏈是怎麼一回事?

 傳說中可以治百病的區塊鏈是怎麼一回事?

高見龍

July 18, 2018
Tweet

More Decks by 高見龍

Other Decks in Programming

Transcript

  1. 傳說中可以治百病的
    區塊鏈是怎麼⼀一回事?
    高見龍

    View Slide

  2. a.k.a Eddie
    愛現! 喜歡冷門的玩具
    Ruby/Rails/iOS app 開發者、講師
    Ruby 技術推廣、教育、諮詢
    台灣、日本等國內外 Ruby 技術研討會講者
    目前於五倍紅寶石擔任紅寶石鑑定商職務
    部落格:https://kaochenlong.com
    高見龍
    photo by Eddie
    @eddiekao
    !

    View Slide

  3. View Slide

  4. 發售中!
    https://gitbook.tw/
    第五刷

    View Slide

  5. 發售中!
    https://railsbook.tw/
    沒人買

    View Slide

  6. 源起
    why this topic?

    View Slide

  7. 1 BTC vs. 19,000 USD

    View Slide

  8. 時代在變

    View Slide

  9. 動⼿手實作
    learning by coding

    View Slide

  10. ⼤大綱
    agenda

    View Slide

  11. 從開發者的⾓角度看區塊鏈
    from a developer's perspective

    View Slide

  12. 區塊、鏈條與挖礦!
    block, chain, and mining!

    View Slide

  13. 以太坊、智能合約、Dapp
    ethereum / smart contract / Dapp
    不會講到

    View Slide

  14. 該不該買比特幣?
    should I buy bitcoin?
    我不懂
    沒錢錢
    不會講到

    View Slide

  15. 沒有買賣,沒有傷害
    No expectations, no disappointments

    View Slide

  16. View Slide

  17. 科普
    popular science

    View Slide

  18. 區塊
    block

    View Slide

  19. 區塊 = 資料結構
    data structure

    View Slide

  20. DATA
    4bb5fc9c
    獮㮆玟璸篷
    ୌ缏碻樌
    Block #0
    交易資料

    View Slide

  21. DATA
    4bb5fc9c
    獮㮆玟璸篷
    ୌ缏碻樌
    Block #0
    DATA
    51e15133
    獮㮆玟璸EEIFF
    ୌ缏碻樌
    Block #1
    DATA
    7a44fb64
    獮㮆玟璸H
    ୌ缏碻樌
    Block #2
    DATA
    00bbedf4
    獮㮆玟璸DIE
    ୌ缏碻樌
    Block #3
    區塊

    View Slide

  22. class Block
    attr_reader :hash
    attr_reader :previous_hash
    attr_reader :data
    attr_reader :timestamp
    def initialize(previous_hash, data)
    @previous_hash = previous_hash
    @data = data
    @timestamp = Time.now.to_i
    @hash = calculate_hash
    end
    private
    def calculate_hash
    # 待會再來來寫!
    end
    end
    檔案:app/block.rb
    定義屬性
    計算Hash
    初始化

    View Slide

  23. def calculate_hash
    content = "!#{previous_hash}!#{timestamp}!#{data}"
    Digest!::SHA256.hexdigest(content)
    end
    檔案:app/block.rb
    SHA256

    View Slide

  24. require 'pp'
    require_relative '!../app/block'
    block0 = Block.new('00000000000000', '我要變成海海賊王!')
    pp block0
    檔案:playground/playground001.rb

    View Slide

  25. #@data="我要變成海海賊王!",
    @hash="b39737768aac9bf8361db4d8658b3f82a76578ae33a5f4e7a326ea07a01e6c9c",
    @previous_hash="00000000000000",
    @timestamp=1531777292>
    程式執⾏行行結果

    View Slide

  26. ⼀一顆區塊不夠,那就來來兩兩顆
    我給你 3 個!

    View Slide

  27. require 'pp'
    require_relative '!../app/block'
    block0 = Block.new('0000000000000000', '我要變成海海賊王!')
    block1 = Block.new(block0.hash, '我是 1 號區塊!')
    block2 = Block.new(block1.hash, '我是 2 號區塊!')
    pp block0
    pp block1
    pp block2
    檔案:playground/playground002.rb

    View Slide

  28. #@data="我要變成海海賊王!",
    @hash="c4a14f3d783c02b0d3a7bf82556ad5093ab77b13d2ae95758e923d0f63a7158f",
    @previous_hash="0000000000000000",
    @timestamp=1531777461>
    #@data="我是 1 號區塊!",
    @hash="d988cbedbd78d697c197e2c7d821184e92f0f20a18e79cedb8c7d2c0a2c66584",
    @previous_hash= "c4a14f3d783c02b0d3a7bf82556ad5093ab77b13d2ae95758e923d0f63a7158f",
    @timestamp=1531777461>
    #@data="我是 2 號區塊!",
    @hash="9d80de727301cc51a34b0777cfb0eb64a689b0714c68c1b03151c616616fef9f",
    @previous_hash= "d988cbedbd78d697c197e2c7d821184e92f0f20a18e79cedb8c7d2c0a2c66584",
    @timestamp=1531777461>
    串起來了
    程式執⾏行行結果

    View Slide

  29. View Slide

  30. 創世
    Genesis block

    View Slide

  31. 比特幣世界裡的第 0 個區塊 (資料來來源:https://blockchain.info)

    View Slide

  32. 彩蛋
    surprise!

    View Slide

  33. The Times 03/Jan/2009 Chancellor on
    brink of second bailout for banks

    View Slide

  34. static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce,
    uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
    {
    const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on
    brink of second bailout for banks";
    const CScript genesisOutputScript = CScript() !<<
    ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0e
    a1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6b
    f11d5f") !<< OP_CHECKSIG;
    return CreateGenesisBlock(pszTimestamp, genesisOutputScript,
    nTime, nNonce, nBits, nVersion, genesisReward);
    }
    檔案:src/chainparams.cpp
    這裡!

    View Slide

  35. 鏈條
    chain

    View Slide

  36. require_relative './block'
    class Blockchain
    attr_reader :chain
    def initialize
    @chain = [ genesis_block ]
    end
    private
    def genesis_block
    @genesis_block !!||= Block.new('0' * 64, '2018/7/18 我宣佈參參選天龍國國
    王,我要變成海海賊王!')
    end
    end
    檔案:app/blockchain.rb
    創世區塊
    初始化

    View Slide

  37. require 'pp'
    require_relative '!../app/blockchain'
    blockchain = Blockchain.new
    pp blockchain
    檔案:playground/playground003.rb

    View Slide

  38. 程式執⾏行行結果
    #@chain=
    [#@data="2018/7/18 我宣佈參參選天龍國國王,我要變成海海賊王!",
    @hash="e3c4d673665a03d9810b6dc3fb1aa7422bac27d3653f0a6fb9f9b07ecb841a1d",
    @previous_hash= "0000000000000000000000000000000000000000000000000000000000000000",
    @timestamp=1531778950>]>
    當個創世神!

    View Slide

  39. 比特幣世界裡的第 0 個區塊 (資料來來源:https://blockchain.info)
    前無古人

    View Slide

  40. 挖礦
    mining

    View Slide

  41. 聽說「挖礦」是在解決複雜
    的數學題⽬目嗎?

    View Slide

  42. 在某個很遙遠的星球...

    View Slide

  43. 使用「輕薄的假象」

    View Slide

  44. ⾙貝吉達:
    「好⿇麻煩!那叫⼩小傑同學來來負責記帳總
    可以了了吧」。

    View Slide

  45. 柯南推著眼鏡:
    「這乍看之下好像沒問題,但如果管錢
    的同學跟管帳的同學⼀一起串串通好的話,
    上⾯面的情況還是可能會發⽣生的。」

    View Slide

  46. ⼩小蘭蘭提議:
    「那如果由全班同學⼀一起來來記帳呢?」

    View Slide

  47. 柯南:
    「好像不錯,但要每位同學都來來記帳好
    像太辛苦了了,同學們同時還要顧⾃自⼰己的
    課業,下課也要參參加社團活動,所以到
    最後可能會沒有⼈人想做這件事…」

    View Slide

  48. 班導師江島⽥田平八站到講臺上說:
    「這樣好了了,為了了⿎鼓勵⼤大家⼀一起記帳,
    每次負責記帳的同學可以獲得 1 個乖寶
    寶點數喔!」。

    View Slide

  49. 挖礦 == 爭取記賬的權利利

    View Slide

  50. ⼯工作證明
    prove of work (PoW)

    View Slide

  51. 雪崩效應
    Avalanche Effect

    View Slide

  52. 打到這裡
    才算成功

    View Slide

  53. 比特幣世界裡的第 0 個區塊 (資料來來源:https://blockchain.info)
    就像這樣!

    View Slide

  54. 隨機數
    Nonce = Number use once

    View Slide

  55. require 'digest'
    class Block
    attr_reader :hash, :previous_hash, :data, :timestamp
    attr_reader :nonce
    def initialize(previous_hash, data)
    @previous_hash = previous_hash
    @data = data
    @timestamp = Time.now.to_i
    @nonce = 0
    @hash = ''
    mine!
    end
    def mine!
    # 待會再來來寫
    end
    private
    def calculate_hash
    content = "!#{previous_hash}!#{timestamp}!#{data}!#{nonce}"
    Digest!::SHA256.hexdigest(content)
    end
    end
    檔案:app/block.rb
    從 0 開始
    隨機數
    隨機數

    View Slide

  56. def mine!
    loop do
    result = calculate_hash
    if result.start_with?("000")
    @hash = result
    break
    else
    @nonce += 1
    @timestamp = Time.now.to_i
    end
    end
    end
    檔案:app/block.rb
    開頭 3 個 0
    ++

    View Slide

  57. ⼗十分鐘

    View Slide

  58. 每兩兩個星期難度會⾃自動調整

    View Slide

  59. 聽說「挖礦」是在解決複雜
    的數學題⽬目嗎?

    View Slide

  60. 每⼗十分鐘就會有⼀一個區塊嗎?

    View Slide

  61. 萬⼀一都找不到合適的隨機數?
    Nonce = Number use once

    View Slide

  62. 記賬
    ledger book

    View Slide

  63. 區塊鏈 == 記賬本

    View Slide

  64. 花錢
    spend mondy

    View Slide

  65. 銀⾏行行轉帳

    View Slide

  66. 未花費的交易易輸出
    Unspent Transaction Output (UTXO)

    View Slide

  67. 巷⼦子⼝口的⽜牛⾁肉麵店...
    prove of work (PoW)

    View Slide

  68. 找錢的時候不⼀一定會找回原
    本的錢包位址

    View Slide

  69. 交易易
    Transaction

    View Slide

  70. class Transaction
    attr_reader :from, :to, :amount
    attr_reader :timestamp
    def initialize(from:, to:, amount:)
    @from = from
    @to = to
    @amount = amount
    @timestamp = Time.now.to_i
    end
    end
    檔案:app/transaction.rb
    要說清楚這是
    要給誰的錢

    View Slide

  71. require './block'
    require './transaction'
    class Blockchain
    attr_reader :chain
    attr_reader :transaction_pool
    def initialize
    @chain = [ genesis_block ]
    @transaction_pool = []
    end
    def add_transaction(transaction)
    raise "必須是交易易" unless transaction.is_a?(Transaction)
    raise "交易易⾦金金額必須⼤大於 0" if transaction.amount !<= 0
    @transaction_pool !<< transaction
    end
    private
    def genesis_block
    # !!... 略略 !!...
    end
    end
    檔案:app/blockchain.rb
    交易先放
    在這裡
    丟進池子裡
    一開始是
    空的

    View Slide

  72. require 'pp'
    require_relative '!../app/blockchain'
    require_relative '!../app/transaction'
    blockchain = Blockchain.new
    tx1 = Transaction.new(from: 'Eddie', to: 'Sherly', amount: 10)
    blockchain.add_transaction(tx1)
    pp blockchain
    檔案:playground/playground004.rb

    View Slide

  73. 程式執⾏行行結果
    #@chain=
    [#@data="2018/7/18 我宣佈參參選天龍國國王,我要變成海海賊王!",
    @hash="00038d02b7b99602bfcb9d96d83018de687cdeb5ac8280cc69bc3f707f19b4bf",
    @nonce=1279,
    @previous_hash= "0000000000000000000000000000000000000000000000000000000000000000",
    @timestamp=1531780614>],
    @transaction_pool=
    [#@amount=10,
    @from="Eddie",
    @timestamp=1531780614,
    @to="Sherly">]>
    待確認交易

    View Slide

  74. 把⼼心情哼成歌

    View Slide

  75. 把交易易挖成礦!

    View Slide

  76. def mine!
    @chain !<< Block.new(last_block.hash, pick_transactions)
    clean_transactions
    end
    private
    def last_block
    @chain.last
    end
    def pick_transactions
    # 細節待實作,暫時先回傳整個 @transaction_pool 陣列列
    @transaction_pool
    end
    def clean_transactions
    # 細節待實作,暫時先把全部的交易易都清掉
    @transaction_pool = []
    end
    檔案:app/blockchain.rb
    挖礦完成
    清除交易

    View Slide

  77. require 'pp'
    require_relative '!../app/blockchain'
    require_relative '!../app/transaction'
    blockchain = Blockchain.new
    tx1 = Transaction.new(from: 'Eddie', to: 'Sherly', amount: 10)
    blockchain.add_transaction(tx1)
    blockchain.mine!
    pp blockchain
    檔案:playground/playground005.rb

    View Slide

  78. 程式執⾏行行結果
    #@chain=
    [#@data="2018/7/18 我宣佈參參選天龍國國王,我要變成海海賊王!",
    @hash="00002669323dbc9e5d9f6f43b7f29094939b3ba1f2c863e33af7ba00ab2d5b2e",
    @nonce=4273,
    @previous_hash= "0000000000000000000000000000000000000000000000000000000000000000",
    @timestamp=1531780941>,
    #@data=
    [#@amount=10,
    @from="Eddie",
    @timestamp=1531780941,
    @to="Sherly">],
    @hash="000f737c1008bfc27be216e5147dbd67079894b34fbeca5b5bf04699a28e2bea",
    @nonce=4688,
    @previous_hash= "00002669323dbc9e5d9f6f43b7f29094939b3ba1f2c863e33af7ba00ab2d5b2e",
    @timestamp=1531780941>],
    @transaction_pool=[]>
    交易清掉了
    產生了新
    的區塊

    View Slide

  79. 散⼾戶挖得到嗎?

    View Slide

  80. 打不贏他,就加入他!

    View Slide

  81. 都沒有⼈人想打包我的交易易
    你就是邊緣啊!

    View Slide

  82. 分叉
    fork

    View Slide

  83. 廣播、講八卦!

    View Slide

  84. 如果差不多時間挖到?

    View Slide

  85. 驗證
    validation

    View Slide

  86. View Slide

  87. 檔案:app/blockchain.rb
    def valid?
    # 來來,讓叔叔幫你檢查!!...你的 Hash 值
    # 第⼀一顆區塊應該要是創世區塊
    return false if first_block !!= genesis_block
    # 接下來來檢查每個區塊是不是合法!!...
    chain.each.with_index do |b, i|
    # 第⼀一顆不⽤用檢查
    if i > 0
    current_block = chain[i]
    previous_block = chain[i - 1]
    # ⽬目前這顆的 previous_hash 應該要等於前⼀一顆的 hash
    return false if current_block.previous_hash !!= previous_block.hash
    # ⽬目前這顆的 hash,再重新計算後應該要得到⼀一樣的結果
    return false if current_block.hash !!= Block.block_hash(current_block)
    end
    end
    # 如果都通過檢查!!...
    return true
    end

    View Slide

  88. DATA
    4bb5fc9c
    獮㮆玟璸篷
    ୌ缏碻樌
    Block #0
    交易資料

    View Slide

  89. 默克爾樹
    Merkle Tree

    View Slide

  90. View Slide

  91. 展⽰示
    demo

    View Slide

  92. 未來來
    future?

    View Slide

  93. 區塊鏈是我們的未來來嗎?

    View Slide

  94. 投資理理財有賺有賠,申購前
    應詳閱公開說明書

    View Slide

  95. 以上
    end

    View Slide

  96. ⾼高⾒見見龍 Blog
    Facebook
    Twitter
    Email
    Mobile
    http://kaochenlong.com
    http://www.facebook.com/eddiekao
    https://twitter.com/eddiekao
    [email protected]
    +886-928-617-687

    View Slide