ethernaut题解
ethernaut是以太坊的一种官方CTF(capture the flag,中文叫做夺旗赛)平台,旨在让人们学习以太坊的智能合约编写与安全。本文将对该平台的相关题目进行分析与解答。
1.密码学难题
密码学难题是ethernaut的第一题,主要介绍了密码学中常见的凯撒密码。凯撒密码是一种古代的加密方式,将明文的每个字母按照一个偏移量进行移位。例如,偏移量为3,则将字母A替换成D,字母B替换成E,以此类推。
题目要求我们到一个字段,可以将其解密后得到一个密码,用于通过验证。我们需要先到被加密的密码字符,再根据凯撒密码算法进行解密。实现代码如下:
```
pragma solidity ^0.4.18;
contract Caesar {
function decode(string _input) public pure returns (bytes32) {
bytes memory input = bytes(_input);
for (uint i=0; i<input.length; i++) {
input[i] = byte(uint8(input[i]) - 3);
}
return keccak256(input);
}
}
```
以上代码中,我们使用了solidity语言中的keccak256哈希函数,将解密后的字符转换为一个32字节的哈希值,用作验证。我们通过在线解密网站进行凯撒密码解密后,得到密码为flynn
lives。
2.认证难题
认证难题是ethernaut的第二题,主要介绍了合约授权与认证的基本知识。题目要求我们修改合约中的函数,使得只有指定的账户能够进行调用,否则会提示“Access Denied”。
实现方法可以在函数内部添加require验证,如下所示:
```
pragma solidity ^0.4.18;
contract AccessControl {
address public owner;
function AccessControl() public {
owner = msg.sender;
}
function authenticate() public constant returns (bool) {
if (msg.sender == owner) {
return true;
}
return false;
solidity}
function allowAccess(address addr) public {
require(authenticate());
// your code here
}
}
```
我们可以在allowAccess函数中添加require(authenticate()),确保只有合约所有者可以调用该函数进行操作。添加后的合约代码如上所示。通过此题后,我们成功学习了以太坊合约的授权认证基础知识。
3.钱包难题
钱包难题是ethernaut的第三题,主要考察solidity语言合约中账户余额查询与转账的基本知识。题目中要求我们在合约中实现一个简单的钱包,并支持两种操作:查询账户余额和转账。转账需要同时进行以下三项验证:
1)目标账户不能为空。
2)转账金额不能为零。
3)发送者余额必须大于等于转账金额。
以下是我们实现的合约代码:
```
pragma solidity ^0.4.18;
contract Wallet {
mapping (address => uint256) public balanceOf;
function deposit() public payable {
balanceOf[msg.sender] += msg.value;
}
function transfer(address _to, uint256 _value) public {
require(_to != address(0));
require(_value > 0);
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论