Ethernaut 1


level 1 Fallback

fallback関数は、関数を呼び出さずにcontractにトランザクションを送信するときに実行される名前のない関数です.receive関数はfallback関数、msgです.データ値が空の場合は、処理を行います.すなわち,他の要求がない場合にイーサを送信する際に役立つ関数である.
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import '@openzeppelin/contracts/math/SafeMath.sol';

contract Fallback {

  using SafeMath for uint256;
  mapping(address => uint) public contributions;
  address payable public owner;

  constructor() public {
    owner = msg.sender;
    contributions[msg.sender] = 1000 * (1 ether);
  }

  modifier onlyOwner {
        require(
            msg.sender == owner,
            "caller is not the owner"
        );
        _;
    }

  function contribute() public payable {
    require(msg.value < 0.001 ether);
    contributions[msg.sender] += msg.value;
    if(contributions[msg.sender] > contributions[owner]) {
      owner = msg.sender;
    }
  }

  function getContribution() public view returns (uint) {
    return contributions[msg.sender];
  }

  function withdraw() public onlyOwner {
    owner.transfer(address(this).balance);
  }

  receive() external payable {
    require(msg.value > 0 && contributions[msg.sender] > 0);
    owner = msg.sender;
  }
}
上の契約書はお金を送って、残高の中の値が所有者より大きいと、ownerの位置を奪います.しかし、送信するたびに0.001 ether未満になるので、通常の方法では難しいです.上記のreceive関数を使用して、所有者の位置を優先する必要があります.

実際、最初の問題は、コードを読み取り、コンソールでトランザクションを送信することです.ただし、トランザクションの送信時に純粋なテキストを入力すると、面倒になります(関数名ハッシュ値をデータに追加する必要があります).
await contract.contribute.sendTransactionはこのように使うといいです

また、toWei関数に値を書く場合、string形式で入れないとエラーが発生します.

値段はちょっと特別ですが、原因は分かりません.ハハハ

推測によると、マイクロ単位で入るのは、16進数(計算するとそうではないようです)

とにかく、今お金を送ります.

この契約は今私のです.
p.s小銭でもATMでお金を引き出すことができます