Ethernaut的工作原理
所有智慧合約原始碼由以太坊虛擬機器(EVM)編譯為兩種格式:
應用程式二進位制介面(ABI):jSON格式的solidity和Javascript之間的通訊層;
位元組碼(Bytecode):由EVM執行的低階機器語言。
當您請求為每個級別get a new instance時,Ethernaut將編譯後的位元組碼部署到Ropsten測試網路上的一個新地址:
一旦在區塊鏈上建立了這個新例項,它的地址將透過一個事件返回到您的Web客戶端,如遊戲的主合同ethernaut.sol所示:
eventLevelInstanceCreatedLog(address indexed player, address instance);
eventLevelCompletedLog(address indexed player, Level level);
function createLevelInstance(Level _level) public payable {
// Ensure level is registered.
require(registeredLevels[_level]);
// Get level factory to create an instance.
address instance = _level.createInstance.value(msg.value)
(msg.sender);
// Store emitted instance relationship with player and level.
emittedInstances[instance] = EmittedInstanceData(msg.sender,
_level, false);
// Retrieve created instance via logs.
LevelInstanceCreatedLog(msg.sender, instance);
}
最後,Web3圍繞這個新的智慧合約例項包裝了一個ABI,並允許您透過Web控制檯與合同進行互動。
請注意,所有“public”函式在Web客戶端中都可用
細節演練
此級別要求您猜測密碼,以便“get clear”後繼續。
1、請注意,Ethernaut在建立合同例項時將_password傳遞給建構函式:
function Instance(string _password)public{
password = _password;
}
2、此密碼儲存為public string變數
stringpublic password;
3、solidity中所有公共的基本變數型別都有一個自動生成的getter函式。這意味著您可以透過在控制檯中鍵入以下內容直接讀取這個不太機密的密碼:
await contract.password()
您可以更輕鬆地使用Async/Wait來處理Web3承諾
4.要透過此級別,只需呼叫最終的authenticate 函式並透過控制檯傳入檢索到的密碼:
await contract.authenticate("[password here]");
您將修改authenticate函式中的儲存,因此在呼叫此事務時需要支付一些gas費用。
5、最後,您應該能夠再次檢查是否透過了此級別:
await contract.getCleared();
關鍵安全要點
儲存在區塊鏈上的所有函式和變數都可供公開檢視。
永遠不要將密碼直接儲存在智慧合約中。