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

    Ruby 技術研討會講者 目前於五倍紅寶石擔任紅寶石鑑定商職務 部落格:https://kaochenlong.com 高見龍 photo by Eddie @eddiekao !
  2. DATA 4bb5fc9c 獮㮆玟璸篷 ୌ缏碻樌 Block #0 DATA 51e15133 獮㮆玟璸EEIFF ୌ缏碻樌

    Block #1 DATA 7a44fb64 獮㮆玟璸H ୌ缏碻樌 Block #2 DATA 00bbedf4 獮㮆玟璸DIE ୌ缏碻樌 Block #3 區塊 鏈
  3. 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 初始化
  4. 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
  5. #<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> 串起來了 程式執⾏行行結果
  6. 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 這裡!
  7. 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 創世區塊 初始化
  8. 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 開始 隨機數 隨機數
  9. 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 ++
  10. 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 要說清楚這是 要給誰的錢
  11. 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 交易先放 在這裡 丟進池子裡 一開始是 空的
  12. 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
  13. 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 挖礦完成 清除交易
  14. 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
  15. 程式執⾏行行結果 #<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=[]> 交易清掉了 產生了新 的區塊
  16. 檔案: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