茶話會第三期:想和你玩一局剪刀、石頭、布

昨天晚上九點,在 Zoom 頻道,成功舉辦了第三期茶話會,本期茶話會的分享人是來自 CKB 的核心開發者,人稱幣圈金城武的蔣金洋老師。

分享內容主要包括兩個部分:第一部分,主要介紹了 CKB 的交易結構,解讀了 CKB 交易中各個字段的含義;第二部分,尤爲精彩,蔣老師爲我們介紹了在 CKB 上實現「剪刀、石頭、布」這樣一個小遊戲的設計思路。

先上實況視頻,昨晚錯過的小夥伴可以直接觀看完整視頻:

關於這次分享的第一部分,我就不過多介紹了,大家可以提供視頻,以及 CKB Transaction Structure 瞭解相關內容。我要來和大家着重介紹一下本次分享的第二部分。

要知道不少現場的小夥伴聽完蔣老師的分享後,不禁讚歎:

S 君:“妙啊,原來還可以這麼設計。”

E 君:“CKB 居然還可以這麼玩!”

所以,你要不要來和我在 CKB 上玩一局「剪刀、石頭、布」~

首先,我們當然要來分析一下需要實現的遊戲邏輯。

現實中,我們是怎麼玩「剪刀、石頭、布」這個遊戲的呢?通常這個遊戲是在兩個人之間進行的,在確定完兩位遊戲參與對象後,然後我們會一起喊一個口號,比如“1,2,3,剪刀、石頭、布”,然後我們同時伸手做出選擇,然後一比較,勝負一目瞭然。

但是這樣的對決,通常會面臨一個問題,就是兩位玩家實際上是不可能在同一時間做出動作的,這就會導致通常後出手的玩家,會存在一些優勢,因爲只要手腦並用且速度夠快,就可以根據對方的出手情況,在第一時間進行調整,做出必勝的選擇。

這其實也是葛優發明,分歧終結機的原因。

茶話會第三期:想和你玩一局剪刀、石頭、布

同樣的,我們在區塊鏈上進行「剪刀、石頭、布」這樣的遊戲,也無法保證兩位玩家同時做出選擇(因爲這是不可能的),那麼我們在 CKB 上,要如何實現這樣一個分歧終結機呢?

先來向大家介紹一下整個遊戲設定。本局遊戲,我們有兩個玩家:Alice 和 Bob,今天他們要來 CKB 上玩一局「剪刀、石頭、布」,當然這是一個存在輸贏的遊戲,爲了帶一點娛樂的氣氛,Alice 和 Bob 都需要拿出一部分 CKB 作爲遊戲勝利者的獎勵,比如兩人都拿出 200 CKB,勝利者就可以將這 400 CKB 都拿走。

如何我們思考一下整場遊戲的遊戲邏輯:

茶話會第三期:想和你玩一局剪刀、石頭、布

  1. 第一步,首先 Alice 開始了一局遊戲,並提交了一個帶有自己選擇哈希的 cell,我們這裏把 Alice 出的結果記爲 [A 選擇],注意,而這裏提交到鏈上的是 Hash[A 選擇],而不是將 [A 選擇] 直接上鍊。

  2. 第二步,Bob 看到了 Alice 發起了這局遊戲,決定加入這局遊戲,然後提交了自己的結果,我們記爲 [B 選擇],注意,這裏 Bob 是直接將 [B 選擇] 提交到鏈上的。

  3. 最後一步,Alice 提交自己的 [A 選擇] 到鏈上,然後根據雙方出的 [A 選擇] 和 [B 選擇] 得出最終的勝負平關係,然後分配金額。

接下來我們會一步一步,詳細地向大家介紹一下,整個遊戲過程是在技術上是如何實現的。

我們先看每一步具體的步驟,最後再來進行一個總結,分析這樣的遊戲合約需要具體如何去設計。

Alice 創建遊戲

茶話會第三期:想和你玩一局剪刀、石頭、布

首先,第一步,Alice 需要創建一個「剪刀、石頭、布」的遊戲,她需要發送一筆交易。在這筆交易中:

輸入的 Cell,和大家平時持有的 CKB 的狀態是完全一致的。

而輸出的 Cell,其中 Lock 改成了 Dummy lock,這意味着這個 Cell 總是可以成功解鎖,任何人都是可以解開這個 Cell 的。但是這並不是說,誰都可以將其中的 CKB 取走,通過輸出 Cell 將 CKB 取出時的邏輯將會受到 Type 的限制。

在 Type 中寫入本次「剪刀、石頭、布」遊戲的合約的腳本,這裏可以直接引用已經存在在鏈上的「剪刀、石頭、布」遊戲合約的 Cell。

Alice 會在 Data 中存入三個字段,分別是:這局遊戲的狀態,Hash [A 選擇],Alice’s lock hash。

這裏遊戲狀態的標記爲:

*遊戲中只有一個玩家,遊戲狀態爲 0;

*遊戲中有兩個玩家,遊戲狀態爲 1。

注意,這裏 Data 中提交的是 Hash [A 選擇],因此後手玩家,無法知道 Alice 究竟出了什麼。另外這裏添加的 Alice’s lock hash,就決定了在當前遊戲狀態下,輸出 Cell 的 Lock 中,只能填寫 Alice's lock hash,此時輸出 Cell 的 Lock 只能爲創建遊戲的玩家,別人沒有辦法被盜走。

實際上,在這個遊戲的邏輯中,最終可以解鎖 Cell 拿走 CKB 的只有兩個人,一個人遊戲的創建者,一個是遊戲的參與者。其他人任何人都搶不走這些 CKB。

無人應答,遊戲撤銷

茶話會第三期:想和你玩一局剪刀、石頭、布

在上一步中 Alice 創建了一局「剪刀、石頭、布」遊戲,按照輸出 Cell 的 lock 的設計,任何人都可以參與這局遊戲。

很遺憾,Alice 創建的遊戲,可能很久很久都沒有人蔘與,這時候,我們不可能讓 Alice 一直等待在線上。所以我們會設計一個 since 字段,實現這樣一個邏輯:從 Alice 創建遊戲開始,如果遊戲狀態一直爲 0,超過 1000 個區塊,這個時候 , Alice 就可以退出遊戲,取回自己抵押的 CKB。

關於 since 實現的具體方法,大家可以查看:

https://ckb.dev/topic/27/rfcs-0017-tx-valid-since

我們可以通過 since 對區塊號、週期號、區塊時間戳進行相對或者絕對的限制,從而保證某筆交易或者某種邏輯必須在某個時間點之後纔可以被執行。

Bob 加入了 Alice 創建的遊戲

茶話會第三期:想和你玩一局剪刀、石頭、布

很開心,Bob 看到了 Alice 創建的這局遊戲,決定加入這局遊戲。注意,任何人都可以看見 Alice 創建的這局遊戲,玩家只需要在 CKB 鏈上搜索所有 Cell 的 Type hash 字段,等於「剪刀、石頭、布」遊戲合約的哈希值即可。很幸運,這局的另一位玩家恰好叫 Bob 而已。

這個時候 Bob 需要提交一筆交易,其中輸入 Cell 有兩個,一個是 Alice 創建的,任何人都可以解鎖的,包含了遊戲合約的 Cell,另一個 Cell 是 Bob 自己的 CKB Cell,其中 Capacity 一項,需要滿足 Alice 在遊戲合約中要求的玩這局遊戲所需的 CKB 的數量。

正如我們在遊戲規則中設定的,Alice 和 Bob 都需要出 200 CKB 作爲遊戲的參與金額,那麼在遊戲合約中,我們可以去驗證 Alice 和 Bob 兩次輸入的 Cell 的 Capacity 是不是都等於 200 CKB,如果不等,那麼這筆交易是無法實現的。

然後我們來看一下輸出,其中 Lock 還是 Dummy lock,Type 還是遊戲合約,而 Capacity 已經變成了 400 CKB (200 CKB 來自 Alice,200 CKB 來自 Bob)。

在 Data 中,遊戲狀態已經從 0 變爲了 1,這意味着這局遊戲已經有兩人蔘加,可以進入最後的結算過程了。Data 中還包含了:Hash [A 選擇],Alice’s lock hash,[B 選擇],Bob’s lock hash。

這個是時候你想說,Alice 不是知道了 Bob 出了什麼嗎,那 Alice 是不是可以作弊了?

不,Alice 並不能作弊,熟悉 Hash[] 的小夥伴知道,只有輸入兩次完全一致的數據或者內容,Hash[] 的值纔會一致,一旦有一個字母發生了變化,兩次的 Hash 值都是截然不同的。因此 Alice 只有老老實實地提交自己最初做出的選擇,遊戲合約纔可能驗證通過。

這裏加入的 Alice’s lock hash 和 Bob’s lock hash,保證了最終輸出的 Cell 只能歸屬於 Alice 或者 Bob,不可能被另外一個人搶走。

Alice 長時間不迴應

茶話會第三期:想和你玩一局剪刀、石頭、布

在 Bob 發送完交易之後,Alice 其實已經知道了遊戲的結果,但是除了 Alice 之外的其他人都還不知道這局遊戲最終的結果,只有等到 Alice 將自己最初的選擇提交到鏈上,大家才知道這局遊戲誰纔是真正的贏家。

這個時候就可能會發生一種情況。Alice 長時間不提交自己的 [A 選擇],可能是由於 Alice 真的掉線了,也可能是因爲 Alice 發現自己輸了,不想再提交自己的選擇。

這個時候我們就又需要用上 since 字段了,遊戲合約要求,在第二位玩家(這裏就是我們的 Bob),提交完交易之後,如果 1000 個區塊後,創建遊戲的玩家(也就是我們的 Alice),如果還沒有不提交最初的選擇,創建第三步結算交易,那麼這些 CKB 都歸屬於第二位玩家。

所以如果 Alice 不在 Bob 發起交易後的 1000 個區塊內,提交 [A 選擇],作爲對 Alice 的懲罰,Bob 將無條件獲勝,拿走所有 CKB。

Alice 完成提交,進行遊戲結算

茶話會第三期:想和你玩一局剪刀、石頭、布

上面說到 Alice 在看到 Bob 的交易之後,其實就已經知道比賽的結果了,如果 Alice 獲得了勝利,毫無疑問 Alice 非常有動力去提交最終的交易;如果 Alice 輸了,因爲 since 字段的存在,不管提不提交最終的交易,獎金都歸屬於 Bob 了(這裏請注意,在具體遊戲設計中,如果 Alice 按時提交了 [A 選擇],發出了最終的交易,哪怕 Alice 輸了,也可以考慮返還一小部分 CKB 給 Alice,這樣不管是輸是贏,Alice 都有動力去創建第三筆交易。(史迪仔認爲:這種遊戲也可以引入押金模式,創建遊戲的玩家需要多存入 100 CKB 作爲押金,只有按時提交最終的結果,才能返回押金,不然會被罰沒。不管是返還還是押金,其實實現的邏輯是完全一致的))。

這裏我們來分析一下最後一筆交易:

輸入 Cell 就是之前 Bob 提交完信息的 Cell,在 Witness 內,Alice 需要提交 [A 選擇]。

輸出 Cell 就是根據遊戲規則,Alice 根據遊戲結果創建的獎金分配 Cell,其中 Alice 獲得了多少 CKB,鎖到 Alice 的 lock 中;Bob 獲得了多少 CKB,鎖到 Bob 的 lock 中。

你是不是會很奇怪,爲什麼我這裏說的是,Alice 創建的獎金分配 Cell,那 Alice 可以隨便創建,將獎金都劃分給自己麼?

當然不可以,Alice 創建的最終結果還是需要通過遊戲合約驗證的,只有滿足遊戲合約設定的交易纔可能被真正執行。這樣設計的原因其實是因爲,CKB 做的只是鏈上的驗證,而不做鏈上的計算,一筆交易被提交到鏈上,其中的輸入 Cell,輸出 Cell 都是已經確定了的,只有驗證成功的交易才能被執行,驗證錯誤的交易無法被執行,整個過程不像是以太坊,還需要經過一個鏈上計算的過程。

至此,整個遊戲的邏輯已經基本完成了,在這裏我再簡要地回顧一下這個「剪刀、石頭、布」遊戲合約需要執行哪些驗證內容:

  1. Alice 創建遊戲,此時遊戲狀態爲 0,Alice 還提交了 Hash[A 選擇],任何人都可以參與此遊戲。

  2. 無人加入 Alice 的遊戲,1000 個區塊後,輸出 Cell 的 lock 只能填入 Alice 的 lock hash,遊戲金額返還給 Alice,本局遊戲消失。

  3. Bob 加入 Alice 的遊戲,輸入了等於遊戲金額的 CKB,並且提交了自己的「剪刀、石頭、布」的選擇,等待最終開獎。

  4. Alice 在 Bob 完成交易的 1000 個區塊後,仍不提交 [A 選擇],輸出 Cell 的 lock 只能填入 Bob 的 lock hash,遊戲金額全部給到 Bob,本局遊戲消失。

  5. Alice 在規定時間內,提交了 [A 選擇],若兩次 Hash[A 選擇] 不相等,則交易無法通過驗證。若 Hash[A 選擇] 通過驗證,再依次驗證輸出 Cell 的 Capacity 和 Lock 是否符合遊戲規則。如果全部通過驗證,則打包交易,本局遊戲消失。

要知道,這是一個任何人都可以創建的「剪刀、石頭、布」遊戲,任何人都可以加入任何一個已經存在且目前還沒有結束的「剪刀、石頭、布」遊戲。

沒有中心化的風險,你不用擔心你的 CKB 被人盜走、騙走,你只需要愉快地在這個遊戲中玩耍。

茶話會第三期:想和你玩一局剪刀、石頭、布135

現場參與茶話會的小夥伴,還對這個遊戲實現的具體內容提出了一系列的問題:

比如,Alice 的 [A 選擇] 中應該是需要加入一個隨機數的,這個隨機數要如何設置呢?

能不能再將這個遊戲過程再簡化一點,優化玩家的使用體驗呢?

能不能在這個基礎上實現更多更復雜的遊戲邏輯呢?

關於這些問題,我在這裏賣個關子,快去視頻中找答案吧!

關於這個遊戲,如果您有任何問題或者想法,歡迎點擊“閱讀原文”,前往 Talk 論壇參與討論。

茶話會第三期:想和你玩一局剪刀、石頭、布

更多 [CKB 茶話會] 系列視頻,歡迎登陸 bilibili 搜索關鍵詞 [CKB 茶話會] 瞭解更多:

茶話會第三期:想和你玩一局剪刀、石頭、布

往期茶話會回顧:

茶話會第三期:想和你玩一局剪刀、石頭、布

第二期:CKB 錢包和 NervosDAO 全流程

茶話會第三期:想和你玩一局剪刀、石頭、布

第一期:原來 CKB 上的 UDT 可以這麼玩

看到這裏不容易

點個關注吧!

來源鏈接:mp.weixin.qq.com