在上一篇文章《1、如何保證 DAS 帳戶的惟一性》中的最後,咱們提到了仍然存在的 Cell 競爭問題。具體問題以下:服務器
假定鏈上已經註冊有 a.bit、b.bit、z.bit 三個帳戶,如今有兩個用戶分別想要註冊 c.bit,d.bit,且註冊時間很靠近。按照規則,註冊發生時,他們使用的註冊服務會分別構造交易讓用戶簽名,交易的內容爲將要註冊的帳戶插入到 b.bit 以後。網絡
問題在於,兩筆交易都會試圖將 AccountCell(b.bit) 消費掉,而一個 Live Cell 只能被消費一次,那麼就會致使必然其中一筆交易會失敗。假定註冊 c.bit 的交易成功了,而註冊 d.bit 的交易失敗了。註冊 d.bit 的用戶不得不被他所使用的註冊服務要求從新簽名交易。這是因爲註冊 d.bit 時,本來須要將 AccountCell(b.bit) 消費掉,而如今須要改成消費 AccountCell(c.bit),交易結構內容發生了變化,必須從新簽名。架構
這將致使很是糟糕的用戶體驗。事實上,當註冊的用戶數量變多時,大部分用戶不得不一次又一次的簽名交易,直到他能註冊成功。 <br/>框架
澄清問題
要解決問題,首要的是澄清問題
上面的問題之因此是個問題,根本之處在於什麼呢?是在於引用了相同的 Cell 致使的交易失敗嗎?若是是這樣,咱們就會將思考聚焦在如何避免交易引用相同的 Cell。進一步思考下去,咱們可能就要推翻有序鏈表這個設計了。函數
那若是咱們把問題歸結爲,交易失敗並非問題,用戶須要不斷簽名交易纔是問題,會怎麼樣呢?那咱們就會將思考聚焦在如何避免用戶不斷地簽名。而這彷佛並不困難。url
Keeper
咱們引入 Keeper 這個機制來解決這個問題。.net
Keeper 是: 1) 一個有任何人均可以無需許可運行的鏈下程序。 2) Keeper 是 dApp 的一部分,不一樣的 Keeper 服務於不一樣的 dApp。 3) 它會根據 CKB 鏈上的狀態,發出交易,修改 CKB 的鏈上狀態。
引入 Keeper 以後,多個用戶同時註冊 DAS 帳戶的技術過程就變成了:設計
- 用戶發起一筆交易,釋放一個包含註冊信息的指令Cell,好比「我要註冊 c.bit」,「我要註冊 d.bit」。同時,這些 Cell 的 lock 是 always_success,任何人均可以消費它們。這筆交易並不會將用戶要註冊的帳戶插入到有序鏈表中。
- Keeper 經過監聽鏈上狀態,會發出一筆交易。將這兩個指令Cell,做爲 input,並在 output 中建立對應的 AccountCell(c.bit),AccountCell(d.bit),一塊兒將他們插入到有序鏈表中合適的位置。
能夠看到,經過這種將多個帳戶註冊請求打包一塊兒插入鏈表的方式,能夠有效地避免用戶屢次簽名的問題。那咱們對 Keeper 的理解,應僅僅是將註冊請求打包處理來避免 Cell 競爭嗎?其實否則。3d
因爲 Keeper 是任何人均可以無需許可來運行(他理應被設計爲如此)的鏈下程序,那麼當多我的運行 Keeper 時,Keeper 之間又會出現 Cell 競爭問題:每一個 Keeper 都在作相同的工做,將用戶的指令Cell 變成對應的 AccountCell 插入到鏈表中合適的位置,它們又要去競爭 Cell 了。code
這彷佛讓人沮喪,Cell 競爭無處不在。但仔細思考,這壓根就再也不是問題了。Keeper 是程序啊,它們發出的交易失敗了 ,有必要的話,它們能夠自動簽名新的交易。交易失敗不會讓它們煩躁,也不會讓它們有任何損失。而這,正好解決了咱們想要解決的問題:如何避免用戶不斷的簽名。
至此,咱們便完全解決了上一篇文章遺留的,由 Cell 競爭所帶來的問題。
對 Keeper 的進一步思考:
- Keeper 更像是一個可執行函數集合,用戶的指令Cell 就是對其中某個函數的調用信息。Keeper + 鏈上驗證腳本,構成了完整的以太坊思惟框架下的 dApp:與 dApp 交互, 就是發送一筆交易,調用 dApp 暴露出來的函數接口,傳入對應的參數。
- Keeper 模塊是 CKB 上 dApp 不可或缺的模塊 ——「鏈下計算」模塊。
- 運行 Keeper 畢竟須要服務器成本,那麼誰又會來運行 Keeper 呢?若是沒有人運行 Keeper 了,那 dApp 不就沒法工做了嗎?
- 做爲 dApp 開發者有充分的理由和動力去保障 dApp 的正常工做,因此他們會去運行,但也不是絕對的。甚至若是隻有 dApp 開發者運行,那開發者的鏈下服務穩定性,會直接影響 dApp 的可用性。
- 因此,咱們更建議從經濟激勵的角度去思考如何鼓勵你們來運行 Keeper。這也正是 DAS 的作法:任何將用戶的指令Cell 轉變爲 AccountCell,從而幫用戶完成註冊的 Keeper,均可以分享到必定比例的註冊費用。事實上,在 DAS 中,大量的邏輯處理都是以這樣的方式去激勵 Keeper 完成的。
- 再結合 Keeper 是可執行函數集合這個理解,少許的(也可能爲 0) Keeper 獎勵 + CKB網絡礦工費,二者合併到一塊兒,就是用戶與合約交互所須要付出的整體成本。更進一步,Keeper 獎勵能夠理解爲「鏈下計算」相關的費用,CKB 網絡礦工費可理解爲「鏈上驗證」相關的費用。 對於以太坊而言,驗證和計算都是在鏈上進行,但咱們仍能夠從邏輯上將其費用拆分紅計算和驗證兩部分。因此從細節上看,CKB 和 ETH 差異很大,但在某個抽象層級來看,他們又具有一致性。
DAS 創始人 TimYang (楊敏)在 Nervos CKB 上開發了 DAS 去中心化帳戶服務。藉着此次的產品開發,TimYang 經過《從 DAS 開始瞭解 CKB 應用開發》系列文章,向你們闡述他的設計思路和開發歷程,讓你們瞭解如何在世界上第一個基於 UTXO 架構的公鏈 CKB 上構建產品級應用。
推薦閱讀:從 DAS 開始瞭解 CKB 應用開發(一)—— 如何保證 DAS 帳戶的惟一性
如若您有更多關於 DAS 產品的使用心得,以及在 CKB 上開發的看法,歡迎前往 Nervos Talk 論壇討論: