Ethernaut 「Level.1 Fallback」解答例
Fallback
下記のコントラクトコードを見てください。
このレベルをクリアするには、
1.このコントラクトのownershipを自分にする
2.コントラクトの残高を0にする
回答に助けになるヒント
・ABIとやり取りする時にEtherを送る方法
・ABIの外部にEtherを送る方法
・wei/etherとの変換
・Fallbackメソッド
Sources
pragma solidity ^0.4.18;
import 'zeppelin-solidity/contracts/ownership/Ownable.sol';
contract Fallback is Ownable {
mapping(address => uint) public contributions;
function Fallback() public {
contributions[msg.sender] = 1000 * (1 ether);
}
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(this.balance);
}
function() payable public {
require(msg.value > 0 && contributions[msg.sender] > 0);
owner = msg.sender;
}
}
解答
クリアする条件と出されたヒントから注目する。
contract sourcesからは、ownershipを変更する「owner = msg.sender」
payableを動かすには、contractにEtherを送信する
msg.value
は、送信されたEtherの値
msg.sender
は、コントラクトを実行したPlayerのアドレス(つまり自分)
となり、msg.sender
のアドレスをowner
に入れればownershipが取れることになります
ownershipが取れてしまえば、withdraw
メソッドにコントラクトのBalanceを全て自分に転送するとあるので実行できればこのレベルはクリアしたことになります。
まずはFallbackメソッドにある下記の条件をクリアする為、contitribute[msg.sender]
を0ではなくしてしまいましょう。
require(msg.value > 0 && contributions[msg.sender] > 0);
contributeメソッドにcontribute[msg.sender]
に送ったEtherの値を加算するコードがありますが、条件として0.001 Ether
未満というものがあります。
0ではなくすれば良い為、0.0001 Ether
を送るようにしてみます。
contract.contribute({value: toWei(0.0001,"ether"), from: player})
Etherを送る場合Valueの値はWei換算の為、EtherをWeiに変換するコードを記入しています。
このコードを実行することでcontribute
に0.0001 Ether
送ることができます。
次のコマンドで自分のcontributions
の値を確認してみましょう
await contract.getContribution()
t {s: 1, e: 14, c: Array(1)}
c:[1]
e:14
s:1
__proto__:Object
自分のcontributions
が0ではなくなれば、contractのsendTransactionを使い0.0001のEtherを送り(0以上ならOK)、Ownerを取得します。
メソッド名のないFallbackメソッドの場合は、sendTransactionを使います。
contract.sendTransaction({ from: player, to: instance, value: toWei(0.0001, "ether")})
ownershipが取得できたかコントラクトのオーナーを確認します。
await contract.owner()
"(自分のアドレス)"
Ownerを取得した後は、contractの残高を取得するwithdraw()
メソッドを実行します。
contract.withdraw()
以上で「Level.1 Fallback」をクリアできます。
解答に導く順序についてはこれが正しいというわけではないのですが、クリア条件を満たすことはできると思います。
コントラクトのメソッドに直接Etherを送る方法については色々と調べさせていただきました。
Author And Source
この問題について(Ethernaut 「Level.1 Fallback」解答例), 我々は、より多くの情報をここで見つけました https://qiita.com/minato774/items/93747d8f9623d1ba3d69著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .