作者Ayukawayen (鮎川彦)
看板DigiCurrency
标题[闲聊] 在ETH智能合约内验证过去区块的Hash值
时间Fri Aug 14 17:39:35 2020
在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.cc), 来自: 140.114.123.85 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/DigiCurrency/M.1597397983.A.13F.html
1F:推 DarkerDuck: 先推,待会贴地址 08/14 18:20
2F:推 leftc: 推,试玩了一下收到12万MMR,when coinbase? (误 08/14 20:39
一个小秘密是推文可以拿12000个Token,但随便往合约丢个Tx就可以拿十几万Token了XD
3F:推 ECZEMA: 推 回溯验长链老区块的工具 这个使用时机和应用有哪些呢? 08/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也可以用这个做
可以让使用者凭旧合约上指定区块号时的资产持有证明到新合约上兑换资产
这样就不用在一开始一口气复制一大堆状态资料到新合约去
4F:→ Ayukawayen: 这是我想做放置型领奖游戏碰到的需求,有空要把它接到 08/14 21:23
6F:→ Ayukawayen: (然而对ETH来说放置游戏的市场甚至难以称为使用时机XD 08/14 21:29
※ 编辑: Ayukawayen (36.227.238.186 台湾), 08/14/2020 22:13:06
7F:推 ECZEMA: 感谢解说 对查金流很有用 08/14 22:22
8F:推 troylee: 0xE5AB5A463c1d9147C49cB09C9f37FA0E21dE433B 来试试看 08/15 00:14
https://ropsten.etherscan.io/tx/
0xe2f458e892e14cf9226448bcf3cb326692c7d2eb3d2bf8ecbab23b881b27bfc1
※ 编辑: Ayukawayen (36.227.238.186 台湾), 08/15/2020 00:20:49
9F:推 troylee: 收到了 08/15 00:23
10F:推 lolo0856: 好玩!! 08/15 01:30
11F:→ Ayukawayen: 用etherscan介面把MMR上架了才发现uniswap网页只要把 08/17 18:01
12F:→ Ayukawayen: metamask切到测试链就能接到测试链上的uniswap环境 XD 08/17 18:02
13F:→ Ayukawayen: 总之现在Ropsten的uniswap上也有MMR/ETH交易对了 08/17 18:10
14F:推 ECZEMA: 强! 锁定 NMR! 08/17 20:45
※ 编辑: Ayukawayen (140.113.136.221 台湾), 08/18/2020 17:10:12
16F:→ Ayukawayen: 啊 中断了 20分内出了330块 超过256块接不起来 08/24 23:31