8. Vault
Chain: Goerli
Difficulty: ●●○○○
Level: https://ethernaut.openzeppelin.com/level/0x78BA1a1DD8833A4a20ecAc0Db8f3aCD8A9211beD
要求
打开 vault 来通过这一关!
分析
1 | // SPDX-License-Identifier: MIT |
分析下合约代码,就是要获取合约的password值。虽然 password 是一个 private,不能直接调用合约取值,但我们可以通过 Web3的getStorageAt 函数可以取得指定地址特定位置的storage。
web3.eth.**getStorageAt**(address, position [, defaultBlock] [, callback])
Get the storage at a specific position of an address.
Parameters
String
- The address to get the storage from.Number|String|BN|BigNumber
- The index position of the storage.Number|String|BN|BigNumber
- (optional) If you pass this parameter it will not use the default block set with web3.eth.defaultBlock. Pre-defined block numbers as"earliest"
,"latest"
,"pending"
,"safe"
or"finalized"
can also be used.Function
- (optional) Optional callback, returns an error object as first parameter and the result as second.
Returns
Promise
returns String
- The value in storage at the given position.
解题
打开 Console 执行以下命令:
1
await web3.eth.getStorageAt(instance, 1)
得到结果:
0x412076657279207374726f6e67207365637265742070617373776f7264203a29
将该结果转换成字符串:
await web3.utils.toAscii("0x412076657279207374726f6e67207365637265742070617373776f7264203a29")
,可以得到:A very strong secret password :)
调用合约代码:
1
await contract.unlock("0x412076657279207374726f6e67207365637265742070617373776f7264203a29")
提交实例,完成关卡。
后记
请记住, 将一个变量设制成私有, 只能保证不让别的合约访问他. 设制成私有的状态变量和本地变量, 依旧可以被公开访问.
为了确保数据私有, 需要在上链前加密. 在这种情况下, 密钥绝对不要公开, 否则会被任何想知道的人获得. zk-SNARKs 提供了一个可以判断某个人是否有某个秘密参数的方法,但是不必透露这个参数.