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

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

F2dcf6633971844e19ca96ea294ba976?s=128

高見龍

July 18, 2018
Tweet

Transcript

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

  2. a.k.a Eddie 愛現! 喜歡冷門的玩具 Ruby/Rails/iOS app 開發者、講師 Ruby 技術推廣、教育、諮詢 台灣、日本等國內外

    Ruby 技術研討會講者 目前於五倍紅寶石擔任紅寶石鑑定商職務 部落格:https://kaochenlong.com 高見龍 photo by Eddie @eddiekao !
  3. None
  4. 發售中! https://gitbook.tw/ 第五刷

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

  6. 源起 why this topic?

  7. 1 BTC vs. 19,000 USD

  8. 時代在變

  9. 動⼿手實作 learning by coding

  10. ⼤大綱 agenda

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

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

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

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

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

  16. None
  17. 科普 popular science

  18. 區塊 block

  19. 區塊 = 資料結構 data structure

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

  21. DATA 4bb5fc9c 獮㮆玟璸篷 ୌ缏碻樌 Block #0 DATA 51e15133 獮㮆玟璸EEIFF ୌ缏碻樌

    Block #1 DATA 7a44fb64 獮㮆玟璸H ୌ缏碻樌 Block #2 DATA 00bbedf4 獮㮆玟璸DIE ୌ缏碻樌 Block #3 區塊 鏈
  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 初始化
  23. def calculate_hash content = "!#{previous_hash}!#{timestamp}!#{data}" Digest!::SHA256.hexdigest(content) end 檔案:app/block.rb SHA256

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

    檔案:playground/playground001.rb
  25. #<Block:0x00007f93461bf040 @data="我要變成海海賊王!", @hash="b39737768aac9bf8361db4d8658b3f82a76578ae33a5f4e7a326ea07a01e6c9c", @previous_hash="00000000000000", @timestamp=1531777292> 程式執⾏行行結果

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

  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
  28. #<Block:0x00007f970588ec78 @data="我要變成海海賊王!", @hash="c4a14f3d783c02b0d3a7bf82556ad5093ab77b13d2ae95758e923d0f63a7158f", @previous_hash="0000000000000000", @timestamp=1531777461> #<Block:0x00007f970588dfd0 @data="我是 1 號區塊!", @hash="d988cbedbd78d697c197e2c7d821184e92f0f20a18e79cedb8c7d2c0a2c66584",

    @previous_hash= "c4a14f3d783c02b0d3a7bf82556ad5093ab77b13d2ae95758e923d0f63a7158f", @timestamp=1531777461> #<Block:0x00007f970588de18 @data="我是 2 號區塊!", @hash="9d80de727301cc51a34b0777cfb0eb64a689b0714c68c1b03151c616616fef9f", @previous_hash= "d988cbedbd78d697c197e2c7d821184e92f0f20a18e79cedb8c7d2c0a2c66584", @timestamp=1531777461> 串起來了 程式執⾏行行結果
  29. None
  30. 創世 Genesis block

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

  32. 彩蛋 surprise!

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

    banks
  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 這裡!
  35. 鏈條 chain

  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 創世區塊 初始化
  37. require 'pp' require_relative '!../app/blockchain' blockchain = Blockchain.new pp blockchain 檔案:playground/playground003.rb

  38. 程式執⾏行行結果 #<Blockchain:0x00007ffa4a83db68 @chain= [#<Block:0x00007ffa4a83dac8 @data="2018/7/18 我宣佈參參選天龍國國王,我要變成海海賊王!", @hash="e3c4d673665a03d9810b6dc3fb1aa7422bac27d3653f0a6fb9f9b07ecb841a1d", @previous_hash= "0000000000000000000000000000000000000000000000000000000000000000", @timestamp=1531778950>]>

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

  40. 挖礦 mining

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

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

  43. 使用「輕薄的假象」

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

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

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

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

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

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

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

  51. 雪崩效應 Avalanche Effect

  52. 打到這裡 才算成功

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

  54. 隨機數 Nonce = Number use once

  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 開始 隨機數 隨機數
  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 ++
  57. ⼗十分鐘

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

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

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

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

  62. 記賬 ledger book

  63. 區塊鏈 == 記賬本

  64. 花錢 spend mondy

  65. 銀⾏行行轉帳

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

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

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

  69. 交易易 Transaction

  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 要說清楚這是 要給誰的錢
  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 交易先放 在這裡 丟進池子裡 一開始是 空的
  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
  73. 程式執⾏行行結果 #<Blockchain:0x00007fa9839873b0 @chain= [#<Block:0x00007fa9839872c0 @data="2018/7/18 我宣佈參參選天龍國國王,我要變成海海賊王!", @hash="00038d02b7b99602bfcb9d96d83018de687cdeb5ac8280cc69bc3f707f19b4bf", @nonce=1279, @previous_hash= "0000000000000000000000000000000000000000000000000000000000000000",

    @timestamp=1531780614>], @transaction_pool= [#<Transaction:0x00007fa985033d48 @amount=10, @from="Eddie", @timestamp=1531780614, @to="Sherly">]> 待確認交易
  74. 把⼼心情哼成歌

  75. 把交易易挖成礦!

  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 挖礦完成 清除交易
  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
  78. 程式執⾏行行結果 #<Blockchain:0x00007f93fe9b2938 @chain= [#<Block:0x00007f93fe9b27f8 @data="2018/7/18 我宣佈參參選天龍國國王,我要變成海海賊王!", @hash="00002669323dbc9e5d9f6f43b7f29094939b3ba1f2c863e33af7ba00ab2d5b2e", @nonce=4273, @previous_hash= "0000000000000000000000000000000000000000000000000000000000000000",

    @timestamp=1531780941>, #<Block:0x00007f93ff04cf28 @data= [#<Transaction:0x00007f93ff04d040 @amount=10, @from="Eddie", @timestamp=1531780941, @to="Sherly">], @hash="000f737c1008bfc27be216e5147dbd67079894b34fbeca5b5bf04699a28e2bea", @nonce=4688, @previous_hash= "00002669323dbc9e5d9f6f43b7f29094939b3ba1f2c863e33af7ba00ab2d5b2e", @timestamp=1531780941>], @transaction_pool=[]> 交易清掉了 產生了新 的區塊
  79. 散⼾戶挖得到嗎?

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

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

  82. 分叉 fork

  83. 廣播、講八卦!

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

  85. 驗證 validation

  86. None
  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
  88. DATA 4bb5fc9c 獮㮆玟璸篷 ୌ缏碻樌 Block #0 交易資料

  89. 默克爾樹 Merkle Tree

  90. None
  91. 展⽰示 demo

  92. 未來來 future?

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

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

  95. 以上 end

  96. ⾼高⾒見見龍 Blog Facebook Twitter Email Mobile http://kaochenlong.com http://www.facebook.com/eddiekao https://twitter.com/eddiekao eddie@5xruby.tw

    +886-928-617-687