閃電網絡:歷史與現實

初心

Aaron Van Wirdum的《閃電網絡的歷史:從頭腦風暴,到測試版本》記錄了2018年前閃電網絡的有趣歷史。

中本聰在2009年創造BTC的時候就有關於支付通道的想法,並且在Bitcoin 1.0裡就已經包含了支付通道的最初代碼實現,之後的幾年,支付通道乃至閃電網絡的想法一直在被BTC社區討論。

Vitalik早年創辦的bitcoinmagazine收錄了閃電網絡的許多重要文章,2013年底,Vitalik在考慮如何進一步擴展比特幣和Mastercoin功能的時候,向Mastercoin團隊提出了一個更通用的方案,該方案允許用靈活且可編寫腳本(但不是圖靈完備的)的合約取代Mastercoin的專業合約語言。雖然Mastercoin團隊對此印象深刻,但這一提議太過激進,無法適應他們的發展路線圖,建議被拒絕。

於是,被拒絕的Vitalik開始起草以太坊白皮書,以實現其關於鏈上智能合約的想法,而BTC的開發者們也逐漸形成共識- 放棄在一層實現智能合約和擴容的路線,把一層的功能固定在安全性和基本功能上面,而把各種擴展放到鏈下實現,兩條公鏈背後是兩種理念。

成型

2015年2月是一個比較重要的時間節點,經歷了程序員們的大量討論之後,Thaddeus Dryja 和Joseph Poon 一起撰寫了一份名為“The Bitcoin Lightning Network: Scalable Off-Chain Instant Payments ” 的白皮書,在2015 年的2 月首次發布,並且在舊金山比特幣開發者研討會(Bitcoin Devs Seminar)上首次展示了他們的構想。

在這之後的幾個月,整個2015 年的春天和夏天,比特幣的擴展問題和區塊大小上限的分歧演變成了公開的爭執。在這種危機氣氛中,人們在2015 年底召開了連續兩場大會:9 月份召開了 Scaling Bitcoin Montreal,10 月份是 Scaling Bitcoin Hong Kong。在蒙特利爾,Poon 和Dryja 再次登台演講,並且都在香港作了第二次更深入的演講。

就在香港的大會之後,Gregory Maxwell 在比特幣開發者郵件組中提出了一份擴展方案路線圖。這張路線圖突出地包括了閃電網絡。它獲得了比特幣技術社區大部分人的支持,並且變成了Bitcoin Core 項目在事實上的路線圖。

閃電網絡的白皮書包含許多技術含量很高的概念,並不太容易讀懂。

閃電網絡的基本組件是支付通道。

支付通道是怎麼實現的呢?這裡麵包含著一系列的基於BTC交易邏輯的密碼學技術手段和巧思,簡而言之,在資金安全得到去信任保證的前提下,兩個用戶同時“充值”到一個2-of-2的多簽地址,然後,通過互換簽名交易信息來實現每次的餘額更新/完成支付,在餘額的限制之內,這樣的支付無需上鍊,交易雙方依靠對正確的簽名交易信息的持有就可以確保自己的利益,在需要的時候,可以通過將最新的交易信息廣播上鍊來進行鏈上結算,關閉支付通道。

然後,通過HTLC,大量的的支付網絡可以連接起來,構成網絡,支付可以通過這樣的網絡到達與支付者並沒有直接通道連接的接受者,這樣一個依賴於BTC鏈建立的線下支付網絡,被稱作閃電網絡。

當然,這樣的描述過於簡化了,要了解細節,還請讀白皮書。

建構

目標確定之後,BTC的擁躉們滿腔熱情地投入了閃電網絡的建設。

為了創建和優化閃電網絡,BTC進行了多次的協議更新,其中最大的一次是隔離見證。

隔離見證實現的事情是,把交易中的發起方簽名部分分離出來可供單獨引用。

An illustration of the old and new transaction serialization posted by David A. Harding .

這讓一件事情成為可能,就是當交易A被簽名好但還沒有被廣播的時候,基於交易A構建的子交易已經可以被廣播了。這可以用於構建預先簽名承諾交易,以化解將資金注入多簽地址後的對手方風險,構建支付通道需要這項功能。

隔離見證的歷史參見“The Long Road to SegWit: How Bitcoin’s Biggest Protocol Upgrade Became Reality”

在漫長的掙扎過後,隔離見證軟分叉最終於2017 年夏天在比特幣區塊鏈上激活,為閃電網絡鋪平了道路。

坦率講,由支付通道自下而上構建成的閃電網絡一開始就有許多問題,其中,最影響用戶體驗的應該是通道容量經濟性問題,此外,還有支付時延問題,狀態管理問題,HTLC問題,依賴於Tor的問題,詳見Shinobi的《閃電網絡尚不盡如人意之處》。

一個通道的生命週期中需要開通和關閉兩筆鏈上交易,但這兩筆交易的成本在許多情況下也足以構成進入門檻,而且,這種類似充值卡的模式在資金使用效率上絕對談不上高效。

舉個例子,假設推特想利用閃電網絡為3億活躍的推特用戶中的1%開通打賞功能,那麼就需要為這300萬用戶中的每一個都開通支付通道,假設每個通道佔用資金0.01BTC,那麼所有這些通道將佔用資金3萬BTC。

而按1ml.com上的統計,當前(2022年10月20日)閃電網絡共有82623個支付通道,通道資金5001BTC.

來自1ml.com

BOLT

“閃電網絡的白皮書是一份長而復雜的文件,包含許多技術含量很高的概念;在2015 年,很少有人有時間和能力讀完並且理解這份文件。但Linux 系統內核長期開發者Rusty Russell 學習了這份白皮書後,大家的基礎認識提高了一大截。在2015 年初的 系 列 博 客 中,Russell 為更廣泛的讀者“翻譯” 了這份白皮書(但還是比較挑人的)。

然後,在2015 年3 月,Russell 接受Blockstream 工程的聘請,開發一個C 語言的閃電網絡實現: c-lightning。事實證明,這是邁向實現的關鍵一步。一個幾個月前才剛剛提出的概念,現在就有了一個世界頂尖的工程師來實現它。後來,Blockstream 的Christian Decker 也加入了Russell;其他人(包括Corné Plooy) 也為這個開源項目做了貢獻。

在Russell 開始開發c-lightning 不久之後,Blocksteam 就不是唯一一個入局實現閃電網絡的公司了。在2015 年夏天,ACINQ 這家更小的比特幣科技公司(一開始計劃開發基於智能卡的硬件錢包)決定也嘗試一下這項富有前景的技術。這家位於巴黎的創業公司後來宣布他們開發者用Scala 編程語言開發出了自己的閃電網絡協議,叫做eclair。

又過了幾個月,第三個實現開始起步。在2016 年1 月,閃電網絡白皮書的作者Poon 和Dryja,也跟Elizabeth Stark 和Olaoluwa “Laolu” Osuntokun 一道,成立了一個全新的公司來開發閃電網絡:Lightning Labs。 Lightning Labs 帶頭在 lnd 上開閘,這是一個用谷歌公司推出的Go 編程語言(也叫“golang”)實現的閃電網絡—— 他們在公司成立之前就開始開發了。

在成立公司大概一年後,在2016 年底,Dryja 離開了Lightning Labs,轉而加入了 MIT Media Lab 的Digital Currency Initiative,這個機構也僱用了Bitcoin Core 的頂尖開發者Wladimir van der Laan 和多位Bitcoin Core 的貢獻者。在MIT,Dryja 繼續開發他在Lightning Labs 起步的閃電網絡實現,重命名為 lit。現在lnd 和lit 都可用。 Lit 與lnd 和其它實現有差異的點在於它把錢包和節點封裝成了一個整體;現在,它還支持同時使用多種幣。

此外,區塊鏈公司 Bitfury(因其礦池服務和挖礦硬件而知名)也fork 了lnd 實現、做了另一個版本。這個版本的特殊之處在於,它在設計上做了犧牲,使得無需修復比特幣網絡的熔融性(malleability)—— 後面我們再詳細說明。 Bitfury 也在交易路由領域作了貢獻,最著名的成果是“Flare” 協議(只不過現在Bitfury 版本的lnd 開發似乎已經停滯下來了)(譯者註:“熔融性” 的例子是,本質上是同一個簽名的交易,可能會產生完全不同的哈希值(交易ID),使交易變得無法跟踪;就像同一塊金屬可以熔成不同的形狀一樣)。

再後來,再2016 年,主要的錢包服務商Blockchain 宣布他們開發出了一個簡化版的閃電網絡,叫做“thunder”。這個實現對標準的閃電網絡實現做了比較大的犧牲,最明顯的是它需要你信任網絡中的對手方。也因為這種犧牲,它得以在2016 年春天推出alpha 版本,比其他開發團隊要早得多。 (雖然thunder 也可能兼容閃電網絡,但這一實現的開發似乎也已經停滯了。)

在Scaling Bitcoin Milan 大會之後,第三次會議在2016 年底舉辦,大部分閃電網絡的貢獻者都齊聚一堂(這場大會因此被稱為第一次閃電網絡峰會)。在這裡,他們討論瞭如何讓所有的不同實現能相互操作,從而產生了一個叫做“BOLT”的閃電網絡協議規範(BOLT 是“閃電網絡技術技術(Basis of Lightning Technology)” 的縮寫)。 ”

-[《**闪电网络的历史:从头脑风暴,到测试版本**》](https://www.btcstudy.org/2020/09/03/history-lightning-brainstorm-beta/)

BOLT協議結構,源自網絡

閃電網絡白皮書做了理論設計,BOLT是閃電網絡的協議棧。是我們今天所知的、實際上的閃電網絡的基礎。

OmniBOLT

2019 年8 月1 日出現的OmniBOLT是BOLT協議的加強版,由omni foundation提出,顧名思義,推出這一加強版協議的最大動力是讓閃電網絡增加對omnilayer資產的支持。

github上的信息顯示,OmniBOLT還支持以下功能,其中的一些還在計劃階段:

OmniBOLT #05: Atomic Swap Protocol among Channels

OmniBOLT #06: Automatic Market Maker, Liquidity Pool and DEX

OmniBOLT #07: Hierarchical Deterministic (HD) wallet, Invoice Encoding

這裡所說的原子交換是通過HTLC進行的,如下圖。

這裡需要注意一點的是,在第三步,Alice用R去解鎖Tx 2獲取BTC時,她必然需要把R暴露給Bob,這一點是保證交換原子性的關鍵。

來源:https://github.com/omnilaboratory/OmniBOLT-spec/blob/master/OmniBOLT-05-Atomic-Swap-among-Channels.md

當然,進行原子交換的雙方不需要擁有一個直接的支付通道,只要存在連接雙方的通道路由就可以,當然,如果路由長了,就會有路由費用問題,也會有交易時延問題。

那麼可不可以有跨鏈的原子交換呢?當然可以,前提是交易雙方擁有對應兩條鏈的兩個支付通道路由,而且這兩條鏈的相關技術結構是一致的,如BTC和LTC。

事實上,在OmniBOLT還未出現的2017年11月,Ligntning Labs就進行過一次跨鏈的原子交換實驗,詳情見這裡:https://blog.lightning.engineering/announcement/2017/11/16/ln-swap.html

對於那些持有BTC或者ominilayer資產的並且不願在自家錢包之外交易的用戶來說,這樣的交易方式的出現是很有意義的。

OmniBOLT的AMM交易模型類似於uniswap v3。

這個交易模型是基於前面所述的原子交換構建的,這裡不存在一個鏈上的智能合約,也不存在一個單個地址上的流動性池,所有的節點都可以用自己在通道裡的資金提供流動性,這些通道裡的資金被區分為“支付餘額”和“流動性餘額”。節點可以發消息給tracker,告知自己提供的流動性是多少,願意參與做市的價格區間是多少。

tracker是一個交易撮合引擎,不斷收集流動性信息和交易請求信息,可以匹配的時候,就幫助節點間撮合,達成交易。

來源:https://github.com/omnilaboratory/OmniBOLT-spec/blob/master/OmniBOLT-06-Automatic-Market-Maker-and-DEX.md

節點並不需要信任tracker,節點可以去驗證tracker提供的信息真偽以及是否符合自己的交易條件,然後決定是否確認交易。

這裡節點參與做市有沒有無常損失呢?跟uniswap v3一樣,有,但LP可以通過設置做市價格區間將無常損失控制在較低的水平。

簡而言之,這裡的交易邏輯相當於uniswap v3 + 訂單薄,只是是在一個分佈式的流動性池上,基於原子交換的邏輯來實現的。

以上的種種技術手段,也可以用來實現抵押借貸,但到目前為止,github上面的信息顯示,OmniBOLT的關於抵押借貸的設想還處在社區討論可行性的階段,並未列入開發路線圖。

Taproot

2021年11月中,BTC完成了Taproot升級,這可以說是在隔離見證之後BTC最重要的一次升級,

Taproot 升級則是三個BIPs 的彙編,這三個BIPs 分別是Schnorr 簽名(BIP 340)、Taproot (BIP 341)和TapScript (BIP 342),這三個升級統稱為BIP Taproot,它為比特幣帶來了更高效、更靈活、更私密的傳輸方式,其核心在於使用了Schnorr 簽名和Merkel 抽象語法樹(MAST)。

來源:https://newbtcworld.medium.com/huffman-taproot-optimization-85698babf742

Taproot的原理,簡單來說,就是定義了一種輸出和兩種花費路徑。如上圖所示,有Alice和Bob兩個參與者,Taproot的運作過程如下:

將Alice和Bob的公鑰聚合為:C=P_A+P_B

加入MerkleRoot,公鑰聚合為:P=C+H(C||MerkleRoot)G,其中H(C||MerkleRoot) 表示C和MerkleRoot的組合hash

鎖定腳本中填入聚合公鑰P,格式類似Segwit:[ver] [P]。 ver表示版本號,Taproot中ver=1。

花費路徑有兩個,二選一:

簽名模式:Alice和Bob全部簽名產生聚合簽名,填入見證腳本。利用聚合公鑰P,對簽名進行驗證後即可花費。

腳本模式:Alice和Bob,有一個拒絕簽名,可以走腳本模式。此時Alice想要完成花費,那麼見證腳本中需要填入:符合Script 1的執行數據D, Script 1, C, Hash 2 。為了驗證簽名,首先利用Script 1, Hash2,計算MerkleRoot,然後驗證P==C+H(C||MerkleRoot)G 是否成立,最後構建完整腳本D||Script 1並執行腳本,驗證結果是否為真。當上述驗證通過後,即可完成花費。

Taproot按照簽名模式進行花費時,多個參與方和單個參與方在區塊鏈上看起來都長得是一樣的,所以許多區塊鏈分析將不可用,從而為所有Taproot 用戶保留隱私。與此同時,Taproot的腳本花費模式讓用戶可以實現複雜的支出條件。 Taproot可以有效壓縮交易腳本字節數。簽名模式下隨著參與者增加,EDSA交易腳本大小線性增長,Taproot交易腳本大小保持不變。腳本模式下隨著腳本數量的增加,EDSA交易腳本大小線性增長,Taproot交易腳本大小對數增長。

Taproot讓智能合約成為可能了嗎?

Taproot的確讓一些基於復雜條件的交易成為可能,Schnorr 簽名也的確讓大批量簽名變得可行,但Taproot也並沒有增強多少BTC的可編程性,它對BTC進行的“智能”加持依然是很有限的。

Taproot催生的最亮眼的孩子是Lighting Labs的Taro。

來源:https://mirror.xyz/huzhiwei.eth/J2Kv1ATWo0_d3ZidG-8BDrIJcYX7DFew_ruQ2p03sgU

與Omnilayer和RGB一樣,Taro在BTC鏈上發行資產的方式也是把資產交易元數據放到UTXO輸出裡面,不過Taro使用了新增的Taproot交易類型來實現這一切,因此應該更加地高效,隱私保護也更好。

RGB

比特幣鏈下協議領域的研究和發展為比特幣打開了一扇窗戶,開發者們追求的已經遠不止以去中心化的方式轉移價值。他們開始嘗試走得更遠,比如說,用鏈下協議的方式實現智能合約, RGB 是這類項目中的佼佼者。

RGB 基於Peter Todd 關於一次性密封和客戶端驗證的研究,並被Giacomo Zucco 和社區在2016 年設想為比特幣和閃電網絡上更好的資產發行協議。這些想法的進一步發展導致Maxim Orlovsky 將RGB 開發成一個更加全面的智能合約系統,他自2019 年以來在社區的參與下領導了這個系統的實現。

根據官方描述,RGB 定義為一組允許我們以可擴展和保密的方式執行複雜智能合約的開源協議。它並非一個特定的網絡(如比特幣或閃電網絡);每個智能合約只是一組能用不同通信通道(默認為閃電網絡)進行交互的合約參與者。 RGB 利用比特幣區塊鏈作為其狀態承諾層,並在鏈下維護智能合約的代碼和數據,藉此實現可擴展性。它利用比特幣交易(以及腳本)作為智能合約的所有權控制系統;儘管智能合約的演化是通過一套鍊下方案來定義的。最後需要注意的是,所有內容都是在客戶端驗證的。

簡而言之,RGB 是一個允許用戶隨時審計、執行和驗證智能合約的系統,而無需任何額外的開銷,它並沒有按照“傳統” 的方式來使用區塊鏈。

一些RGB的擁躉們看不上以太坊,下面這張出自他們之手的表很能表現他們的這種態度。

來源:https://bitcoinmagazine.com/guides/a-brief-introduction-to-rgb-protocols

這裡需要簡單討論一下比特幣的可編程性以及對比一下比特幣與以太坊的智能合約的不同。

比特幣的運行基於兩個基本的概念:交易和UTXO。當一筆交易創造了一個新的UTXO的時候,會自帶一個由鎖定腳本表達的解鎖條件,當下一個交易要話費這個UTXO的時候,必須提供相應數據,通過鎖定腳本所指定的驗證程序,否則就無法花費。若要編程比特幣,不外乎要在交易層面或者腳本層面做文章。

比特幣的編程工具箱,目前有簽名,多重簽名,哈希鎖,時間鎖,流程控制等工具。

對比一下以太坊和比特幣,可以發現比特幣的可編程性在下面這些方面有明顯的限制:

  1. 它允許的驗證程序不是任意的,只有有限的幾種。

  2. 它不允許將資金的內部狀態存儲在腳本中。即使它規定了多條解鎖路徑,也無法限制各解鎖路徑能夠動用的資金量,只要能解鎖資金,運用任何一條路徑都可以使用全部資金。也可以說,腳本是不會計算的。

  3. 它不允許限制資金的花費方式。在一個UTXO 解鎖之後,怎麼花都可以,腳本完全無法限制資金的花費方式。

  4. 解鎖腳本所表達的是完備、獨立的解鎖條件,它不允許我們表達對另一個UTXO 的依賴。一個UTXO 不會(也不能)根據另一個UTXO 存不存在來決定自己能不能解鎖,也不會(不能)根據另一個UTXO 的鎖定條件來決定自己能不能解鎖。一言以蔽之,在花費一個UTXO 時,該UTXO 的鎖定腳本和交易所提供的解鎖腳本就是一個獨立的宇宙,不受任何外在的東西干擾。

如果我們問一位熱愛BTC的技術專家,BTC支持智能合約嗎?他很可能會說,BTC從一開始就是支持智能合約的。

我們沒法說他錯,因為簡單的腳本程序也可以說是智能合約,閃電網絡可以說是基於BTC區塊鏈運行的合約式協議,我們仔細研究閃電網絡時,會發現一些特點,可能是BTC原生智能合約的共同特點:

  • 可以使用交易來表達合約的狀態,交易的更替就表示合約狀態的變化。

  • 如果進入一種狀態會面臨失控的風險,可以通過預先簽名承諾交易,來約束進入這種狀態之後的走向,從而消除相應的對手方風險。比如,進入一個2-of-2 多簽名輸出有可能導致資金被鎖定,那就先安排一筆花費這個輸出的交易。

  • 除了退出合約以外,狀態的更新總是需要所有參與方在線。

  • 表達狀態的歷史交易需要參與方各自存儲(至少在目前是如此)。

  • 鎖定腳本的主要作用是安排合約參與者的行動優先權,而不是直接產生結果;換言之,基於比特幣的協議編程是在運用博弈學。

比特幣的編程對應用開發人員和應用參與者都提出了更高的要求,這些限制使得應用開發起來更不直觀、更難分析,打個不恰當的比方,有點像螺絲殼裡做道場,或者用彙編語言寫操作系統。用戶也不能依靠區塊鏈來為他們提供充足的便利,而必須自己承擔更多的責任(比如在閃電網絡中,你需要自己保管歷史狀態交易和相應的哈希原像,或者至少要有人負責保管)。

我們不能說BTC如此限制可編程性沒有意義,比特幣一直在事實上奉行著一種“資源使用最小化”原則,拒絕低成本交易占用區塊空間,擴展?到鏈下去。現在的這種狀態是堅持初心的自然結果。

在以太坊的語境裡,“智能合約”意味著在虛擬機環境中確定性的運行的不可變的計算機程序,合約部署在鏈上的合約賬戶中,EVM在每個以太坊節點上作為本地實例運行,但由於EVM的所有實例都在相同的初始狀態下運行並產生相同的最終狀態,因此整個系統表現為單台圖靈完備的世界計算機。

交易的原子性由EVM運行的規則保證,無論合約在被調用時執行的是什麼。僅在交易成功終止時記錄全局狀態(合約,帳戶等)的任何更改。成功終止意味著程序執行時沒有錯誤並且達到執行結束。如果交易由於錯誤而失敗,則其所有效果(狀態變化)都會“回滾”,就好像交易從未運行一樣。失敗的交易仍存儲在區塊鏈中,並從原始賬戶扣除gas成本,但對合約或賬戶狀態沒有其他影響。

這裡,智能合約上鍊,所有狀態上鍊,帶來的結果是良好的開發者和用戶體驗,當然,還有區塊鏈的膨脹。

我們無法簡單評判哪條道路的對錯,這是選擇的問題。

當然,RGB團隊是BTC道路的深度信仰者,他們如此解釋他們的選擇:

當前的區塊鏈行業提倡把智能合約代碼和數據都存儲在區塊鏈上,並由全網所有節點執行,而無視區塊鏈體積的過度增長和計算資源的濫用。由RGB 提出的方案則更加智能和高效,因為它通過將智能合約和數據從區塊鏈中分離出來而擺脫了區塊鏈範式,從而避免了在其它平台上常見的網絡飽和的情況,反過來,它並不要求每個節點都執行每份合約,而是將執行者變成了合約的相關方,這帶來了前所未見的保密性。

RGB 上的智能合約開發者定義了一套方案來規定合約如何隨時間推移而演化。這套方案是在RGB 中構建智能合約的標準,發行者在定義發行的合約時和錢包或交易所在面對具體的合約時,必須先以這套標準來驗證合約。只有當驗證無誤時,每個參與方才能接受請求並處理相應的資產。

RGB 中的智能合約是一個由狀態變更構成的有向無環圖(DAG),該圖始終只有一部分是已知的,其餘部分則無法訪問。 RGB 方案是規定智能合約如何演化的一組核心規則,是所有智能合約的起點。每個合約參與方都可以對這組規則進行補充(在架構允許的前提下),由此產生的圖是根據這些規則的迭代式應用而構建的。

– Francisco Calderon[《A brief Introduction to RGB Protocols》](https://bitcoinmagazine.com/guides/a-brief-introduction-to-rgb-protocols)

聽起來很美好,但既然把比特幣區塊鏈當成狀態承諾層,就必然受制於BTC可編程性的局限,在許多場景之下,這些局限都是相當關鍵的。

RGB的開發目前也基本上只是走到了發行資產這一步,鏈下智能合約的實現絕不會順利,是否真正有機會匹敵乃至超越鏈上智能合約更要打上一個大大的問號。

前景

幾個月來,閃電網絡領域大額融資頻出,尤其被關注的是以下幾個:

加密支付應用提供商Strike 融資8000 萬美元。 ❕

Lightning Labs 獲得7000 萬美元融資。

lightspark從a16z和paradigm獲得投資,投資額未披露。

閃電網絡的通道容量近兩年有了較大的增長:

背後主要是這些機構的力量:

來源:https://river.com/learn/files/river-lightning-report.pdf

雖然增長較快,但目前閃電網絡的整體容量與粉絲們對它的期望相比還是很不相符的。下面是1ml10月20日的數據。

來源:1ml.com

畢竟跨鏈到ETH的BTC有17萬以上。

基於閃電網絡的衍生品交易平台Kollider, 10月22日日交易量約1.1BTC。

https://pro.kollider.xyz/

畢竟閃電網絡更適合於微支付,並不太適合於大額交易。

閃電網絡對於BTC代表的鏈下擴容路線有著里程碑的意義,雖然一路艱辛,但在開發者努力,大額融資與社區熱望加持之下,閃電網絡應該是能掀起一波應用熱潮的。

畢竟氣氛已經烘托到這裡了。

但鑑於其局限,也不應該對其抱有不切實際的期望。

Total
0
Shares
Related Posts