「The Ethernaut by Zeppelin Level 16. Preservation」を翻訳してみました
原文はこちら
https://ethernaut.zeppelin.solutions
16. Preservationをクリック
16. Preservation
難易度 8/6
このコントラクトは、2つの異なるタイムゾーンの2つの異なる時間を格納するためにライブラリを利用しているぞ。
コンストラクタは、保存する時間ごとにライブラリの2つのインスタンスをしているぞ。
このレベルのクリア条件はインスタンス(コントラクト)のオーナーを自分自身のアドレスに変更することだ。
回答の助けになるヒント
- デリゲートコールにおける低レベル関数がどのように動作するか、デリゲートする為にはどのように使用するか、Solidityのドキュメントを参照せよ。
- delegatecallがコンテキストを保持する(context-preserving)とは?の理解
- ストレージ変数の格納方法とアクセス方法の理解
- さまざまなデータタイプ間でのキャストの仕組みの理解
ソースコード
pragma solidity ^0.4.23;
contract Preservation {
// public library contracts
address public timeZone1Library;
address public timeZone2Library;
address public owner;
uint storedTime;
// Sets the function signature for delegatecall
bytes4 constant setTimeSignature = bytes4(keccak256("setTime(uint256)"));
constructor(address _timeZone1LibraryAddress, address _timeZone2LibraryAddress) public {
timeZone1Library = _timeZone1LibraryAddress;
timeZone2Library = _timeZone2LibraryAddress;
owner = msg.sender;
}
// set the time for timezone 1
function setFirstTime(uint _timeStamp) public {
timeZone1Library.delegatecall(setTimeSignature, _timeStamp);
}
// set the time for timezone 2
function setSecondTime(uint _timeStamp) public {
timeZone2Library.delegatecall(setTimeSignature, _timeStamp);
}
}
// Simple library contract to set the time
contract LibraryContract {
// stores a timestamp
uint storedTime;
function setTime(uint _time) public {
storedTime = _time;
}
}