该怎么猜智能合约上的随机数?
该怎么猜智能合约上的随机数?
在链上创建随机数是一项复杂的任务。事实上,有一些方法可以做到这一点,但总的来说,强烈建议在链下进行,因为几乎所有用于熵的输入都是公开的,或者在某种程度上可以被操纵。
幸运的是,这个挑战要求我们猜测链上创建的一个“随机”数字。这是怎么回事?
猜随机数字挑战智能合约代码
合约的第一行是一个uint8变量,answer。记住uint8变量最多包含256个可能的整数:0到255。
这个变量在构造函数中被分配给两个输入的 keccak256 哈希:包含我们部署交易的那个区块的前一个区块的blockhash (block.blockhash(block.number - 1)
, of type bytes32)和我们的区块被挖的时间戳*(now
, of type uint256)*。
请记住,这个合约使用的是编译器版本^0.4.21,从那以后,一些语法发生了变化:block.blockhash()现在是blockhash(),now现在是block.timestamp。
正如我们在这行中看到的,keccak256函数(一个 bytes32 固定大小的字节数组)随后被显式转换为uint8并赋值给我们的变量。
这看起来很随机,对吧?我们应该如何猜出0到255之间的一个数字,它来自于对某个区块的哈希函数和时间戳,
其实很简单。因为区块链上的所有东西都是公开的。
我们的目标是在函数下guess
,我们必须调用它并发送一个uint8 + 1 以太(我们已经在部署上发送了一个),然后如果我们的uint8等于answer变量,合约将发送我们2个以太,耗尽余额,因此isComplete()函数将返回到 true。
有多种与合约交互的方式,但我决定通过另一个合约来实现。这不是最简单的方法,在这种情况下,甚至没有必要,但绝对是我们可以利用的方法。
以下是我为解决这个问题所编写的代码:
// SPDX-License-Identifier: No License
pragma solidity ^0.8.0;interface IGuessTheRandomNumberChallenge {function guess(uint8) external payable;
}contract GuessTheRandomNumberSolver { IGuessTheRandomNumberChallenge public _interface;bytes32 public previousBlockHash = 0x66bcdb5e320c9e0c04a9fdeaa15de33a4c8a040db342f4f955fa54f170dba9ce;uint public previousTimestamp = 1641520092; constructor(address _interfaceAddress) {require(_interfaceAddress != address(0), "Address can not be Zero");_interface = IGuessTheRandomNumberChallenge(_interfaceAddress);} function solve() public payable {uint8 answer = uint8(uint256(keccak256(abi.encodePacked(previousBlockHash, previousTimestamp))));_interface.guess{value: 1 ether}(answer);} function getBalance() public view returns(uint){return address(this).balance;} function withdraw() public {payable(msg.sender).transfer(address(this).balance);} receive() external payable {}
}
编译器版本之后,首先看到的是一个接口。我们可以使用它们通过代码与其他合约交互。它基本上是一个带有一些规则的简单合约:
- 它们不能从其他合约继承,但可以从其他接口继承。
- 所有声明的函数必须是外部的。
- 它们不能声明构造函数。
- 它们不能声明状态变量。
- 它们不能声明修饰符。
因为我们只需要调用’ guess '函数,所以它是我们在接口中声明的唯一一个函数。
然后,在我们的GuessTheRandomNumberSolver合约中,我们将声明一个_interface变量,并通过构造函数分配挑战的地址(在CTE中部署它时获得的的地址)。
这就是我们现在在已部署的挑战中调用函数所需要的一切,我们继续收集信息,以重新创建与它一起部署的random number。
这些都可以在etherscan中找到,我们只需要寻找我们挑战的地址。
Blockhash(block.number - 1):要得到这个,可以转到内部Internal Txns标签,然后单击显示Contract Creation的同一行上的区块号码。在我的例子中,区块是#11766860:
现在,我们可以看到很多关于那个区块的信息,但我们需要访问前一个,所以继续寻找它。在我的例子中,它是#11766859。
下面我们可以看到hash。这是我们需要的第一个信息。
Block.timestamp:回到我们的区块,你会在第二行看到时间戳。这是一种人类可读的格式,我们需要Unix Timestamp格式。那是什么? 它是自1970年1月1日以来所经过的秒数。这是衡量时间的标准方法。
为了将这个人类可读的时间戳转换为Unix时间,我使用了一个非常方便的站点epochconverter。有了这个数字,我们终于有了最后一块拼图,我们可以来解决这个挑战。
回到GuessTheRandomNumberSolver合约,让我们创建一个solve函数,我们将调用它来联系我们的挑战合约。
为了提高可读性,我还创建了两个新变量:
bytes32 public previousBlockHash
uint public previousTimestamp.
创建它们,但要赋予它们挑战的价值。
然后,在我们的solve函数中,我们将创建uint8 answer变量,并将其赋值:
uint8(uint256(keccak256(abi.encodePacked(previousBlockHash, previousTimestamp))))
语法和格式的变化是因为我们使用的是0.8.0版本的编译器,而挑战是使用0.4.21版本。
现在我们已经将答案赋给了变量,我们只需要通过接口调用挑战。这就是下一行要做的:
_interface.guess{value: 1 ether}(answer)
我假设你正在使用remix,所以继续,通过Injected Web3环境连接到metamask钱包,并部署合约,指定自己的挑战地址来分配给自己的界面。
现在,在将值输入为1的情况下,继续调用guess函数。
我已经添加了更多的函数:
getBalance()
withdraw()
receive()
这是因为挑战是msg.sender将是我们的GuessTheRandomNumberSolver合约,而不是我们的EOA -所以我们需要接收2个以太,并能够将它们发送到我们的EOA。
Source:https://betterprogramming.pub/capture-the-ether-guess-the-random-number-2ebb8c9c0347
关于
ChinaDeFi - ChinaDeFi.com 是一个研究驱动的DeFi创新组织,同时我们也是区块链开发团队。每天从全球超过500个优质信息源的近900篇内容中,寻找思考更具深度、梳理更为系统的内容,以最快的速度同步到中国市场提供决策辅助材料。
Layer 2道友 - 欢迎对Layer 2感兴趣的区块链技术爱好者、研究分析人与Gavin(微信: chinadefi)联系,共同探讨Layer 2带来的落地机遇。敬请关注我们的微信公众号 “去中心化金融社区”。
该怎么猜智能合约上的随机数?相关推荐
- 跟着cryptokitties(以太坊云养猫)学写智能合约(上)
cryptokitties(以太坊云养猫)是近期出现在以太坊区块链上一个游戏.超级可爱的猫形象,再配合上繁殖,配种,拍卖这样丰富的玩法,一下子就引爆了以太坊的区块链.这款游戏的核心是基于以太坊的智能合 ...
- 众说区块链:智能合约在建材链上的落地实践
上期<众说区块链>讨论的主题是"数字货币交易所",围绕这个的相关主题,大家对这方面的相关话题展开了进一步的谈论. 本期<众说区块链>讨论的主题是" ...
- ChatGpt4刚刚被证实,已能实时检查以太坊链上智能合约漏洞
check GPT four刚刚被证实 已经能够 实时的检测 仪态房链上的智能合约的漏洞 今年2023年最火的AI项目check GPT 昨天已经学习到进化到4.0的版本 3.0-3.5的进步还只是文 ...
- vrf名称_如何使用VRF(可验证随机函数)在以太坊上生成随机数
Chainlink 如何解决以太坊"随机数问题" 随机数和区块链一直很难达到"一致"(译者注:区块链要求确定性,而随机数正相反).到目前为止,区块链上还没有可验 ...
- 以太坊智能合约安全 Dasp Top10
译者:爱上平顶⼭ 来源:慢雾区 原文链接:https://www.dasp.co/ 这是分布式应⽤安全项⽬(或DASP)2018 年排名前10的漏洞第⼀次迭代 该项⽬是NCC集团的⼀项举措.这是⼀个开 ...
- 智能合约如何可信的与外部世界交互
区块链应用中,外部世界如何与智能合约交互往往是一个容易被忽视的问题,很多的智能合约应用场景是根据一些外部事件,输出相应的结果,而传统的IT数据交互方式实际上并不能投入真正的工作.例如,按照农产品价格情 ...
- java 以太坊 智能合约_web3j教程:java使用web3j开发以太坊智能合约交易
从广义上讲,有web3j支持三种类型的以太坊交易: 1.以太币从一方交易到另一方 2.创建一个智能合约 3.与智能合约交易 为了进行这些交易,必须有以太币(以太坊区块链的代币)存在于交易发生的以太坊账 ...
- 区块链智能合约Coursera(第一周)智能合约基础
课程链接 https://www.coursera.org/learn/smarter-contracts/home/week/1 这是区块链专项课程的第二门课 智能合约 Smart Contract ...
- PeckShield CEO 蒋旭宪:智能合约安全问题不可怕,预防和响应机制才是关键
2018年6月3日,由中国IT技术社区CSDN和专注以太坊生态建设的领先企业灵钛科技主办,以太坊爱好者社区.柏链道捷.火星财经.金色财经.Unitimes.区块链大本营协办的「2018以太坊技术及应用 ...
最新文章
- 2018/8/26 PSO-based Clustering Techniques to Solve Multimodal Optimization Problems: A Survey
- mysql的主从复制原理
- UPS电池延时估算方法及配置表,ups配置不再难
- AV1挑起的Codec之战
- 项目入口_新进展!石家庄地铁项目长安公园站出入口全部封顶
- 设计师妹子问:字体颜色渐变,你能实现?
- spring 计划任务
- python连接池框架_Python中的连接池是非常重要的!神级程序员详解!
- 【基础】优化背后的数学基础
- 这几道Redis面试题都不懂,怎么拿到阿里后端offer?
- JAVA8——StringJoiner类
- 1011. A+B和C (15)
- mysql基于SpringBoot的“1818小酒馆”商城网站的设计与实现毕业设计源码192004
- 1、前端背景图自适应
- linux 文件管理系统
- JMETER-清除cookies
- Git _ 报错信息
- acwing 95. 费解的开关(蓝桥杯)
- 国药集团获得美国默沙东公司新冠口服药“莫诺拉韦”经销权和独家进口权 | 美通社头条...
- 基于移动位置服务器,基于移动位置的服务系统及方法