Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

源起 why this topic?

Slide 7

Slide 7 text

1 BTC vs. 19,000 USD

Slide 8

Slide 8 text

時代在變

Slide 9

Slide 9 text

動⼿手實作 learning by coding

Slide 10

Slide 10 text

⼤大綱 agenda

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

科普 popular science

Slide 18

Slide 18 text

區塊 block

Slide 19

Slide 19 text

區塊 = 資料結構 data structure

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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 初始化

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

# 程式執⾏行行結果

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

# # # 串起來了 程式執⾏行行結果

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

創世 Genesis block

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

彩蛋 surprise!

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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 這裡!

Slide 35

Slide 35 text

鏈條 chain

Slide 36

Slide 36 text

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 創世區塊 初始化

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

程式執⾏行行結果 #]> 當個創世神!

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

挖礦 mining

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

使用「輕薄的假象」

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

⼯工作證明 prove of work (PoW)

Slide 51

Slide 51 text

雪崩效應 Avalanche Effect

Slide 52

Slide 52 text

打到這裡 才算成功

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

隨機數 Nonce = Number use once

Slide 55

Slide 55 text

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 開始 隨機數 隨機數

Slide 56

Slide 56 text

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 ++

Slide 57

Slide 57 text

⼗十分鐘

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

記賬 ledger book

Slide 63

Slide 63 text

區塊鏈 == 記賬本

Slide 64

Slide 64 text

花錢 spend mondy

Slide 65

Slide 65 text

銀⾏行行轉帳

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

交易易 Transaction

Slide 70

Slide 70 text

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 要說清楚這是 要給誰的錢

Slide 71

Slide 71 text

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 交易先放 在這裡 丟進池子裡 一開始是 空的

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

程式執⾏行行結果 #], @transaction_pool= [#]> 待確認交易

Slide 74

Slide 74 text

把⼼心情哼成歌

Slide 75

Slide 75 text

把交易易挖成礦!

Slide 76

Slide 76 text

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 挖礦完成 清除交易

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

程式執⾏行行結果 #, #], @hash="000f737c1008bfc27be216e5147dbd67079894b34fbeca5b5bf04699a28e2bea", @nonce=4688, @previous_hash= "00002669323dbc9e5d9f6f43b7f29094939b3ba1f2c863e33af7ba00ab2d5b2e", @timestamp=1531780941>], @transaction_pool=[]> 交易清掉了 產生了新 的區塊

Slide 79

Slide 79 text

散⼾戶挖得到嗎?

Slide 80

Slide 80 text

打不贏他,就加入他!

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

分叉 fork

Slide 83

Slide 83 text

廣播、講八卦!

Slide 84

Slide 84 text

如果差不多時間挖到?

Slide 85

Slide 85 text

驗證 validation

Slide 86

Slide 86 text

No content

Slide 87

Slide 87 text

檔案: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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

默克爾樹 Merkle Tree

Slide 90

Slide 90 text

No content

Slide 91

Slide 91 text

展⽰示 demo

Slide 92

Slide 92 text

未來來 future?

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

以上 end

Slide 96

Slide 96 text

⾼高⾒見見龍 Blog Facebook Twitter Email Mobile http://kaochenlong.com http://www.facebook.com/eddiekao https://twitter.com/eddiekao eddie@5xruby.tw +886-928-617-687