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

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

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

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

Avatar for 高見龍

高見龍

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