PTT評價

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

看板DigiCurrency標題[閒聊] 在ETH智能合約內驗證過去區塊的Hash值作者
Ayukawayen
(鮎川彥)
時間推噓 8 推:8 噓:0 →:8

在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。


--
ethereum:0xF78CF7Bb109f7fB55e3Cba2DD87edd5e836Eb0b3

simpleledger:qqjzmy6mjp8sp97c7thhflv9s2j96xk0q5dcppcf4p

--

※ PTT 留言評論
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.114.123.85 (臺灣)
PTT 網址

DarkerDuck08/14 18:20先推,待會貼地址

leftc08/14 20:39推,試玩了一下收到12萬MMR,when coinbase? (誤

一個小秘密是推文可以拿12000個Token,但隨便往合約丟個Tx就可以拿十幾萬Token了XD

ECZEMA08/14 21:07推 回溯驗長鏈老區塊的工具 這個使用時機和應用有哪些呢?

我有想了一下,還沒有很深入。 首先,能驗證BlockHash就能驗證BlockHeader,能驗BlockHeader就能驗BlockBody。 我想重點會在這裡。 如此可以驗證「指定內容的Tx確實存在於鏈上」, 當然,也可以驗證 Tx Receipt 及 Log 的存在性。 智能合約內部是無法查詢過去的Log的,所以ERC20提供了Transfer Event外,還採用了 approve的方式來做合約間的Token支付。 如果能驗證歷史Log的存在,就可能做到讓使用者提交Log內容及證明,而合約內可以驗 證某帳戶確實曾經在另一個合約做過特定的行為。 (例:曾經向DAI合約發出Tx,成功轉了100 DAI到指定位址,在區塊內留下DAI的Log。 畢竟DAI合約做完轉帳後,其他合約不會收到通知(ERC223?) ) 當然以ERC20來說,用approve機制就好了, 但能驗Tx Receipt和Log的存在性可以一般化的處理任何其他合約的Log, 還可以檢驗非關合約的原生ETH的轉帳證明 (WETH的出現其中一項就是為了方便驗證)。 == 又想到一個,舊版合約的Snapshot也可以用這個做 可以讓使用者憑舊合約上指定區塊號時的資產持有證明到新合約上兌換資產 這樣就不用在一開始一口氣複製一大堆狀態資料到新合約去

Ayukawayen08/14 21:23這是我想做放置型領獎遊戲碰到的需求,有空要把它接到

Ayukawayen08/14 21:29(然而對ETH來說放置遊戲的市場甚至難以稱為使用時機XD

※ 編輯: Ayukawayen (36.227.238.186 臺灣), 08/14/2020 22:13:06

ECZEMA08/14 22:22感謝解說 對查金流很有用

troylee08/15 00:140xE5AB5A463c1d9147C49cB09C9f37FA0E21dE433B 來試試看

https://ropsten.etherscan.io/tx/

0xe2f458e892e14cf9226448bcf3cb326692c7d2eb3d2bf8ecbab23b881b27bfc1

※ 編輯: Ayukawayen (36.227.238.186 臺灣), 08/15/2020 00:20:49

troylee08/15 00:23收到了

lolo085608/15 01:30好玩!!

Ayukawayen08/17 18:01用etherscan介面把MMR上架了才發現uniswap網頁只要把

Ayukawayen08/17 18:02metamask切到測試鏈就能接到測試鏈上的uniswap環境 XD

Ayukawayen08/17 18:10總之現在Ropsten的uniswap上也有MMR/ETH交易對了

ECZEMA08/17 20:45強! 鎖定 NMR!

Ayukawayen08/18 17:00https://i.imgur.com/76xpcXe.png 剛好32768 紀念一下

※ 編輯: Ayukawayen (140.113.136.221 臺灣), 08/18/2020 17:10:12

Ayukawayen08/24 23:31啊 中斷了 20分內出了330塊 超過256塊接不起來