成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

構建第一個 Swift 區(qū)塊鏈應用

移動開發(fā)
區(qū)塊鏈作為一項革命性的技術,開始受到越來越多追捧。為什么呢?因為區(qū)塊鏈是許多加密數(shù)字貨幣的底層技術,比如:比特幣(BTC),以太坊(ETH)以及萊特幣(LTC)。區(qū)塊鏈具體是如何工作的?本篇教程會涵蓋所有區(qū)塊鏈相關的知識,還會教你如何構建 Swift 區(qū)塊鏈。下面讓我們開始吧!

區(qū)塊鏈作為一項革命性的技術,開始受到越來越多追捧。為什么呢?因為區(qū)塊鏈是許多加密數(shù)字貨幣的底層技術,比如:比特幣(BTC),以太坊(ETH)以及萊特幣(LTC)。區(qū)塊鏈具體是如何工作的?本篇教程會涵蓋所有區(qū)塊鏈相關的知識,還會教你如何構建 Swift 區(qū)塊鏈。下面讓我們開始吧!

區(qū)塊鏈的工作原理

顧名思義,區(qū)塊鏈是一條由不同區(qū)塊連接組成的鏈。每一個塊包含三個信息:數(shù)據(jù)、哈希(hash)、以及前置區(qū)塊的哈希。

  1. 數(shù)據(jù) – 由于應用場景不同,存儲在區(qū)塊中的數(shù)據(jù)由區(qū)塊鏈的類型決定。例如,在比特幣區(qū)塊鏈中,存儲的數(shù)據(jù)是交易信息:轉賬金額和交易雙方的信息。
  2. 哈希 – 你可以將哈??醋鰯?shù)字指紋,用來唯一標識一個區(qū)塊及其數(shù)據(jù)。哈希的重要之處在于它是一個獨特的字母數(shù)字代碼,通常是 64 個字符。當一個區(qū)塊被創(chuàng)建時,哈希也隨之創(chuàng)建。當一個區(qū)塊被修改,哈希也隨之修改。因此,當你想要查看在區(qū)塊上所做的任何變更時,哈希就顯得非常重要。
  3. 前置區(qū)塊的哈希 – 通過存儲前置區(qū)塊的哈希,你可以還原每個區(qū)塊連接成區(qū)塊鏈的過程!這使得區(qū)塊鏈安全性特別高。

我們來看下這張圖片:

 

區(qū)塊鏈
區(qū)塊鏈

你可以看到,每一個區(qū)塊包含數(shù)據(jù)(圖片中沒有指明)、哈希以及前置區(qū)塊的哈希。例如,黃色區(qū)塊包含自身的哈希:H7s6,以及紅色區(qū)塊的哈希:8SD9。這樣它們就構成了一條相互連接的鏈?,F(xiàn)在,假如有一個黑客準備惡意篡改紅色的區(qū)塊。請記住,每當塊以任何方式被篡改時,該區(qū)塊的哈希都會改變!當下一個區(qū)塊檢查并發(fā)現(xiàn)前置哈希不一致時,黑客將無法訪問它,因為他與前置區(qū)塊的聯(lián)系被切斷了(譯者注:即如果黑客想要要篡改一個區(qū)塊的話,就需要把這個區(qū)塊后面的所有區(qū)塊都要改掉,而這個工作量是很難實現(xiàn)的)。

這使得區(qū)塊鏈特別安全,幾乎不可能回滾或者篡改任何數(shù)據(jù)。雖然哈希為保密和隱私提供了巨大的保障,但是還有兩個更加安全妥當?shù)拇胧┳寘^(qū)塊鏈更加安全:工作量證明(Proof-of-Work)以及智能合約(Smart Contracts)。本文我不會深入講解,你可以在這里了解更多相關知識。

區(qū)塊鏈最后一個保證自身安全性的方式是基于其定位。和大多數(shù)存儲在服務器和數(shù)據(jù)庫的數(shù)據(jù)不同,區(qū)塊鏈使用的是點對點(P2P)網(wǎng)絡。P2P 是一種允許任何人加入的網(wǎng)絡,并且該網(wǎng)絡上的數(shù)據(jù)會分發(fā)給每一個接收者。

每當有人加入這個網(wǎng)絡,他們就會獲得一份區(qū)塊鏈的完整拷貝。每當有人新建一個區(qū)塊,就會廣播給全網(wǎng)。在將該塊添加到鏈之前,節(jié)點會通過幾個復雜的程序確定該塊是否被篡改。這樣,所有人、所有地方都可以使用這個信息。如果你是 HBO 美劇硅谷 的粉絲,對此應該不會感到陌生。在該劇中,主演(Richard)使用一種相似的技術創(chuàng)造了新型互聯(lián)網(wǎng)(譯者注:有趣的是劇中還發(fā)行了區(qū)塊鏈數(shù)字貨幣 PiedPaperCoin,感興趣的童鞋可以刷一下這部劇)。

因為每個人都有區(qū)塊鏈或者節(jié)點的一份拷貝,他們可以達成一種共識并決定哪部分區(qū)塊是有效的。因此,如果你想要攻擊某個區(qū)塊,你必須同時攻擊網(wǎng)絡上 50% 以上的區(qū)塊(譯者:51% 攻擊),使得你的區(qū)塊可以追上并替換原區(qū)塊鏈。所以區(qū)塊鏈或許是過去十年所創(chuàng)造的最安全的技術之一。

關于示例程序

現(xiàn)在你已經(jīng)對區(qū)塊鏈的原理有了初步的認識,那么我們就開始寫示例程序吧!你可以在這里下載原始項目。

如你所見,我們有兩個比特幣錢包。第一個賬戶 1065 有 500 BTC,而第二個賬戶 0217 沒有 BTC。我們通過 send 按鈕可以發(fā)送比特幣到另外的賬戶。為了賺取 BTC,我們可以點擊 Mine 按鈕,可以獲得 50 BTC 的獎勵。我們主要工作是查看控制臺輸出,觀察兩個賬戶間的交易過程。

 

這里寫圖片描述
這里寫圖片描述

在左側導航欄可以看到兩個很重要的類:Block 和 Blockchain。目前這兩個類都是空實現(xiàn),我會帶著你們在這兩個類中寫入相關邏輯。下面讓我們開始吧!

 

這里寫圖片描述
這里寫圖片描述

在 Swift 中定義區(qū)塊

首先打開 Block.swift 并添加定義區(qū)塊的代碼。在此之前,我們需要定義區(qū)塊是什么。前面我們曾定義過,區(qū)塊是由三部分組成:哈希、實際記錄的數(shù)據(jù)以及前置區(qū)塊的哈希。當我們想要構建我們的區(qū)塊鏈時,我們必須知道該區(qū)塊是第一個還是第二個。我們可以很容易地在 Swift 的類中做如下定義:

  1. var hash: String! 
  2. var data: String! 
  3. var previousHash: String! 
  4. var indexInt

現(xiàn)在需要添加最重要的代碼。我曾提過區(qū)塊在被修改的情況下,哈希也會隨之變化,這是區(qū)塊鏈如此安全的特性之一。因此我們需要創(chuàng)建一個函數(shù)去生成哈希,該哈希由隨機字母和數(shù)字組成。這個函數(shù)只需要幾行代碼:

  1. func generateHash() -> String { 
  2.     return NSUUID().uuidString.replacingOccurrences(of"-"with""

NSUUID 是一個代表通用唯一值的對象,并且可以橋接成 UUID。它可以快速地生成 32 個字符串。本函數(shù)生成一個 UUID,刪除其中的連接符,然后返回一個 String,最后將結果作為區(qū)塊的哈希。Block.swift 現(xiàn)在就像下面:

 

這里寫圖片描述
這里寫圖片描述

現(xiàn)在我們已經(jīng)定義好了 Block 類,下面來定義 Blockchain 類,首先切換到 Blockchain.swift 。

在 Swift 中定義區(qū)塊鏈

和之前一樣,首先分析區(qū)塊鏈的基本原理。用非常基礎的術語來說,區(qū)塊鏈只是由一連串的區(qū)塊連接而成,也可以說是一個由多個條目組成的列表。這是不是聽起來很熟悉呢?其實這就是數(shù)組的定義!而且這個數(shù)組是由區(qū)塊組成的!接下來添加以下代碼:

  1. var chain = [Block]() 

快速提示: 這個方法可以應用于計算機科學世界里的任何事物。如果你遇到大難題,可以嘗試把它分解成若干個小問題,以此來建立起解決問題的方法,正如我們解決在 Swift 中如何添加區(qū)塊和區(qū)塊鏈的問題。

你會注意到數(shù)組里面是我們前面定義的 Block 類,這就是區(qū)塊鏈所需要的所有變量。為了完成功能,我們還需要在類中添加兩個函數(shù)。請嘗試著根據(jù)我之前教過的方法解答這個問題。

區(qū)塊鏈中的兩個主要函數(shù)是什么?

我希望你能認真思考并回答這個問題!實際上,區(qū)塊鏈的兩個主要功能是創(chuàng)建創(chuàng)世區(qū)塊(最初的始塊),以及在其結尾添加新的區(qū)塊。當然現(xiàn)在我不打算實現(xiàn)分叉區(qū)塊鏈和添加智能合約的功能,但你必須了解這兩個是基本功能!將以下代碼添加到 Blockchain.swift:

  1. func createGenesisBlock(data:String) { 
  2.     let genesisBlock = Block() 
  3.     genesisBlock.hash = genesisBlock.generateHash() 
  4.     genesisBlock.data = data 
  5.     genesisBlock.previousHash = "0000" 
  6.     genesisBlock.index = 0 
  7.     chain.append(genesisBlock) 
  8.  
  9. func createBlock(data:String) { 
  10.     let newBlock = Block() 
  11.     newBlock.hash = newBlock.generateHash() 
  12.     newBlock.data = data 
  13.     newBlock.previousHash = chain[chain.count-1].hash 
  14.     newBlock.index = chain.count 
  15.     chain.append(newBlock) 

1、我們添加的第一個函數(shù)的作用是創(chuàng)建創(chuàng)世區(qū)塊。為此,我們創(chuàng)建了一個以區(qū)塊數(shù)據(jù)為入?yún)⒌暮瘮?shù)。然后定義了一個類型為 Block 的變量 genesisBlock,它擁有此前在 Block.swift 中定義的所有變量和函數(shù)。我們將 generateHash() 賦值給哈希,將輸入的 data 參數(shù)賦值給數(shù)據(jù)。由于這是第一個區(qū)塊,我們將前置區(qū)塊的哈希設為 0000,這樣我們就可以知道這是起始區(qū)塊。最后我們將 index 設為 0,并將這個區(qū)塊加入到區(qū)塊鏈中。

2、我們創(chuàng)建的第二個函數(shù)適用于 genesisBlock 之后的所有區(qū)塊,并且能創(chuàng)建剩余的區(qū)塊。你會注意到它與第一個函數(shù)非常相似。唯一的區(qū)別是,我們將 previousHash 的值設置為前一個區(qū)塊的哈希值,并將 index 設置為它在區(qū)塊鏈中的位置。就這樣,區(qū)塊鏈已經(jīng)定義好了!你的代碼應該看起來跟下圖一樣!

 

這里寫圖片描述
這里寫圖片描述

錢包后端

現(xiàn)在切換到 ViewController.swift,我們會發(fā)現(xiàn)所有的 outlet 都已經(jīng)連接好了。我們只需要處理交易,并將其輸出到控制臺。

然而在此之前,我們需要稍微研究一下比特幣的區(qū)塊鏈。比特幣是由一個總賬戶產(chǎn)生的,我們將這個賬號的編號稱為 0000。當你挖到一個 BTC,意味著你解決了數(shù)學問題,因此會發(fā)行一定數(shù)量的比特幣作為獎勵。這提供了一個發(fā)幣的高明方法,并且可以激勵更多人去挖礦。在我們的應用,讓我們把挖礦獎勵設為 100 BTC。首先,在視圖控制器中添加所需的變量:

  1. let firstAccount = 1065 
  2. let secondAccount = 0217 
  3. let bitcoinChain = Blockchain() 
  4. let reward = 100 
  5. var accounts: [String: Int] = ["0000": 10000000] 
  6. let invalidAlert = UIAlertController(title: "Invalid Transaction", message: "Please check the details of your transaction as we were unable to process this.", preferredStyle: .alert) 

首先定義號碼為 1065 和 0217 的兩個賬號。然后添加一個名為 bitcoinChain 的變量作為我們的區(qū)塊鏈,并將 reward 設為 100。我們需要一個主帳戶作為所有比特幣的來源:即創(chuàng)世帳戶 0000。里面有 1000 萬個比特幣。你可以把這個賬戶想象成一個銀行,所有因獎勵產(chǎn)生的 100 個比特幣都經(jīng)此發(fā)放到合法賬戶中。我們還定義了一個提醒彈窗,每當交易無法完成時就會彈出。

現(xiàn)在,讓我們來編寫幾個運行時需要的通用函數(shù)。你能猜出是什么函數(shù)嗎?

  1. 第一個函數(shù)是用來處理交易的。我們需要確保交易雙方的賬戶,能夠接收或扣除正確的金額,并將這些信息記錄到我們的區(qū)塊鏈中。
  2. 下一個函數(shù)是在控制臺中打印整個記錄 —— 它將顯示每個區(qū)塊及其中的數(shù)據(jù)。
  3. 最后一個是用于驗證區(qū)塊鏈是否有效的函數(shù),通過校驗下一個區(qū)塊的 previousHash 和上一個區(qū)塊 hash 是否匹配。由于我們不會演示任何黑客方法,因此在我們的示例程序中,區(qū)塊鏈是永遠有效的。

交易函數(shù)

下面是一個通用的交易函數(shù),請在我們定義的變量下方輸入以下代碼:

  1. func transaction(from: String, to: String, amount: Int, type: String) { 
  2.     // 1 
  3.     if accounts[from] == nil { 
  4.         self.present(invalidAlert, animated: true, completion: nil) 
  5.         return 
  6.     } else if accounts[from]!-amount < 0 { 
  7.         self.present(invalidAlert, animated: true, completion: nil) 
  8.         return 
  9.     } else { 
  10.         accounts.updateValue(accounts[from]!-amount, forKey: from
  11.     } 
  12.      
  13.     // 2 
  14.     if accounts[to] == nil { 
  15.         accounts.updateValue(amount, forKey: to
  16.     } else { 
  17.         accounts.updateValue(accounts[to]!+amount, forKey: to
  18.     } 
  19.      
  20.     // 3 
  21.     if type == "genesis" { 
  22.         bitcoinChain.createGenesisBlock(data: "From: \(from); To: \(to); Amount: \(amount)BTC"
  23.     } else if type == "normal" { 
  24.         bitcoinChain.createBlock(data: "From: \(from); To: \(to); Amount: \(amount)BTC"
  25.     } 

代碼量看起來好像很大,但主要是定義了每個交易需要遵循的一些規(guī)則。一開始是函數(shù)的四個參數(shù):

to,from,amount,type。前三個參數(shù)不需要再解釋了,而 Type 主要用于定義交易的類型。總共有兩個類型:正常類型(normal) 和創(chuàng)世類型(genesis)。正常類型的交易會發(fā)生在賬戶 1065 和 2017 之間,而創(chuàng)世類型將會涉及到賬戶 0000。

  1. 第一個 if-else 條件語句處理轉出賬戶的信息。如果賬戶不存在或者余額不足,將會提示交易不合法并返回。
  2. 第二個 if-else 條件語句處理轉入賬戶的信息。如果賬戶不存在,則創(chuàng)建新賬戶并轉入相應的比特幣。反之,則向該賬戶轉入正確數(shù)量的比特幣。
  3. 最后一個 if-else 條件語句處理交易類型。如果類型是創(chuàng)世類型,則添加一個創(chuàng)世區(qū)塊,否則創(chuàng)建一個新的區(qū)塊存儲數(shù)據(jù)。

打印函數(shù)

為了確保交易正確執(zhí)行,在每個交易結束后,我們希望拿到所有交易的清單。以下是我們在交易函數(shù)下方的代碼,用來打印相關信息:

  1. func chainState() { 
  2.     for i in 0...bitcoinChain.chain.count-1 { 
  3.         print("\tBlock: \(bitcoinChain.chain[i].index!)\n\tHash: \(bitcoinChain.chain[i].hash!)\n\tPreviousHash: \(bitcoinChain.chain[i].previousHash!)\n\tData: \(bitcoinChain.chain[i].data!)"
  4.     } 
  5.     redLabel.text = "Balance: \(accounts[String(describing: firstAccount)]!) BTC" 
  6.     blueLabel.text = "Balance: \(accounts[String(describing: secondAccount)]!) BTC" 
  7.     print(accounts) 
  8.     print(chainValidity()) 

這是一個簡單的循環(huán)語句,遍歷 bitcoinChain 中的所有區(qū)塊,并打印區(qū)塊號碼,哈希,前置哈希,以及存儲的數(shù)據(jù)。同時我們更新了界面中的標簽(label),這樣就可以顯示賬戶中正確的 BTC 數(shù)量。最后,打印所有的賬戶(應該是 3 個),并校驗區(qū)塊鏈的有效性。

現(xiàn)在你應該會在函數(shù)的最后一行發(fā)現(xiàn)一個錯誤。這是由于我們還沒有實現(xiàn) chainValidity() 函數(shù),讓我們馬上開始吧。

有效性函數(shù)

判斷一個鏈是否有效的標準是:前置區(qū)塊的哈希與當前區(qū)塊所表示的是否匹配。我們可以再次用循環(huán)語句來遍歷所有的區(qū)塊:

  1. func chainValidity() -> String { 
  2.     var isChainValid = true 
  3.     for i in 1...bitcoinChain.chain.count-1 { 
  4.         if bitcoinChain.chain[i].previousHash != bitcoinChain.chain[i-1].hash { 
  5.             isChainValid = false 
  6.         } 
  7.     } 
  8.     return "Chain is valid: \(isChainValid)\n" 

和之前一樣,我們遍歷了 bitcoinChain 中的所有區(qū)塊,并檢查了前置區(qū)塊的 hash 是否與當前區(qū)塊的 previousHash 一致。

就醬!我們已經(jīng)將定義了所有需要的函數(shù)!你的 ViewController.swift 應該如下圖一樣:

 

這里寫圖片描述
這里寫圖片描述

收尾工作就是連接按鈕和函數(shù)啦。讓我們馬上開始最后的部分吧!

讓一切關聯(lián)起來

當我們的應用第一次啟動時,需要創(chuàng)世賬戶 0000 發(fā)送 50 BTC 到我們的第一個賬戶。再從第一個賬戶轉賬 10 BTC 到第二個賬戶,這只需要寥寥三行代碼。最后 viewDidLoad 中的代碼如下:

  1. override func viewDidLoad() { 
  2.     super.viewDidLoad() 
  3.     transaction(from"0000"to"\(firstAccount)", amount: 50, type: "genesis"
  4.     transaction(from"\(firstAccount)"to"\(secondAccount)", amount: 10, type: "normal"
  5.     chainState() 
  6.     self.invalidAlert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) 

我們使用已定義好的函數(shù)轉賬,并調(diào)用 chainState() 函數(shù)。最后,我們還在 invalidAlert 中添加了一個標題為 OK 的 UIAlertAction。

現(xiàn)在讓我們來實現(xiàn)剩下的四個函數(shù):ReMeNe()、BrimeMeNe()、ReSdEnter()和BuLeScript()。

挖礦函數(shù)

挖礦函數(shù)特別簡單,只需要三行代碼。添加以下代碼:

  1. @IBAction func redMine(_ sender: Any) { 
  2.     transaction(from"0000"to"\(firstAccount)", amount: 100, type: "normal"
  3.     print("New block mined by: \(firstAccount)"
  4.     chainState() 
  5.      
  6. @IBAction func blueMine(_ sender: Any) { 
  7.     transaction(from"0000"to"\(secondAccount)", amount: 100, type: "normal"
  8.     print("New block mined by: \(secondAccount)"
  9.     chainState() 

在第一個挖礦函數(shù)中,我們使用交易函數(shù)從創(chuàng)世賬戶發(fā)送了 100 BTC 到第一個賬戶。我們打印了挖礦的區(qū)塊,然后打印了區(qū)塊鏈的狀態(tài)。同樣地,在 blueMine 函數(shù)中,我們轉給了第二個賬戶 100 BTC。

發(fā)送函數(shù)

發(fā)送函數(shù)和挖礦函數(shù)略微相似:

  1. @IBAction func redSend(_ sender: Any) { 
  2.     if redAmount.text == "" { 
  3.         present(invalidAlert, animated: true, completion: nil) 
  4.     } else { 
  5.         transaction(from"\(firstAccount)"to"\(secondAccount)", amount: Int(redAmount.text!)!, type: "normal"
  6.         print("\(redAmount.text!) BTC sent from \(firstAccount) to \(secondAccount)"
  7.         chainState() 
  8.         redAmount.text = "" 
  9.     } 
  10.      
  11. @IBAction func blueSend(_ sender: Any) { 
  12.     if blueAmount.text == "" { 
  13.         present(invalidAlert, animated: true, completion: nil) 
  14.     } else { 
  15.         transaction(from"\(secondAccount)"to"\(firstAccount)", amount: Int(blueAmount.text!)!, type: "normal"
  16.         print("\(blueAmount.text!) BTC sent from \(secondAccount) to \(firstAccount)"
  17.         chainState() 
  18.         blueAmount.text = "" 
  19.     } 

首先,我們檢查 redAmount 或者 blueAmount 的文本值是否為空。如果為空,則彈出無效交易的提示框。如果不為空,則繼續(xù)下一步。我們使用交易函數(shù)從第一個賬戶轉賬到第二個賬戶(或者反向轉賬),金額為輸入的數(shù)量。我們打印轉賬金額,并調(diào)用 chainState() 方法。最后,清空文本框。

就醬,工作完成!請檢查你的代碼是否和圖中一致:

 

這里寫圖片描述
這里寫圖片描述

現(xiàn)在運行應用并測試一下。從前端看,這就像一個正常的交易應用,但是運行在屏幕背后的可是區(qū)塊鏈啊!請嘗試使用應用將 BTC 從一個帳戶轉移到另一個帳戶,隨意測試,盡情把玩吧!

結論

在這個教程中,你已經(jīng)學會了如何使用 Swift 創(chuàng)建區(qū)塊鏈,并且創(chuàng)建了你自己的比特幣交易系統(tǒng)。請注意,真正加密貨幣的后端,和我們上面的實現(xiàn)完全不一樣,因為它需要用智能合約實現(xiàn)分布式,而本例僅用于學習。

在這個示例中,我們將區(qū)塊鏈技術應用于加密貨幣,然而你能想到區(qū)塊鏈的其他應用場景嗎?請留言分享給大家!希望你能學到更多新東西!

為了參考,你可以從 GitHub 下載完整的示例。

責任編輯:未麗燕 來源: Swift翻譯組
相關推薦

2013-01-14 09:44:58

JavaScriptJSJS框架

2018-03-19 17:40:10

Python區(qū)塊鏈

2021-04-07 13:38:27

Django項目視圖

2010-07-30 14:58:06

Flex應用

2012-02-08 11:15:38

HibernateJava

2018-07-30 14:28:22

2023-10-09 14:32:48

2018-11-08 13:53:15

Flink程序環(huán)境

2023-05-19 08:49:58

SQLAlchemy數(shù)據(jù)庫

2014-12-24 11:34:23

CoreOSWordPress集群部署

2020-11-13 07:08:51

Spring Boot應用Spring

2018-05-24 23:41:45

2019-12-31 08:00:00

DebianLinuxApple Swift

2021-04-03 12:31:48

Python開發(fā)數(shù)據(jù)科學

2010-12-07 16:53:43

商業(yè)智能

2018-01-31 15:45:07

前端Vue.js組件

2022-05-19 14:23:09

區(qū)塊鏈數(shù)字化轉型SWIFT

2018-06-14 11:02:37

區(qū)塊鏈支付寶去中心化

2015-04-15 11:28:04

Apple Watch殺手應用

2011-06-08 10:01:36

Windows Pho 應用程序
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美成人一区二区三区片免费 | 国产精产国品一二三产区视频 | 欧美一级片中文字幕 | 在线观看中文字幕av | 日韩欧美一级片 | 黑人巨大精品欧美一区二区免费 | 国产午夜一级 | 国产精品成人一区二区三区 | 日本精品一区二区三区在线观看 | 久久99精品久久久久久噜噜 | 男女下面一进一出网站 | 美女爽到呻吟久久久久 | 欧美视频日韩 | 欧美一区二区三区 | 一区二区三区视频在线观看 | 日韩欧美在线观看 | 美女久久久 | 九九久久这里只有精品 | 欧美电影一区 | 亚洲a视频 | 色婷婷综合久久久中文字幕 | 二区三区视频 | 久久99精品久久久97夜夜嗨 | 国产欧美精品一区二区色综合 | 久久免费看 | 国产精品久久 | 一区中文字幕 | 欧美亚洲另类丝袜综合网动图 | 日本电影一区二区 | 成人免费在线小视频 | www.天堂av.com | 亚洲成人中文字幕 | 国产91视频播放 | 国精久久| 操操操日日日 | 亚洲一区二区三区四区五区午夜 | 成人小视频在线观看 | 午夜久久久久 | 日韩一区二区三区在线视频 | 天天操天天天干 | 成人欧美一区二区三区黑人孕妇 |