SITOCN 2018 議程筆記

由淺入坑區塊鏈~從認識架構到應用智能合約! - 牟展佑

開場影片

講者資訊

  • 松資活動/總務
  • 學長推坑SITCON
  • 偏好將資訊結合金融領域
  • 願在成為工具人之前成長茁壯(?

Part 0 銀行、中心化、比特幣到去中心化

貨幣

  • 以物易物>金銀銅鐵錫>法幣>信用卡
  • 法定貨幣缺點: 中心化

Part 1 區塊鏈架構

數位簽章(電腦的帳本)

  • 雜湊(hash)演算法SHA-256
  • 交易事件加密(簽章)

加密

  • 對稱加密: 相同鑰匙加密解密
  • 非對稱加密: 分為私鑰和公鑰,私鑰加密公鑰解密

礦工收到: 紀錄 簽章

  1. SHA-256(紀錄) >雜湊1
  2. 用私鑰加密
  3. 加密雜湊 >簽章
  4. 用公鑰解密 >雜湊
  5. SHA-256(紀錄) > 雜湊2
  6. 驗證 雜湊1 == 雜湊2

去中心化

  1. 把元改成BTC(加密)
  2. 把需要根付換成支付(數位簽章)
  3. 確認支付量(無法查詢餘額故每筆交易都以過去的交易作為基礎)
  4. 交易雙方的名字改成帳號(避免重名)
  5. 轉帳紀錄存於各節點

一致性問題

  • 避免紀錄竄改->區塊相連
  • 紀錄同步->產生新區塊
  • 避免重複使用->每筆交易會和前一個來源一起加密

如何實現

  • hash 區塊 > hash值前72位為0 > 挖到礦
  • CPU > GPU > 礦機 > 一堆礦機(礦場)

獎勵機制

  1. 挖到得到 12.5BTC(2017)
  2. 交易手續費

    算力過剩

  • 調整難度

    同時產生區塊?

  • 保留最長的區塊

小結

* 利用SHA-256 & 非對稱加密製作數字簽名
* 利用區塊練儲存交易紀錄
* 設置外的工作控制單位時間生產數
* 將一定數量比特幣發給礦工,促進成長
* 轉帳不依賴任何銀行或政府機構
* 比特幣網路內總量不超過2100萬個比特幣

交易方式

  • 場外交易:信任的人
  • 場內交易:交易所(bitoex、maicoin)

Part 2 從比特幣到以太坊

  • 把數字改成文字

    Etherenum

  • 智能合約
  • 快速驗證(1min以下)
  • 有錢就可做到無窮迴圈(有錢就是任性?)
  • 目前無專用礦機
智能合約
  • Browser-
  • Geth:讓我們能夠執行合約..等
  • Mist:錢包

智能合約的應用 ex:勞基法 老闆有智能合約 ->加班的錢放入智能合約->判斷要給錢給員工(員工加班)還是退還老闆(員工放假)

Part 3 區塊練3.0

SITCON 夏令營 2017 chatbot 共筆

一小隊 2017 SITCON 夏令營 bot 共筆

bot目的:處理日常金融用途1

@book_keeping_bot


日常記帳

  • 收/支出、時間、內容、金額、總金額
        * 記錄前次內容提供清空
        * 將記帳紀錄固定於單一訊息
    

指令:

  • /list:將目前表格秀出

         讓用戶可選擇要編輯的訊息
    
  • 輸入順序:收入(+)/支出(-) 項目 金額

         直接設定成表格填空
         從使用者API中提取時間
    
  • /start 開始說明

    book-keeping, [19.01.18 13:10]
    OK, William
    你準備好了…… 讓我們開始記帳吧

book-keeping, [19.01.18 13:10]
記帳請依序輸入 /add +/-

book-keeping, [19.01.18 13:10]
請輸入/list查看帳本,輸入/total 獲取總資產

book-keeping, [19.01.18 13:10]
借款請依序輸入 /lend <@username>

book-keeping, [19.01.18 13:10]
查看借貸請輸入 /ldict <@username>


user借還錢

  • 借貸時間、內容、金額、備註
        * 利用@表示被借錢者
        * 借還錢時與@確認借據正確性
         
         指令:將目前欠款人統一成一張清單
         指令:查詢目前欠款紀錄
         指令:查詢歷史借款人(username/借款次數、金額
         
    

借貸實際測試範例

William Mou, [19.01.18 13:10]
/lend @WilliamMou 100

book-keeping, [19.01.18 13:10]
借款給 @WilliamMou 100元

book-keeping, [19.01.18 13:10]
請借款人 @WilliamMou 回傳 /borrow @WilliamMou 1516338639 驗證

William Mou, [19.01.18 13:10]
/borrow @WilliamMou 1516338639

book-keeping, [19.01.18 13:10]
提醒:輸入 /payback @WilliamMou 1516338639 還款

William Mou, [19.01.18 13:11]
/ldict @WilliamMou

book-keeping, [19.01.18 13:11]
欠款確認,欠100元


Bot架構

      array:
          0:
              id:
              time:
              type:
              proj:
              money:
              total:
          ...

相關bot

bot:
@RawDataBot

相關網站

bot&python3
telegpot說明文件
python telegram定義
git版本控制

技術問題

  1. telegram如何輸出適合螢幕大小的記帳表格

```python=

-- coding: utf8 --

import telepot
from telepot.loop import MessageLoop
from telepot.namedtuple import (
ReplyKeyboardMarkup,
KeyboardButton,
InlineKeyboardMarkup,
InlineKeyboardButton
)
from random import choice
import json
import time

TOKEN = ‘’

bot = telepot.Bot(TOKEN)
telBot=telepot.Bot (TOKEN)
Bot_inf=telBot.getMe()

#資料結構:{chatid:[[+-,money,event],[+-,money,even],[+-,money,even]]}
moneydict={}
#資料傑{idtousername:{data:[1,]}} 0:未確認 1:確認 2:還款確認 pop:還款完成
lenddict={}

def print_msg(msg):
print(json.dumps(msg, indent=10))

def on_chat(msg):
print_msg(msg)
print(“~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~”)
header = telepot.glance(msg, flavor=”chat”,long =True)
data=””
if header[0] == “text”:
text = msg[“text”]
# command
if text.startswith(“/“):
command = text.lstrip(“/“)

        if command == "start":
            text = "OK, {}\n你準備好了...... 讓我們開始記帳吧"
            bot.sendMessage(header[2], text.format(msg["from"]["first_name"]))
            bot.sendMessage(header[2], "記帳請依序輸入 /add +/- <money> <porj>")
            bot.sendMessage(header[2], "請輸入/list查看帳本,輸入/total 獲取總資產")
            bot.sendMessage(header[2], "借款請依序輸入 /lend <@username> <money> <porj>")
            bot.sendMessage(header[2], "查看借貸請輸入 /ldict <@username>")
            
        elif command[:3] == "add":
            #data=[+-,money,event]
            data=command[3:].split()
            if data[0] == '+' or data[0]=='-':
                try:
                    int(data[1])
                    bot.sendMessage(header[2],"增加收支細項"+str(data[2]))
                    if header[2] in moneydict:
                        moneydict[header[2]].append(data)
                    else:
                        moneydict[header[2]]=[data]
                    bot.sendMessage(header[2],"收支帳本"+str(moneydict[header[2]]))
                except:
                    bot.sendMessage(header[2],"請符合格式ouo")
            else:
                bot.sendMessage(header[2],"請符合格式ouo")

        elif command[:4] == "lend":
            data=command[4:].split()
            bot.sendMessage(header[2],"借款給 "+str(data[0])+" "+str(data[1])+"元")
            if msg["from"]["username"]+"to"+str(data[0][1:]) in lenddict:
                lenddict[str(msg["from"]["username"])+"to"+str(data[0][1:])][msg["date"]]=[0,str(data[1])]
            else:
                lenddict[str(msg["from"]["username"])+"to"+str(data[0][1:])]={msg["date"]:[0,str(data[1])]}

            bot.sendMessage(header[2],"請借款人 "+str(data[0])+" 回傳 /borrow @"+str(msg["from"]["username"])+" "+str(msg["date"])+" 驗證")
            #bot.sendMessage(header[2],str(lenddict))

            '''
            if str(msg["from"]["username"])+"to"+str(data[0]) in lenddict:
                lenddict[str(msg["from"]["username"])+"to"+str(data[0])]={msg[data]:0}
                bot.sendMessage(header[2],0)
            else:
                lenddict[str(msg["from"]["username"])+"to"+str(data[0])]={msg[data]:0}
            '''    
        #commond: /borrow @username date
        elif command[:6] == "borrow":
            data=command[6:].split()
            lenddict[data[0][1:]+"to"+msg["from"]["username"]][int(data[1])][0]=1
            #bot.sendMessage(header[2],str(lenddict))
            bot.sendMessage(header[2],"提醒:輸入 /payback " + data[0] + " " +data[1]+" 還款")
            
        #commond: /payback @username date
        elif command[:7] == "payback":
            data=command[7:].split()
            lenddict[data[0][1:]+"to"+msg["from"]["username"]][int(data[1])][0]=2
            bot.sendMessage(header[2],"請 "+data[0]+" 確認 @"+str(msg["from"]["username"])+" 是否還款,並輸入 /payok @"+msg["from"]["username"]+" "+str(data[1])+" 確認")
            
        #commond: /payok @username date
        elif command[:5] == "payok":
            data=command[5:].split()
            lenddict[msg["from"]["username"]+"to"+data[0][1:]].pop(int(data[1]))
            bot.sendMessage(header[2],"還款確認完成><資料已核銷")
            
        elif command == "list":
            for i in range(len(moneydict[header[2]])):
                bot.sendMessage(header[2],"收支帳本"+str(moneydict[header[2]][i]))
                
        # /ldict @username
        elif command[:5] == "ldict":
            data=command[5:].split()
            if msg["from"]["username"]+"to"+data[0][1:] in lenddict:
            #for i in lenddict[msg["from"]["username"]+"to"+data[0][1:]]:
                for i in lenddict[msg["from"]["username"]+"to"+data[0][1:]]:
                    if lenddict[msg["from"]["username"]+"to"+data[0][1:]][i][0]==0:
                        bot.sendMessage(header[2]," 欠款待確認,欠"+str(lenddict[msg["from"]["username"]+"to"+data[0][1:]][i][1])+"元")
                    elif lenddict[msg["from"]["username"]+"to"+data[0][1:]][i][0]==1:
                        bot.sendMessage(header[2]," 欠款確認,欠"+str(lenddict[msg["from"]["username"]+"to"+data[0][1:]][i][1])+"元")
                    elif lenddict[msg["from"]["username"]+"to"+data[0][1:]][i][0]==2:
                        bot.sendMessage(header[2]," 還款待確認,欠"+str(lenddict[msg["from"]["username"]+"to"+data[0][1:]][i][1])+"元")
            else:
                bot.sendMessage(header[2],str(data[0])+" 暫無欠您的款項")
                
        elif command[:5] == "total":
            s=0
            for i in range(len(moneydict[msg['chat']['id']])):
                if moneydict[msg['chat']['id']][i][0]=='+':
                    try:
                        s+=int(moneydict[msg['chat']['id']][i][1])
                    except:
                        pass
                else:
                    try:
                        s-=int(moneydict[msg['chat']['id']][i][1])
                    except:
                        pass
            bot.sendMessage(header[2],str(msg['chat']['id'])+"總資產:"+str(s))
        
        elif command[:9] == "del_list":
            del moneydict[msg['chat']['id']]
            bot.sendMessage(header[2],"以清除您的儲蓄列表")
          


    # other msg
    #else: 
        # 我覺得不行!
        #image_url = "https://cdn.pixabay.com/photo/2016/03/22/23/45/money-1273908_960_720.jpg"
        #bot.sendPhoto(header[2], image_url)
#bot.sendMessage(header[2],"輸入/start查看指令")
    if "@all" in msg["text"]:
        admins_list=[]
        admins_dict=telBot.getChatAdministrators (msg["chat"]["id"])
        chat_name=msg["chat"]["title"].encode('utf8')
        print(admins_dict)
        for admin in admins_dict:
            if 'username' in admin['user']:
                admins_list.append('@'+str(admin['user']["username"])+" ")
            else:
                user_id=admin["user"]["id"]

                try :
                    first_name=admin["user"]["first_name"]
                except:
                    pass
                try :
                    last_name=admin["user"]["last_name"]
                except:
                    pass
                try:
                    admins_list.append('@ '+first_name+" "+last_name)
                except:
                    try:
                        admins_list.append('@'+first_name)
                    except:
                        pass
                    try:
                        admins_list.append('@'+last_name)  
                    except:
                        pass
            print(admins_list)
        send=""
        for admin in admins_list:
            send+= admin + " "
        bot.sendMessage(header[2], send)
        print(admins_list)
    
    if "@book_keeping_bot 閉嘴" in msg["text"] or "shut up" in msg["text"]:
        bot.sendMessage(header[2], '@' + msg['from']['username'] + " 對不起Q.Q")
        time.sleep(5)
        bot.sendMessage(header[2], '@' + msg['from']['username'] + " 你以為我會這樣說ㄇ?")
        bot.sendMessage(header[2], '@' + msg['from']['username'] + "\n\

——————/´ ¯/) \n
—————–/—-/ \n
—————-/—-/ \n
———–/´¯/‘–’/´¯`·\n
———-/‘/–/—-/—–/¨¯\n
——–(‘(———- ¯~/‘–’)\n
———\————-‘—–/\n
———-‘'————
-·´\n
————\———–(\n
————-\———– “)

    elif "@book_keeping_bot" in msg["text"]:

        bot.sendMessage(header[2], '@' + msg['from']['username'] + " 我可是很忙得")
        image_url ="https://www.moedict.tw/%E5%88%B7%E5%88%B7.png"
        bot.sendMessage(header[2], '@' + msg['from']['username'] + " 找我有啥事情?")
        bot.sendMessage(header[2],"孤單寂寞覺得冷?")
        bot.sendMessage(header[2],"簡單,我可以陪你刷起來!")
        for ii in range(3):
            bot.sendPhoto(header[2], image_url)
            
    
    

MessageLoop(bot, {
‘chat’: on_chat,
#’callback_query’: on_callback_query,
}).run_as_thread()

print(‘Listening …’)