[閒聊] 在ETH智能合約內驗證過去區塊的Hash值

作者: Ayukawayen (亞布里艾爾發芽>//<)   2020-08-14 17:39:35
在Ropsten測試鏈上放了一個驗證區塊Hash值的合約。
如果我們要在乙太坊的智能合約內取得過去某個區塊的Blockhash,EVM有提供內建函式
blockhash(uint blockNumber),可以取得最近256個區塊的Hash值。若是超過256個區
塊,內建函式就無能為力了。取而代之的,我們可以要求使用者把區塊Hash值及證明傳
入合約函式,由合約驗證傳入的區塊Hash值是否正確。
合約位址及程式碼見Etherscan:
https://ropsten.etherscan.io/address/2c003df99cab1064ed93e273f54275ee8e24393a
另外有個懸賞合約給找出偽陰性(?)案例的板友1個Ropsten ETH,請見文章最後。
(雖然Ropsten ETH到水龍頭拿就有了 XD)
=============================================================================
MMR結構
合約的原理是將區塊Hash值用Merkle Mountain Range結構儲存
Merkle Mountain Range(MMR)結構就是多棵不同高度的Full Merkle Tree
G
/ \
/ \
C F
/ \ / \
A B D E H
/ \ / \ / \ / \ / \
00 01 02 03 04 05 06 07 08 09 10
如圖,11個Blockhash值組成3棵Tree,分別是
Block#00-#07的8個區塊組成高度3的Tree
Block#08-#09的2個區塊組成高度1的Tree
Block#10的1個區塊組成高度0的Tree
合約儲存這3棵Tree的Root(稱為Peak),也就是G、H、10。
當新的Blockhash值加入MMR結構時,會發生合併現象。
G
/ \
/ \
C F J
/ \ / \ / \
A B D E H I
/ \ / \ / \ / \ / \ / \
00 01 02 03 04 05 06 07 08 09 10 11
Block#11加入後,Block#08-#11合併為1棵高度2的Tree,
合約內儲存的內容變成G、J兩個Peak。
MMR的證明和驗證與一般的Merkle Tree證明流程相同,
要證明00,則額外傳入[01,B,F]做為證明,
合約內進行3次hash後,將結果與G比對即可驗證。
基本的原理是這樣,至於技術細節的說明還在寫,若想研究細節請先看程式碼。
做了一個簡單的網頁介面,可以看到MMR結構的現況,產生證明和進行驗證:
https://ayukawayen.github.io/MerkleMountainRange/
(建議開Metamask連,Metamask要連到Ropsten鏈)
=============================================================================
MMR Token
合約需要定期將新區塊的Hash值寫入MMR結構。
傳送Tx至合約位址會呼叫合約的fallback function,觸發更新流程。
這個動作需要花費gas,根據更新者所花費的gas值,給予等量的MMR Token做為回報。
任何人都可以傳送Tx來協助維護合約,Tx不需要任何input data,Gas limit建議設為
330000。
以下是一個範例Tx的ID,總共花了237,682的gas,獲得202,670個MMR Token:
0xff230cc54fe3837a074b99d4056e44b4fd4348b08852728418aba170077ad9f2
MMR Token可以用來支付驗證手續費。
其他合約在鏈上呼叫合約的verifyOnChain()函式時,每次驗證收取6000個MMR Token做
為手續費,鏈下呼叫verify()函式時則不需要手續費。
也可以直接用Ropsten ETH向合約換MMR Token,避免需要驗證卻無法取得Token的情況。
=============================================================================
懸賞合約
合約位址與程式碼同樣見Etherscan:
https://ropsten.etherscan.io/address/a702611a1b4cd6149df1bac72d3462e286d3d918
UI還沒寫好,熟悉Etherscan操作的人可以先使用Etherscan和合約互動。
只要能輸入1個blockNumber、2個blockHash及證明,符合以下條件:
兩個blockHash都不是0
兩個blockHash值不相同
兩個blockHash都通過MMR驗證
就能取得合約裡的所有Ropsten ETH。
兩次驗證需要12000個MMR Token,底下開放推文,留下Ropsten位址,我會轉12000個
Token過去,approve給懸賞合約後,呼叫challengeWithToken()進行挑戰。
=============================================================================
如果有在Ropsten上開發智能合約,有驗證過去區塊的需求的話,也可以試用看看。
不過程式碼是未經審查的,可能有bug。
作者: DarkerDuck (達克鴨)   2020-08-14 18:20:00
先推,待會貼地址
作者: leftc (阿左)   2020-08-14 20:39:00
推,試玩了一下收到12萬MMR,when coinbase? (誤
作者: ECZEMA (加油!)   2020-08-14 21:07:00
推 回溯驗長鏈老區塊的工具 這個使用時機和應用有哪些呢?
作者: Ayukawayen (亞布里艾爾發芽>//<)   2020-08-14 21:23:00
這是我想做放置型領獎遊戲碰到的需求,有空要把它接到https://ayukawayen.github.io/GolemGemGathering/Web(然而對ETH來說放置遊戲的市場甚至難以稱為使用時機XD
作者: ECZEMA (加油!)   2020-08-14 22:22:00
感謝解說 對查金流很有用
作者: troylee (troylee)   2020-08-15 00:14:00
0xE5AB5A463c1d9147C49cB09C9f37FA0E21dE433B 來試試看收到了
作者: lolo0856 (lolot)   2020-08-15 01:30:00
好玩!!
作者: Ayukawayen (亞布里艾爾發芽>//<)   2020-08-17 18:01:00
用etherscan介面把MMR上架了才發現uniswap網頁只要把metamask切到測試鏈就能接到測試鏈上的uniswap環境 XD總之現在Ropsten的uniswap上也有MMR/ETH交易對了
作者: ECZEMA (加油!)   2020-08-17 20:45:00
強! 鎖定 NMR!
作者: Ayukawayen (亞布里艾爾發芽>//<)   2020-08-18 17:00:00
https://i.imgur.com/76xpcXe.png 剛好32768 紀念一下

Links booklink

Contact Us: admin [ a t ] ucptt.com