Nivel 2: Fallout
Este es el nivel 2 del juego Ethernaut.
Requisitos previos:
- Solidity smart contract constructors
Atajos
contrato dado:
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import 'openzeppelin-contracts-06/math/SafeMath.sol';
contract Fallout {
using SafeMath for uint256;
mapping (address => uint) allocations;
address payable public owner;
/* constructor */
function Fal1out() public payable {
owner = msg.sender;
allocations[owner] = msg.value;
}
modifier onlyOwner {
require(
msg.sender == owner,
"caller is not the owner"
);
_;
}
function allocate() public payable {
allocations[msg.sender] = allocations[msg.sender].add(msg.value);
}
function sendAllocation(address payable allocator) public {
require(allocations[allocator] > 0);
allocator.transfer(allocations[allocator]);
}
function collectAllocations() public onlyOwner {
msg.sender.transfer(address(this).balance);
}
function allocatorBalance(address allocator) public view returns (uint) {
return allocations[allocator];
}
}
El player
tiene que reclamar la propiedad del contrato.
Al inspeccionar todos los métodos, se puede ver que no hay ningún método que cambie la propiedad del contrato. Solo la lógica de propiedad está dentro del constructor. ¡Pero los constructores se llaman solo una vez en el momento de la implementación!
Algo sobre la declaración del constructor parece inusual: "parece" estar definido con el mismo nombre que el contrato, es decir Fallout
(en realidad NO lo está). ¿No usamos constructor
palabras clave para declarar constructores?
En primer lugar, la declaración de constructor prevista tiene un error tipográfico, Fal1out
en lugar de Fallout
. Por lo tanto, solo se trata como un método normal, no como un constructor. Por lo tanto, simplemente lo llamamos y reclamamos la propiedad.
En segundo lugar, incluso si no fue un error tipográfico, es decir, el constructor se declaró como Fallout
, ¡ni siquiera se compilará!
Las versiones anteriores de Solidity tenían este tipo de declaración de constructor. Si revisa los documentos, encontrará que la palabra clave constructor
es obligatorio incluso en v0.5.0
- _ "Los constructores ahora deben definirse usando la palabra clave constructor"_ . Y usos del contrato objetivo v0.6.0
.
await contract.Fal1out()
Y player
se ha hecho cargo como owner
. Verificar por:
await contract.owner() === player
// Output: true
Enviar instancia. Hecho.
Top comments (0)