The Libra Blockchain開發(fā)者文檔-(三)交易生命周期

對(duì)應(yīng)官方文檔:https://developers.libra.org/docs/life-of-a-transaction

交易的生命周期

為了更深入的了解Libra交易的生命周期,我們將跟蹤一筆交易,從提交到Libra驗(yàn)證器,到使用Libra區(qū)塊鏈處理確認(rèn)交易的整個(gè)過程。然后,我們將“放大”來看驗(yàn)證器的每個(gè)邏輯組件及與其他組件之間的交互。

客戶提交交易

Libra客戶端創(chuàng)建一個(gè)原始的交易(稱為T~5~raw)將10個(gè)Libra Coin從Alice賬戶轉(zhuǎn)移到Bob賬戶。原始交易包含以下字段,每個(gè)字段都和其詞匯表定義相關(guān)聯(lián)。

Alice的賬戶地址.

程序中Alice要執(zhí)行的操作,包含如下:?

Move點(diǎn)對(duì)點(diǎn)交易字節(jié)碼腳本

腳本輸入列表(例如,Bob的帳戶地址和付款金額)

Gas價(jià)格(以微Libra/Gas為單位)-發(fā)送方執(zhí)行交易時(shí)所需要支付的Gas金額。Gas是支付在區(qū)塊鏈上計(jì)算和存儲(chǔ)的所需要的費(fèi)用,這是一個(gè)抽象浮動(dòng)的計(jì)量,沒有具體固定的真實(shí)價(jià)值。

Alice愿意為此次交易支付的最高Gas量

交易的到期時(shí)間。

序號(hào)5?

序號(hào)為5的交易只能應(yīng)用于交易序號(hào)為5的帳戶。

客戶端使用Alice的私鑰對(duì)事務(wù)T~5~raw進(jìn)行簽名。簽名后的交易T5包括以下內(nèi)容:

原始交易。

Alice的公鑰

Alice的數(shù)字簽名

假設(shè)

為了描述交易T5的生命周期,我們假設(shè):

Alice和Bob在Libra區(qū)塊鏈上有賬戶

Alice的賬戶中有Libra Coin。

Alice的帳戶的當(dāng)前序列號(hào)是5(表示已經(jīng)從Alice的帳戶發(fā)送了5個(gè)交易)。

網(wǎng)絡(luò)上總共有100個(gè)驗(yàn)證器 - 網(wǎng)絡(luò)上的V1到V100。

客戶端將交易T5提交給驗(yàn)證器V1

驗(yàn)證器 V1是本輪的提議者/領(lǐng)導(dǎo)者。

交易的生命周期

在本節(jié)中,我們將描述交易T5的生命周期,從客戶端提交開始到交易在Libra區(qū)塊鏈確認(rèn)。

根據(jù)相關(guān)的情況,并在交易生命周期中的各個(gè)步驟編號(hào),我們提供相關(guān)驗(yàn)證器節(jié)點(diǎn)及其相應(yīng)組件之間的交互鏈接,熟悉了交易的生命周期中所有的步驟后,你可以參考每個(gè)步驟中相應(yīng)組件之間的交互信息。

?注意:本文檔中所有圖形中的箭頭都表示組件之間的指向,終止于執(zhí)行操作的組件上。 箭頭不表示讀取,寫入或返回的數(shù)據(jù)。


圖1.1交易生命周期

接收交易

1?— 客戶端將交易T5提交給驗(yàn)證器V1,驗(yàn)證器V1的準(zhǔn)入控制(AC)組件接收該交易。 (客戶端→AC?AC.1

2?— AC將使用虛擬機(jī)(VM)組件執(zhí)行驗(yàn)證檢查,例如簽名驗(yàn)證,檢查Alice的帳戶是否有足夠的余額,檢查交易T5是否未被重復(fù)廣播等。(AC→VM?AC.2,VM.1

3?— 當(dāng)T5通過驗(yàn)證檢查時(shí),AC將T5發(fā)送到V1的內(nèi)存池。 (AC→內(nèi)存池?AC.3MP.1

發(fā)布交易至其他驗(yàn)證器節(jié)點(diǎn)

4?— 內(nèi)存池將T5保存在內(nèi)存緩沖區(qū)中。 內(nèi)存池可能已包含從Alice的地址發(fā)送的多個(gè)交易。

5?— 使用shared-mempool協(xié)議,V1將在其內(nèi)存池中與其他驗(yàn)證器(V2到V100)廣播交易(包括T5),并將從其他驗(yàn)證器接收的交易放入其自己的內(nèi)存池中。 (內(nèi)存池→其他驗(yàn)證者MP.2

塊提議

6?— 由于驗(yàn)證器V1是提議者/領(lǐng)導(dǎo)者,它將從其內(nèi)存池中提取一個(gè)交易塊,并通過其共識(shí)組件將此塊作為提議復(fù)制到其他驗(yàn)證器。(共識(shí)→內(nèi)存池?MP.3,CO.1

7?— V1的共識(shí)部分負(fù)責(zé)根據(jù)提議的塊中的交易順序協(xié)調(diào)所有驗(yàn)證器之間的協(xié)議。 (共識(shí)→其他驗(yàn)證者CO.2)。 有關(guān)我們提出的共識(shí)協(xié)議LibraBFT的詳細(xì)信息,請(qǐng)參閱我們的Libra區(qū)塊鏈中的狀態(tài)機(jī)復(fù)制技術(shù)文章。

區(qū)塊執(zhí)行和達(dá)成共識(shí)

8?— 作為達(dá)成協(xié)議的一部分,交易塊(包含T5)被傳遞給執(zhí)行組件。 (共識(shí)→執(zhí)行CO.3,EX.1

9?— 執(zhí)行組件管理虛擬機(jī)(VM)中的交易的執(zhí)行。 請(qǐng)注意,在塊中的交易已經(jīng)達(dá)成一致之前,這種執(zhí)行是以不確定的方式進(jìn)行的。 (執(zhí)行→VM?EX.2VM.3

10?— 在執(zhí)行塊中的交易之后,執(zhí)行組件將塊中的交易(包括T5)附加到Merkle累加器(分布式歷史賬本)。 這是Merkle累加器的內(nèi)存/臨時(shí)版本。 執(zhí)行了這些交易的(建議/推測(cè))結(jié)果返回到共識(shí)組件。 (共識(shí)→執(zhí)行CO.3,EX.1)。 從“共識(shí)”到“執(zhí)行”的箭頭表示執(zhí)行交易的請(qǐng)求是由共識(shí)組件完成的。 (為了在本文檔中一致使用箭頭,我們不使用箭頭來表示數(shù)據(jù)流)。

11?— V1(共識(shí)領(lǐng)導(dǎo)者)試圖與參與共識(shí)的其他驗(yàn)證者就該塊的執(zhí)行結(jié)果達(dá)成共識(shí)。 (共識(shí)→其他驗(yàn)證者CO.3

區(qū)塊提交(生成)

12?— 如果塊的執(zhí)行結(jié)果由一組具有超過多數(shù)票數(shù)的驗(yàn)證器達(dá)成一致后并簽名了,則驗(yàn)證器V1的執(zhí)行組件從高速緩存中讀取塊執(zhí)行的結(jié)果并提交塊中的所有交易至持久存儲(chǔ)。 (共識(shí)→執(zhí)行CO.4EX.3),(執(zhí)行→存儲(chǔ)EX.4ST.3

13?— Alice的賬號(hào)現(xiàn)在有100個(gè)Libra Coin,其序列號(hào)為6.如果T5由Bob重播,它將被拒絕,因?yàn)锳lice的賬號(hào)(6)的序列號(hào)大于重放的交易的序列號(hào)(5)。.

驗(yàn)證器組件交互

上一節(jié), 我們描述了一個(gè)交易從提交到在區(qū)塊鏈分布式數(shù)據(jù)庫中確認(rèn)的一個(gè)典型交易生命周期?,F(xiàn)在讓我們更深入的了解驗(yàn)證器組件之間的交互,驗(yàn)證器處理交易并響應(yīng)查詢。相信這些信息對(duì)以下人員最為有用:

想要全面了解系統(tǒng)如何在后臺(tái)工作。

有興趣為Libra Core軟件做出貢獻(xiàn)。

對(duì)于我們的描述,我們假設(shè)客戶端將交易TN提交給驗(yàn)證器VX。 對(duì)于每個(gè)驗(yàn)證器組件,我們將在相應(yīng)組件下的子組件中描述其每個(gè)組件之間交互。 請(qǐng)注意,描述組件間交互的子部分未嚴(yán)格按其執(zhí)行順序列出。 大多數(shù)交互與交易的處理相關(guān),少數(shù)與客戶端讀取查詢相關(guān)(查詢區(qū)塊鏈上的當(dāng)前信息)。

讓我們看一下驗(yàn)證器節(jié)點(diǎn)的核心邏輯組件:

準(zhǔn)入控制

內(nèi)存池

共識(shí)

執(zhí)行

虛擬機(jī)

存儲(chǔ)

在每個(gè)部分的末尾,我們提供了Libra Core相應(yīng)“README”的鏈接。

準(zhǔn)入控制 (AC)

)?

圖1.2準(zhǔn)入控制

準(zhǔn)入控制是驗(yàn)證器的唯一外部接口。 客戶端向驗(yàn)證器發(fā)出的任何請(qǐng)求都會(huì)先轉(zhuǎn)到AC。

客戶端 → AC (AC.1)

客戶端將事務(wù)提交給驗(yàn)證器VX的準(zhǔn)入控制。 這可以通過以下方式完成:AC::SubmitTransaction().

AC → 虛擬機(jī) (AC.2)

準(zhǔn)入控制訪問驗(yàn)證器的虛擬機(jī)(VM)并對(duì)交易初步檢查,以便盡早拒絕格式錯(cuò)誤的交易。 這通過以下方式完成:VM::ValidateTransaction().

AC → 內(nèi)存池 (AC.3)

一旦?VM::ValidateTransaction()?沒有返回錯(cuò)誤, AC通過Mempool::AddTransactionWithValidation().將交易轉(zhuǎn)發(fā)到驗(yàn)證器VX的內(nèi)存池。 只有當(dāng)TN的序列號(hào)大于或等于發(fā)送者帳戶的當(dāng)前序列號(hào)時(shí),驗(yàn)證器VX的內(nèi)存池才會(huì)接受來自AC的交易TN(請(qǐng)注意,除非交易序號(hào)是下一個(gè)序列號(hào),否則交易無法達(dá)成共識(shí))

AC → 存儲(chǔ) (AC.4)

當(dāng)客戶端對(duì)Libra區(qū)塊鏈執(zhí)行查詢時(shí)(例如,為了獲得Alice帳戶的余額),AC直接與存儲(chǔ)組件交互以獲取所請(qǐng)求的信息。

準(zhǔn)入控制自述文件

有關(guān)實(shí)施細(xì)節(jié),請(qǐng)參閱準(zhǔn)入控制自述文件.

虛擬機(jī) (VM)

圖1.3虛擬機(jī)

Move虛擬機(jī)(VM)驗(yàn)證并執(zhí)行Move字節(jié)碼編寫的交易腳本。

AC → 虛擬機(jī) (VM.1)

當(dāng)驗(yàn)證器VX的準(zhǔn)入控制從客戶端接收到交易時(shí),它會(huì)調(diào)用VM上的VM::ValidateTransaction()來驗(yàn)證交易。

虛擬機(jī) → 存儲(chǔ) (VM.2)

當(dāng)AC或內(nèi)存池通過VM::ValidateTransaction()請(qǐng)求虛擬機(jī)驗(yàn)證交易時(shí),虛擬機(jī)從存儲(chǔ)加載交易到發(fā)送者的帳戶并執(zhí)行以下驗(yàn)證:

檢查交易中的簽名是否正確(如發(fā)現(xiàn)錯(cuò)誤簽名的交易則拒絕)。

檢查發(fā)送人的帳戶身份信息,驗(yàn)證密鑰是否與其公鑰的哈希相同(對(duì)應(yīng)交易中的私鑰)。

驗(yàn)證交易的序列號(hào)是否不小于發(fā)件人帳戶的當(dāng)前序列號(hào)。 執(zhí)行此檢查可防止針對(duì)發(fā)件人帳戶重復(fù)廣播同一交易。

驗(yàn)證簽名了的交易中的程序代碼有沒有格式的錯(cuò)誤,因?yàn)樘摂M機(jī)無法執(zhí)行格式錯(cuò)誤的程序代碼。

驗(yàn)證發(fā)件人帳戶中是否有足夠的余額來支付交易中指定的最大Gas量,從而確保交易可以支付,且使用其賬戶中的資源。

執(zhí)行 → 虛擬機(jī) (VM.3)

執(zhí)行組件利用虛擬機(jī)通過VM::ExecuteTransaction()執(zhí)行交易。

這里重點(diǎn)要理解:執(zhí)行交易不同于更新分布式賬本的狀態(tài)和將執(zhí)行結(jié)果保存在存儲(chǔ)中。 交易TN首先執(zhí)行,但它作為在共識(shí)期間達(dá)成一致性共識(shí)的一部分來執(zhí)行。 如果與其他驗(yàn)證節(jié)點(diǎn)就交易順序及其執(zhí)行結(jié)果達(dá)成了一致,那么結(jié)果就將保留在存儲(chǔ)中,并更新分布式賬本的狀態(tài)。

內(nèi)存池 → 虛擬機(jī) (VM.4)

當(dāng)內(nèi)存池通過共享的內(nèi)存池從其他驗(yàn)證器接收交易時(shí),內(nèi)存池會(huì)在虛擬機(jī)上調(diào)用VM::ValidateTransaction()來驗(yàn)證交易。

虛擬機(jī)自述文件

有關(guān)實(shí)現(xiàn)的詳細(xì)信息,請(qǐng)參閱虛擬機(jī)自述文件

內(nèi)存池

圖1.4內(nèi)存池

內(nèi)存池是一個(gè)共享緩沖區(qū),用于保存“等待”執(zhí)行的交易。 當(dāng)新交易添加到內(nèi)存池時(shí),內(nèi)存池與區(qū)塊鏈系統(tǒng)中的其他驗(yàn)證器共享此交易。 為了減少“共享內(nèi)存池”中的網(wǎng)絡(luò)消耗,每個(gè)驗(yàn)證器負(fù)責(zé)將其自己的交易傳遞給其他驗(yàn)證器。 當(dāng)一個(gè)驗(yàn)證器從另一個(gè)驗(yàn)證器的內(nèi)存池接收到一個(gè)交易時(shí),該交易將被添加到接收者驗(yàn)證器的內(nèi)存池中。

AC → 內(nèi)存池 (MP.1)

執(zhí)行初始驗(yàn)證檢查后,驗(yàn)證器的AC將交易發(fā)送到驗(yàn)證器的內(nèi)存池。

但是僅當(dāng)TN的序列號(hào)大于或等于發(fā)件人帳戶的當(dāng)前序列號(hào)時(shí),驗(yàn)證器VX中的內(nèi)存池才接收發(fā)送人帳戶的交易TN。

內(nèi)存池 → 其余驗(yàn)證器 (MP.2)

驗(yàn)證器VX的內(nèi)存池與同一網(wǎng)絡(luò)中的其他驗(yàn)證器共享交易TN。

其他驗(yàn)證器在其內(nèi)存池中與驗(yàn)證器VX的內(nèi)存池共享交易。

共識(shí) → 內(nèi)存池 (MP.3)

當(dāng)驗(yàn)證器VX成為領(lǐng)導(dǎo)者時(shí),其共識(shí)將從其內(nèi)存池中提取一塊交易并將該塊復(fù)制到其他驗(yàn)證器。 這樣做的目的是為了將交易的排序和塊中交易的執(zhí)行結(jié)果達(dá)成共識(shí)。

請(qǐng)注意,因?yàn)榻灰譚N包含在共識(shí)塊中,它不能保證TN最終會(huì)存儲(chǔ)在區(qū)塊鏈的分布式數(shù)據(jù)庫中永久存儲(chǔ)(也就是有效區(qū)塊生成)。

內(nèi)存池 → 虛擬機(jī) (MP.4)

當(dāng)內(nèi)存池從其他驗(yàn)證器接收到交易時(shí),內(nèi)存池會(huì)在虛擬機(jī)上調(diào)用VM::ValidateTransaction()來驗(yàn)證交易。

內(nèi)存池自述文件

有關(guān)實(shí)現(xiàn)的詳細(xì)信息,請(qǐng)參閱Mempool自述文件。

共識(shí)

圖1.5共識(shí)

共識(shí)組件負(fù)責(zé)處理排序交易塊,并通過與網(wǎng)絡(luò)中的其他驗(yàn)證器一起參與共識(shí)協(xié)議來達(dá)成一致結(jié)果。

共識(shí) → 內(nèi)存池 (CO.1)

當(dāng)驗(yàn)證器VX是領(lǐng)導(dǎo)者/提議者時(shí),驗(yàn)證器VX的共識(shí)通過該方式Mempool::GetBlock()從其內(nèi)存池中提取一個(gè)交易塊,并發(fā)出提議。

共識(shí) → 其他驗(yàn)證器 (CO.2)

如果VX是提議者/領(lǐng)導(dǎo)者,則其共識(shí)將提取的交易塊復(fù)制到其他驗(yàn)證器。

共識(shí) → 執(zhí)行, 共識(shí) → 其他驗(yàn)證器 (CO.3)

共識(shí)與執(zhí)行組件交互來執(zhí)行一個(gè)交易塊。 共識(shí)通過執(zhí)行組件來執(zhí)行一個(gè)交易塊:Execution:ExecuteBlock()(參見共識(shí)→執(zhí)行

在執(zhí)行塊中的交易之后,執(zhí)行組件響應(yīng)這些交易執(zhí)行后的一個(gè)結(jié)果。

共識(shí)出示執(zhí)行后的結(jié)果,并試圖與參與協(xié)商的其他驗(yàn)證節(jié)點(diǎn)就此結(jié)果達(dá)成一致。

共識(shí) → 執(zhí)行 (CO.4)

如果網(wǎng)絡(luò)中有足夠的驗(yàn)證器為同一執(zhí)行結(jié)果來投票,則驗(yàn)證器VX的共識(shí)組件通過Execution::CommitBlock()通知執(zhí)行組件該交易塊已準(zhǔn)備好提交。

共識(shí)自述文件

有關(guān)實(shí)施細(xì)節(jié),請(qǐng)參閱共識(shí)自述文件.

執(zhí)行

圖1.6執(zhí)行

執(zhí)行組件的工作是協(xié)調(diào)交易塊(區(qū)塊),并維持一個(gè)通過共識(shí)協(xié)商投票的過渡狀態(tài)。

共識(shí) → 執(zhí)行 (EX.1)

共識(shí)請(qǐng)求執(zhí)行組件通過以下方式來執(zhí)行交易塊:?Execution::ExecuteBlock().

執(zhí)行組件維護(hù)一個(gè)“暫存器”,它將保存存儲(chǔ)器中Merkle累加器中相關(guān)部分的副本。 此信息用于計(jì)算區(qū)塊鏈當(dāng)前狀態(tài)的根哈希值。

將當(dāng)前狀態(tài)的根哈希與關(guān)于塊中的交易信息組合以確定Merkle累加器的新根哈希值。 這一步在保留任何數(shù)據(jù)之前就執(zhí)行了,這是為了確保在足夠數(shù)量的驗(yàn)證者達(dá)成協(xié)議之前不會(huì)存儲(chǔ)任何狀態(tài)或交易。

執(zhí)行計(jì)算推測(cè)根哈希值,然后驗(yàn)證器VX的共識(shí)簽署此根哈希值,并嘗試與其他驗(yàn)證器達(dá)成對(duì)此根哈希值的協(xié)議。

執(zhí)行 → 虛擬機(jī) (EX.2)

當(dāng)共識(shí)請(qǐng)求執(zhí)行組件使用:Execution::ExecuteBlock()執(zhí)行交易塊時(shí),執(zhí)行組件使用虛擬機(jī)來確定執(zhí)行交易塊的結(jié)果。

共識(shí) → 執(zhí)行 (EX.3)

如果足夠(法定)數(shù)量的驗(yàn)證器同意該塊的執(zhí)行結(jié)果,那么每個(gè)驗(yàn)證器會(huì)一致性通過執(zhí)行Execution::CommitBlock()該執(zhí)行包括了:通知其執(zhí)行組件該塊已準(zhǔn)備好提交, 對(duì)執(zhí)行組件的進(jìn)行包括同意的簽名,及為其協(xié)議提供證明。

執(zhí)行 → 存儲(chǔ) (EX.4)

執(zhí)行組件從其“暫存器”獲取值,并通過Storage::SaveTransactions()將它們發(fā)送到存儲(chǔ)器以實(shí)現(xiàn)持久存儲(chǔ)。 執(zhí)行篩選刪除“暫存器”中的舊值(例如,無法提交的塊)。

執(zhí)行自述文件

有關(guān)實(shí)現(xiàn)的詳細(xì)信息,請(qǐng)參閱執(zhí)行自述文件.

存儲(chǔ)

圖1.7存儲(chǔ)

存儲(chǔ)保存共識(shí)執(zhí)行后的交易塊及其執(zhí)行結(jié)果。 在以下情況下,將通過存儲(chǔ)一個(gè)/一組交易(包括交易TN):

以下所有問題,只要網(wǎng)絡(luò)中超過2f + 1的驗(yàn)證者就能通過共識(shí)協(xié)議達(dá)成共識(shí):?

包含在塊中的交易。

交易的排序。

包含在塊中的交易的執(zhí)行結(jié)果。

有關(guān)如何將交易附加到區(qū)塊鏈中數(shù)據(jù)結(jié)構(gòu)的信息,請(qǐng)參閱[Merkle累加器](https://developers.libra.org/docs/reference/glossary#merkle-accumulators)。

虛擬機(jī) → 存儲(chǔ) (ST.1)

當(dāng)AC或內(nèi)存池調(diào)用VM::ValidateTransaction()來驗(yàn)證交易時(shí),VM::ValidateTransaction()從存儲(chǔ)中加載發(fā)送人的帳戶,并通過只讀權(quán)限來檢查交易的有效性。

執(zhí)行 → 存儲(chǔ) (ST.2)

當(dāng)共識(shí)組件調(diào)用Execution::ExecuteBlock()時(shí),執(zhí)行組件從存儲(chǔ)中讀取當(dāng)前狀態(tài)并結(jié)合內(nèi)存中的“暫存器”數(shù)據(jù)來確定執(zhí)行結(jié)果。

執(zhí)行 → 存儲(chǔ) (ST.3)

一旦達(dá)成了對(duì)交易塊的共識(shí),執(zhí)行組件就會(huì)通過調(diào)用?Storage::SaveTransactions()來存儲(chǔ)來保存交易塊并永久記錄它們。 同時(shí)還將存儲(chǔ)網(wǎng)絡(luò)中同意該交易塊驗(yàn)證器節(jié)點(diǎn)的數(shù)字簽名。

該塊中“暫存器”的內(nèi)存數(shù)據(jù)將更新到存儲(chǔ)中,并記錄交易。

更新存儲(chǔ)時(shí),每個(gè)交易變更后的所有資源的序列號(hào)都會(huì)相應(yīng)更新。

注意:對(duì)于來自該帳戶的每個(gè)已提交交易,Libra區(qū)塊鏈上的帳戶序列號(hào)增加1。

AC → 存儲(chǔ) (ST.4)

客戶端查詢區(qū)塊鏈中的信息,AC直接與存儲(chǔ)交互以讀取所請(qǐng)求的信息。

存儲(chǔ)自述文件

有關(guān)實(shí)現(xiàn)的詳細(xì)信息,請(qǐng)參閱存儲(chǔ)自述文件.

參考

歡迎頁

我的第一筆交易?- 指導(dǎo)您使用Libra CLI客戶端在Libra區(qū)塊鏈上執(zhí)行您的第一筆交易。

Move入門?- Move新區(qū)塊鏈編程語言。

交易的生命周期?- 提供交易提交和執(zhí)行時(shí)“幕后”發(fā)生的事情。

Libra核心概述?- Libra核心組件的概念和實(shí)現(xiàn)細(xì)節(jié)。

CLI指南?- 列出Libra CLI客戶端的命令及其用法。

Libra 詞匯表?- 提供Libra術(shù)語的快速參考。

Libra區(qū)塊鏈中的狀態(tài)機(jī)復(fù)制?— 詳細(xì)介紹我們的共識(shí)協(xié)議LibraBFT。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容