詳解區(qū)塊鏈P2P網(wǎng)絡

根據(jù)前一篇文章《從微觀到宏觀理解區(qū)塊鏈》我們已經(jīng)了解到她奥,微觀上黎做,區(qū)塊鏈本質(zhì)就是一種不可篡改且可追蹤溯源的哈希鏈條;宏觀上靖避,還具備了另外三個基本特征:分布式存儲、P2P 網(wǎng)絡和共識機制比默。分布式存儲無非就是網(wǎng)絡上大部分節(jié)點都保存了整條區(qū)塊鏈幻捏,這容易理解也不復雜,所以就沒必要再展開細講了命咐。但區(qū)塊鏈的 P2P 網(wǎng)絡和共識機制相對則復雜得多粘咖,因此我將用兩篇文章分別展開講講這兩部分內(nèi)容,本篇文章就先來了解區(qū)塊鏈的 P2P 網(wǎng)絡侈百。

P2P 網(wǎng)絡

由于大部分人對 P2P 網(wǎng)絡了解甚少瓮下,因此有必要先聊聊 P2P 網(wǎng)絡的一些基本原理翰铡。這個章節(jié)的內(nèi)容主要來自《P2P對等網(wǎng)絡原理與應用》這本書,這本書較為系統(tǒng)地介紹了 P2P 的理論基礎(chǔ)讽坏,非常適合希望全面掌握 P2P 知識的初級讀者锭魔,建議大伙都可以看看。

P2P 網(wǎng)絡不同于傳統(tǒng)的客戶端/服務端(client/server,C/S)結(jié)構(gòu)路呜,P2P 網(wǎng)絡中的每個節(jié)點都可以既是客戶端也是服務端迷捧,因此也不適合使用 HTTP 協(xié)議進行節(jié)點之間的通信,一般都是直接使用 Socket 進行網(wǎng)絡編程胀葱。

P2P 主要存在四種不同的網(wǎng)絡模型漠秋,也代表著 P2P 技術(shù)的四個發(fā)展階段:集中式、純分布式抵屿、混合式和結(jié)構(gòu)化模型庆锦。不過需要指出的是,這里所說的網(wǎng)絡模型主要是指路由查詢結(jié)構(gòu)轧葛,即不同節(jié)點之間如何建立連接通道搂抒,兩個節(jié)點之間一旦建立連接,具體傳輸什么數(shù)據(jù)則是兩個節(jié)點之間的事情了尿扯。

最簡單的路由方式就是集中式求晶,即存在一個中心節(jié)點保存了其他所有節(jié)點的索引信息,索引信息一般包括節(jié)點 IP 地址衷笋、端口芳杏、節(jié)點資源等。集中式路由的優(yōu)點就是結(jié)構(gòu)簡單辟宗、實現(xiàn)容易蚜锨。但缺點也很明顯,由于中心節(jié)點需要存儲所有節(jié)點的路由信息慢蜓,當節(jié)點規(guī)模擴展時,就很容易出現(xiàn)性能瓶頸郭膛;而且也存在單點故障問題晨抡。

image

那第二種路由結(jié)構(gòu)則是純分布式的,移除了中心節(jié)點则剃,在 P2P 節(jié)點之間建立隨機網(wǎng)絡耘柱,就是在一個新加入節(jié)點和 P2P 網(wǎng)絡中的某個節(jié)點間隨機建立連接通道,從而形成一個隨機拓撲結(jié)構(gòu)棍现。新節(jié)點加入該網(wǎng)絡的實現(xiàn)方法也有很多種调煎,最簡單的就是隨機選擇一個已經(jīng)存在的節(jié)點并建立鄰居關(guān)系。像比特幣的話己肮,則是使用 DNS 的方式來查詢其他節(jié)點士袄,DNS 一般是硬編碼到代碼里的悲关,這些 DNS 服務器就會提供比特幣節(jié)點的 IP 地址列表,從而新節(jié)點就可以找到其他節(jié)點建立連接通道娄柳。新節(jié)點與鄰居節(jié)點建立連接后寓辱,還需要進行全網(wǎng)廣播,讓整個網(wǎng)絡知道該節(jié)點的存在赤拒。全網(wǎng)廣播的方式就是秫筏,該節(jié)點首先向鄰居節(jié)點廣播,鄰居節(jié)點收到廣播消息后挎挖,再繼續(xù)向自己的鄰居節(jié)點廣播这敬,以此類推,從而廣播到整個網(wǎng)絡蕉朵。這種廣播方法也稱為泛洪機制崔涂。純分布式結(jié)構(gòu)不存在集中式結(jié)構(gòu)的單點性能瓶頸問題和單點故障問題,具有較好的可擴展性墓造,但泛洪機制引入了新的問題堪伍,主要是可控性差的問題,包括兩個較大的問題觅闽,一是容易形成泛洪循環(huán)帝雇,比如節(jié)點 A 發(fā)出的消息經(jīng)過節(jié)點 B 到 節(jié)點 C,節(jié)點 C 再廣播到節(jié)點 A蛉拙,這就形成了一個循環(huán)尸闸;另一個棘手問題則是響應消息風暴問題,如果節(jié)點 A 想請求的資源被很多節(jié)點所擁有孕锄,那么在很短時間內(nèi)吮廉,會出現(xiàn)大量節(jié)點同時向節(jié)點 A 發(fā)送響應消息,這就可能會讓節(jié)點 A 瞬間癱瘓畸肆。

image


再來看看第三種路由結(jié)構(gòu):混合式宦芦。混合式其實就是混合了集中式和分布式結(jié)構(gòu)轴脐,如下圖所示调卑,網(wǎng)絡中存在多個超級節(jié)點組成分布式網(wǎng)絡,而每個超級節(jié)點則有多個普通節(jié)點與它組成局部的集中式網(wǎng)絡大咱。一個新的普通節(jié)點加入恬涧,則先選擇一個超級節(jié)點進行通信,該超級節(jié)點再推送其他超級節(jié)點列表給新加入節(jié)點碴巾,加入節(jié)點再根據(jù)列表中的超級節(jié)點狀態(tài)決定選擇哪個具體的超級節(jié)點作為父節(jié)點溯捆。這種結(jié)構(gòu)的泛洪廣播就只是發(fā)生在超級節(jié)點之間,就可以避免大規(guī)模泛洪存在的問題厦瓢。在實際應用中提揍,混合式結(jié)構(gòu)是相對靈活并且比較有效的組網(wǎng)架構(gòu)啤月,實現(xiàn)難度也相對較小,因此目前較多系統(tǒng)基于混合式結(jié)構(gòu)進行開發(fā)實現(xiàn)碳锈。其實顽冶,比特幣網(wǎng)絡如今也是這種結(jié)構(gòu),后面再細說售碳。
image


最后一種網(wǎng)絡則是結(jié)構(gòu)化 P2P 網(wǎng)絡强重,它也是一種分布式網(wǎng)絡結(jié)構(gòu),但與純分布式結(jié)構(gòu)不同贸人。純分布式網(wǎng)絡就是一個隨機網(wǎng)絡间景,而結(jié)構(gòu)化網(wǎng)絡則將所有節(jié)點按照某種結(jié)構(gòu)進行有序組織,比如形成一個環(huán)狀網(wǎng)絡或樹狀網(wǎng)絡艺智。而結(jié)構(gòu)化網(wǎng)絡的具體實現(xiàn)上倘要,普遍都是基于 **DHT(Distributed Hash Table,分布式哈希表) **算法思想十拣。DHT 只是提出一種網(wǎng)絡模型封拧,并不涉及具體實現(xiàn),主要想解決如何在分布式環(huán)境下快速而又準確地路由夭问、定位數(shù)據(jù)的問題泽西。具體的實現(xiàn)方案有 Chord、Pastry缰趋、CAN捧杉、Kademlia 等算法,其中 Kademlia 也是以太坊網(wǎng)絡的實現(xiàn)算法秘血,很多常用的 P2P 應用如 BitTorrent味抖、電驢等也是使用 Kademlia。因為篇幅有限灰粮,就不展開講這些算法的具體原理了仔涩。目前,我們主要理解 DHT 的核心思想即可粘舟。

在 P2P 網(wǎng)絡中熔脂,可以抽象出兩種空間:資源空間節(jié)點空間。資源空間就是所有節(jié)點保存的資源集合蓖乘,節(jié)點空間就是所有節(jié)點的集合。對所有資源和節(jié)點分別進行編號韧骗,如把資源名稱或內(nèi)容用 Hash 函數(shù)變成一個數(shù)值(這也是 DHT 常用的一種方法)嘉抒,這樣,每個資源就有對應的一個 ID袍暴,每個節(jié)點也有一個 ID些侍,資源 ID 和節(jié)點 ID 之間建立起一種映射關(guān)系隶症,比如,將資源 n 的所有索引信息存放到節(jié)點 n 上岗宣,那要搜索資源 n 時蚂会,只要找到節(jié)點 n 即可,從而就可以避免泛洪廣播耗式,能更快速而又準確地路由和定位數(shù)據(jù)胁住。當然,在實際應用中刊咳,資源 ID 和節(jié)點 ID 之間是無法做到一一對應的彪见,但因為 ID 都是數(shù)字,就存在大小關(guān)系或偏序關(guān)系等娱挨,基于這些關(guān)系就能建立兩者的映射關(guān)系余指。這就是 DHT 的核心思想弯汰。DHT 算法在資源編號和節(jié)點編號上就是使用了分布式哈希表瑰谜,使得資源空間和節(jié)點空間的編號有唯一性、均勻分布式等較好的性質(zhì)殴穴,能夠適合結(jié)構(gòu)化分布式網(wǎng)絡的要求柴钻。

綜上淮韭,這就是 P2P 網(wǎng)絡的一點理論基礎(chǔ),不同的區(qū)塊鏈可能會使用不一樣的網(wǎng)絡模型顿颅,但基本原理是一樣的缸濒。后面分別講解下最有代表性的兩個區(qū)塊鏈的網(wǎng)絡:比特幣網(wǎng)絡和以太坊網(wǎng)絡。

比特幣網(wǎng)絡

首先粱腻,比特幣網(wǎng)絡中的節(jié)點主要有四大功能:錢包庇配、挖礦、區(qū)塊鏈數(shù)據(jù)庫绍些、網(wǎng)絡路由捞慌。每個節(jié)點都會具備路由功能,但其他功能不一定都具備柬批,不同類型的節(jié)點可能只包含部分功能啸澡,一般只有比特幣核心(bitcoin core)節(jié)點才會包含所有四大功能。

image

所有節(jié)點都會參與校驗和廣播交易及區(qū)塊信息氮帐,且會發(fā)現(xiàn)和維持與其他節(jié)點的連接嗅虏。有些節(jié)點會包含完整的區(qū)塊鏈數(shù)據(jù)庫,包括所有交易數(shù)據(jù)上沐,這種節(jié)點也稱為全節(jié)點(Full Node)皮服。另外一些節(jié)點只存儲了區(qū)塊鏈數(shù)據(jù)庫的一部分,一般只存儲區(qū)塊頭而不存儲交易數(shù)據(jù),它們會通過“簡化交易驗證(SPV)”的方式完成交易校驗龄广,這樣的節(jié)點也稱為 SPV節(jié)點輕節(jié)點(Lightweight Node)硫眯。錢包一般是 PC 或手機客戶端的功能,用戶通過錢包查看自己的賬戶金額择同、管理錢包地址和私鑰两入、發(fā)起交易等。除了比特幣核心錢包是全節(jié)點之外敲才,大部分錢包都是輕節(jié)點裹纳。挖礦節(jié)點則通過解決工作量證明(PoW)算法問題,與其他挖礦節(jié)點相互競爭創(chuàng)建新區(qū)塊归斤。有些挖礦節(jié)點同時也是全節(jié)點痊夭,即也存儲了完整的區(qū)塊鏈數(shù)據(jù)庫,這種節(jié)點一般都是獨立礦工(Solo Miner)脏里。還有一些挖礦節(jié)點不是獨立挖礦的她我,而是和其他節(jié)點一起連接到礦池,參與集體挖礦迫横,這種節(jié)點一般也稱為礦池礦工(Pool Miner)番舆。這會形成一個局部的集中式礦池網(wǎng)絡,中心節(jié)點是一個礦池服務器矾踱,其他挖礦節(jié)點全部連接到礦池服務器恨狈。礦池礦工礦池服務器之間的通信也不是采用標準的比特幣協(xié)議,而是使用礦池挖礦協(xié)議呛讲,而礦池服務器作為一個全節(jié)點再與其他比特幣節(jié)點使用主網(wǎng)絡的比特幣協(xié)議進行通信禾怠。

在整個比特幣網(wǎng)絡中,除了不同節(jié)點間使用比特幣協(xié)議作為通信協(xié)議的主網(wǎng)絡贝搁,也存在很多擴展網(wǎng)絡吗氏,包括上面提到的礦池網(wǎng)絡。不同的礦池網(wǎng)絡可能還會使用不同的礦池挖礦協(xié)議雷逆,目前主流的具體礦池協(xié)議應該是 Stratum協(xié)議弦讽,該協(xié)議除了支持挖礦節(jié)點,也支持瘦客戶端錢包膀哲。一個包含了比特幣協(xié)議主網(wǎng)絡各種節(jié)點和 Stratum 網(wǎng)絡往产,以及其他礦池網(wǎng)絡的擴展比特幣網(wǎng)絡大概如下圖所示:

image

另外,挖礦這塊還有特殊需求某宪。我們知道仿村,礦工創(chuàng)建新區(qū)塊后,是需要廣播給全網(wǎng)所有節(jié)點的兴喂,當全網(wǎng)都接受了該區(qū)塊蔼囊,給礦工的挖礦獎勵才算是有效的包颁,這之后才好開始下一個區(qū)塊 Hash 的計算。所以礦工必須最大限度縮短新區(qū)塊的廣播和下一個區(qū)塊 Hash 計算之間的時間压真。如果礦工之間傳播區(qū)塊只采用上圖所示的比特幣協(xié)議網(wǎng)絡,那無疑會有很高的網(wǎng)絡延遲蘑险,所以滴肿,需要一個專門的傳播網(wǎng)絡用來加快新區(qū)塊在礦工之間的同步傳播,這個專門網(wǎng)絡也叫比特幣傳播網(wǎng)絡比特幣中繼網(wǎng)絡(Bitcoin Relay Network)佃迄。

以太坊網(wǎng)絡

和比特幣一樣泼差,以太坊的節(jié)點也具備錢包、挖礦呵俏、區(qū)塊鏈數(shù)據(jù)庫堆缘、網(wǎng)絡路由四大功能,也同樣存在很多不同類型的節(jié)點普碎,除了主網(wǎng)絡之外也同樣存在很多擴展網(wǎng)絡吼肥。但與比特幣不同的,比特幣主網(wǎng)的 P2P 網(wǎng)絡是無結(jié)構(gòu)的麻车,但以太坊的 P2P 網(wǎng)絡是有結(jié)構(gòu)的缀皱。前面我們已經(jīng)提過,以太坊的 P2P 網(wǎng)絡主要采用了 Kademlia(簡稱 Kad) 算法實現(xiàn)动猬,Kad 是一種分布式哈希表(DHT)技術(shù)啤斗,使用該技術(shù),可以實現(xiàn)在分布式環(huán)境下快速而又準確地路由赁咙、定位數(shù)據(jù)的問題钮莲。所以,下面主要講解下以太坊的 Kad 網(wǎng)絡彼水。

在 Kad 網(wǎng)絡中崔拥,每個節(jié)點都具有一個唯一的節(jié)點 ID。另外猿涨,也會計算不同節(jié)點之間的距離握童,但這個距離不是物理上的距離,而是邏輯上的距離叛赚,是通過對兩個節(jié)點 ID 進行 異或(符號為^) 計算得到的澡绩,即 A、B 兩節(jié)點之間的距離的計算公式為:D(A,B) = A.ID^B.ID俺附。異或有一個重要的性質(zhì):假設 a肥卡、b、c 為任意三個數(shù)事镣,如果 a^b = a^c 成立步鉴,那就一定 b = c。因此,如果給定一個結(jié)點 a 和距離 L氛琢,那就有且僅有一個結(jié)點 b, 會使得 D(a,b) = L喊递。通過這種方式,就能有效度量 Kad 網(wǎng)絡中不同節(jié)點之間的邏輯距離阳似。

在異或距離度量的基礎(chǔ)上骚勘,Kad 還可以將整個網(wǎng)絡拓撲組織成如下圖所示的一個二叉前綴樹,每個 NodeID 會映射到二叉樹上的某個葉子撮奏。

image


映射規(guī)則主要是:

  1. 將 NodeID 以二進制形式表示俏讹,然后從高到低對每一位的 0 或 1 依次處理;
  2. 二進制的第 n 位就對應了二叉樹的第 n 層畜吊;
  3. 如果該位是 0泽疆,進入左子樹,是 1 則進入右子樹(反過來也可以)玲献;
  4. 全部位都處理完后殉疼,這個 NodeID 就對應了二叉樹上的某個葉子。

在這種二叉樹結(jié)構(gòu)下捌年,對每個節(jié)點來說株依,離它越近的節(jié)點異或距離也是越近的。接著延窜,可以按照離自己異或距離的遠近恋腕,對整顆二叉樹進行拆分。拆分規(guī)則是:從根節(jié)點開始逆瑞,將不包括自己的那顆子樹拆分出來荠藤,然后在包含自己的子樹中,把不包括自己的下一層子樹再拆分出來获高,以此類推哈肖,直到只剩下自己。以上圖的 110 節(jié)點為例念秧,從根節(jié)點開始淤井,由于 110 節(jié)點在右子樹,所以將左邊的整顆子樹拆分出來摊趾,即包含 000币狠、001、010 這三個節(jié)點的這顆子樹砾层;接著漩绵,到第二層子樹,將不包含 110 節(jié)點的左子樹再拆分出來肛炮,即包含 100 和 101 這兩個節(jié)點的子樹止吐;最后宝踪,再將 111 拆分出來。這樣碍扔,就將 110 節(jié)點之外的整個二叉樹拆分出了三顆子樹瘩燥。

完成子樹拆分后,只要知道每個子樹里面的其中一個節(jié)點不同,就可以進行遞歸路由實現(xiàn)整顆二叉樹所有節(jié)點的遍歷颤芬。但在實際場景下,由于節(jié)點是動態(tài)變化的套鹅,所以一般不會只知道每個子樹的一個節(jié)點,而是需要知道多個節(jié)點汰具。因此卓鹿,Kad 中有一個叫 K-桶(K-bucket)的概念,每個桶會記錄每顆子樹里所知道的多個節(jié)點留荔。其實吟孙,一個K-桶就是一張路由表,如果拆分出來有 m 顆子樹聚蝶,那對應節(jié)點就需要維護 m 個路由表杰妓。每個節(jié)點都會各自維護自己的 m 個 K-桶,每個 K-桶里記錄的節(jié)點信息一般會包括 NodeID碘勉、IP巷挥、Endpoint、與 Target 節(jié)點(即維護該 K-桶的節(jié)點)的異或距離等信息验靡。以太坊中倍宾,每個節(jié)點維護的 K-桶數(shù)量為 256 個,這 256 個 K-桶會根據(jù)與 Target 節(jié)點的異或距離進行排序胜嗓,每個 K-桶保存的節(jié)點數(shù)量上限是 16高职。

在以太坊的 Kad 網(wǎng)絡中,節(jié)點之間的通信是基于 UDP 的辞州,另外設置了 4 個主要的通信協(xié)議:

  1. Ping:用于探測一個節(jié)點是否在線
  2. Pong:用于響應 Ping 命令
  3. FindNode:用于查找與 Target 節(jié)點異或距離最近的其他節(jié)點
  4. Neighbours:用于響應 FindNode 命令怔锌,會返回一或多個節(jié)點

通過以上 4 個命令,就可以實現(xiàn)新節(jié)點的加入变过、K-桶的刷新等機制埃元。具體的實現(xiàn)流程就不細講了,留給大伙自己去思考媚狰。

總結(jié)

不同結(jié)構(gòu)的 P2P 網(wǎng)絡亚情,會有不同的優(yōu)點和缺點。比特幣網(wǎng)絡的結(jié)構(gòu)明顯容易理解哈雏,實現(xiàn)起來也相對容易得多楞件,而以太坊網(wǎng)絡引入了異或距離衫生、二叉前綴樹、K-桶等土浸,結(jié)構(gòu)上復雜不少罪针,但在節(jié)點路由上的確會比比特幣快很多。另外黄伊,不管是比特幣還是以太坊泪酱,其實都只是一種或多種協(xié)議的集合,不同節(jié)點其實可以用不同的具體實現(xiàn)还最,比如墓阀,比特幣就有用 C++ 實現(xiàn)的 Bitcoin Core,還有用 Java 實現(xiàn)的 BitcoinJ拓轻;以太坊也有用 Go 語言實現(xiàn)的 go-ethereum斯撮,也有用 C++ 實現(xiàn)的 go-ethereum,還有用 Java 實現(xiàn)的 Ethereum(J)扶叉。

思考和實踐

在以太坊的 Kad 網(wǎng)絡中勿锅,新節(jié)點的加入和 K-桶的刷新流程是怎樣的?比特幣的新節(jié)點加入流程又是怎樣的枣氧?哈希表有哪些實現(xiàn)方式溢十?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市达吞,隨后出現(xiàn)的幾起案子张弛,更是在濱河造成了極大的恐慌,老刑警劉巖酪劫,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乌庶,死亡現(xiàn)場離奇詭異,居然都是意外死亡契耿,警方通過查閱死者的電腦和手機瞒大,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來搪桂,“玉大人透敌,你說我怎么就攤上這事√咝担” “怎么了酗电?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長内列。 經(jīng)常有香客問我撵术,道長,這世上最難降的妖魔是什么话瞧? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任嫩与,我火速辦了婚禮寝姿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘划滋。我一直安慰自己饵筑,他們只是感情好,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布处坪。 她就那樣靜靜地躺著根资,像睡著了一般。 火紅的嫁衣襯著肌膚如雪同窘。 梳的紋絲不亂的頭發(fā)上玄帕,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天,我揣著相機與錄音想邦,去河邊找鬼裤纹。 笑死,一個胖子當著我的面吹牛案狠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播钱雷,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼骂铁,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了罩抗?” 一聲冷哼從身側(cè)響起拉庵,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎套蒂,沒想到半個月后钞支,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡操刀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年烁挟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骨坑。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡撼嗓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出欢唾,到底是詐尸還是另有隱情且警,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布礁遣,位于F島的核電站斑芜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏祟霍。R本人自食惡果不足惜杏头,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一盈包、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧大州,春花似錦续语、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至根暑,卻和暖如春力试,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背排嫌。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工畸裳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人淳地。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓怖糊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親颇象。 傳聞我的和親對象是個殘疾皇子伍伤,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容