本系列题目出自推特博主@the_ethernaut系列推特。
本人是在准备面试过程中,总结一些有意思的题目。
本文永久链接:https://learnblockchain.cn/article/3845
- How would you call a function on a third party contract B, on behalf of the sender, through your contract A, guaranteeing no reverts?
题目意思就是如何通过合约A代表发送者调用合约B的函数,答案很简单咯,就是delegatecall。
contract B{
uint value;
function test(){
value = 10;
}
}
contract A{
function _delegate(address _B){
(bool suc,) = _B.delegatecall(abi.encodeWithSignature("test"));
require(suc, "delegate call failed");
}
}
- What’s the main difference between a transparent proxy and a universal proxy?
题目意思是透明合约和代理合约的主要区别是啥?社区里这篇文章很详细的介绍了这俩代理模式的。可以瞅一瞅。
contract TransparentProxy{
uint public value;
address public implementation;
address public owner;
constructor(address _v1){
implementation = _v1;
owner = msg.sender;
}
modifier onlyOwner(){
require(msg.sender == owner, "only owner");
_;
}
function _upgrade(address _newImplementation) public onlyOwner{
implementation = _newImplementation;
}
function _delegatecall() public {
(bool suc,) = implementation.delegatecall(msg.data);
require(suc, "delegatecall failed");
}
}
contract BoxV1{
uint public value;
function set(uint _value) public{
value = _value;
}
}
contract UniversalProxy{
uint public value;
address public implementation;
constructor(address _v1){
implementation = _v1;
}
function _delegatecall() public {
(bool suc,) = implementation.delegatecall(msg.data);
require(suc, "delegatecall failed");
}
}
abstract contract Box{
uint public value;
address public implementation;
address public owner ;
modifier onlyOwner(){
require(msg.sender == owner, "only owner");
_;
}
function _upgrade(address _newimplementation) public onlyOwner {
implementation = _newimplementation;
}
}
contract BoxV1 is Box{
function set(uint _value) public {
value = _value;
}
}
参考答案:
通用代理优势:通过在实现合约上定义所有函数,它可以依靠Solidity编译器检查任何函数选择器冲突。此外,通用代理的大小要小得多,从而使部署更便宜。在每次调用中,从存储中需要读取的内容更少,降低了开销。 通用代理劣势:如果一次合约忘记写upgrade函数,将会永远无法升级了。
- How could you destroy the implementation of, and effectively brick, a universal proxy? Assumptions:
- You re not the owner of the proxy
- No one owns the implementation
- The implementation uses delegatecall to guarantee that the next implementation is not sterile
题目大概意思是,你怎么能破坏通用代理的实现合约,并有效地将其变成砖头(废弃)?条件如下:
参考答案:因为implementation合约里有调用delegatecall,去调用别的合约,那只要在该合约中加一个selfdestruct函数,即可完成对通用代理的毁灭。所以在implementation合约里最好不要使用selfdestruct和delegatecall函数。详细可以查看这篇文档
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!