ABI (Application Binary Interface) 定義函式的介面,包含輸入輸出、函式讀寫狀態等,可以幫助開發者了解怎麼跟這支合約互動。 詳細欄位說明可以參考:ABI-function-fields.md
題目要求先從 contract.info() 開始,呼叫後發現會給你下一個要呼叫的提示,一路跟著提示呼叫 function 就可以過關了。這裡不贅述,附上解題的過程(Chrome Develope Tools):
› await contract.info()
‹ 'You will find what you need in infol().'
› await contract.info1()
‹ 'Try info2(), but with "hello" as a parameter.'
› await contract.info2("hello")
« 'The property infoNum holds the number of the next info method to call.'
› await contract.infoNum()
‹ {negative:0,words:[42],length:1,red:null}
› await contract.info42()
« 'theMethodName is the name of the next method.'
› await contract.theMethodName()
« 'The method name is method7123949.'
› await contract.method7123949()
‹ 'If you know the password, submit it to authenticate().'
› await contract.password()
« 'ethernauto'
› await contract.authenticate('ethernauto')
提交之後,等待一下就會通知過關了。成功後會秀出這支合約的原始碼。
題目合約
// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;contractInstance{
stringpublic password;
uint8public infoNum =42;
stringpublic theMethodName ="The method name is method7123949.";
boolprivate cleared =false;
// constructorconstructor(stringmemory _password) {
password = _password;
}
functioninfo() publicpurereturns (stringmemory) {
return"You will find what you need in info1().";
}
functioninfo1() publicpurereturns (stringmemory) {
return'Try info2(), but with "hello" as a parameter.';
}
functioninfo2(stringmemory param) publicpurereturns (stringmemory) {
if (keccak256(abi.encodePacked(param)) ==keccak256(abi.encodePacked("hello"))) {
return"The property infoNum holds the number of the next info method to call.";
}
return"Wrong parameter.";
}
functioninfo42() publicpurereturns (stringmemory) {
return"theMethodName is the name of the next method.";
}
functionmethod7123949() publicpurereturns (stringmemory) {
return"If you know the password, submit it to authenticate().";
}
functionauthenticate(stringmemory passkey) public{
if (keccak256(abi.encodePacked(passkey)) ==keccak256(abi.encodePacked(password))) {
cleared =true;
}
}
functiongetCleared() publicviewreturns (bool) {
return cleared;
}
}
review 一下題目合約,在第 5 行可以發現 password 一開始並未被賦值,直到合約被實例化的時候才會由創建者輸入(11-13 行) 38-42 行判斷我們最後提交的密碼是否正確,其他解題時呼叫的 function 也都可以在程式碼中找到。這裡還有一個觀念,Solidity 的變數在宣告時若是屬於 public 的狀態,會自動生成一個 getter function,讓任何人都可以透過這個 function 取得該變數的值,這也是為什麼在原始碼中看不到 password() 這個 function 但是 ABI 中會有的關係。關於 Solidity 的變數讀取狀態可以參考這篇:[EN] Learn Solidity lesson 2. Public variables.