이번시간에는 delegatecall에 대해서 배워봅시다.
delegate란 "위임하다" 라는 뜻을 가지고있습니다.
여기서는 함수를 위임받다 라는 정도만 이해하시고가면 될 것 같습니다.
delegatecall 특징
1. msg.sender가 스마트컨트랙트 사용자를 가르킨다.
2. 외부 컨트랙트의 함수를 마치 자기 것 처럼 사용한다. << 위임
3. 외부 스마트컨트랙트와 "똑같은" 변수를 가지고있어야함.
delegatecall 특징은 이렇게 세 가지를 가지고있는데
바로 코드를 통해서 이해해 봅시다.
contract A {
uint256 public num = 0;
event INFO(address _add, uint256 _num);
function plusNum() public {
num = num + 1;
emit INFO(msg.sender,num);
}
}
contract B {
uint256 public num = 0;
function delegateCall(address _contractADD) public payable {
(bool success,) = _contractADD.delegatecall(abi.encodeWithSignature("plusNum()"));
require(success,"Failed");
}
}
자 delegatecall 특징 첫번째부터 보시죠.
1. msg.sender가 스마트컨트랙트 사용자를 가르킨다.
msg.sender는 원래 그 함수를 호출한 사람의 주소가 나와야합니다.
즉 contractB에서 contractA를 호출하면 contract B의 주소가 나와야합니다.
하지만 delegatecall을 사용한다면 msg.sender는 사용자를 가르킵니다.
바로 배포를 하고 확인해봅시다.
(배포 후)
사용자의 주소
contract A,B의 주소
즉 원래같았으면 B에서 A의 함수를 호출하니 msg.sender는 B의 주소 0XB27... 이 나와야합니다
하지만 delegatecall을 했을때 msg.sender는 사용자의 주소가 나옵니다
사용자의 주소 0x5B3...이 나온 걸 확인할 수 있습니다.
2. 외부 컨트랙트의 함수를 마치 자기 것 처럼 사용한다. << 위임
contract A {
uint256 public num = 0;
event INFO(address _add, uint256 _num);
function plusNum() public {
num = num + 1;
emit INFO(msg.sender,num);
}
}
contract B {
uint256 public num = 0;
function delegateCall(address _contractADD) public payable {
(bool success,) = _contractADD.delegatecall(abi.encodeWithSignature("plusNum()"));
require(success,"Failed");
}
}
contractA의 plusNum 함수를 그대로 가져와 자기것처럼 사용합니다.
즉 여기서 제일 중요한건 plusNum을 통해 num이 증가된것은
contractA의 num이 아니라 contract B의 num입니다.
contactA의 num은 아직도 0 이고 contractB의 num이 1로 증가된 걸 볼 수있습니다.
3. 외부 스마트컨트랙트와 "똑같은" 변수를 가지고있어야함.
즉 contract A가 num이라는 변수를 가지고있으면 contractB도 " 똑같은 " 변수를 가지고 있어야합니다.
이렇게 오늘은 delegatecall에 대해서 알아봤습니다 감사합니다.
Better than Yestday
-김태양-
'Solidity' 카테고리의 다른 글
call 함수란? (3) | 2023.10.24 |
---|---|
Fallback 과 receive함수란? (1) | 2023.10.24 |
balance 와 msg.sender란? (3) | 2023.10.23 |
이더를 보내는 함수(send,transfer) feat. (payable,msg.value) (2) | 2023.10.22 |
Modifier란? (3) | 2023.10.22 |