[闲聊] 在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