2023. 6. 4. 21:08ㆍBlockChain/Solidity 깨부수기 ( 유투브 강의 )
목차 |
1. Call |
2. DelegateCall |
1. Call
전에도 몇 번 예제 코드에 나온 call에 대해서 살펴보자.
call 메서드
1. 이더리움의 송금
2. 외부 스마트 컨트랙트의 호출
3. send, transfer와 다르게 가변적으로 가스를 소모
4. 3의 이유로, 이스탄불 하드포크 이후에 call의 사용을 권장
(※ 가스의 가격이 올랐으므로 2300 gas로는 발동 X)
5. re-entrancy(재진입) 공격위험으로 인해서 *특정 패턴*을 사용해야한다.
(*특정 패턴* : Checks_Effects_Interactions_pattern)
여기서 2번에 대해서 살펴보도록 하자.
이전의 예제 코드에서 (bool sent, ) = _to.call{ value : ... }(" "); 과 같은 문법으로 사용한 적이 있다.
이 때 ( bool sent, [ ] ) [ ]에 대해서 의문이 생길 수 있다.
왜 비워놓는 것인가?
답은 call이 반환하는 값이 두 가지이기 때문이다.
call은 외부 컨트랙트의 함수를 호출하는 기능을 가지고 있다.
그러기 위해서는 다음의 문법을 따라야한다.
// call 문법
// 송금을 할 경우
(bool [변수명], ) = [address 값].call{value: 보낼양}("");
// 외부 스마트 컨트랙트 함수 부르기
(bool [변수명], bytes memory [변수명]) = [address 값].call(abi.encodeWithSignature("[함수명(매개변수 명, ...)]", 매개변수 명, 매개변수 명,...));
송금은 이전에도 보았던 대로 간단한 모양이지만,
외부 스마트 컨트랙트를 호출하는 법은 다소 어려워 보인다.
외부 스마트 컨트랙트를 호출하려면 call의 호출부( )에 abi.encodeWithSignature를 통해서 실행할 함수의 내용을 전달해주어야한다.
( *abi(application binary interface)란, 대개 json 파일형식으로 정의되어있는 스마트 컨트랙트의 내용이다. )
[address 값]에는 주소 값이 들어가야하는데 EOA계정이 아닌 CA계정의 주소가 들어가야한다.
CA는 배포되어있는 컨트랙트의 주소이며, EOA와 다르게 CA는 정의된 함수를 가지고 있기 때문이다.
※ 함수를 호출하는 주체
call을 이용해서 다른 스마트 컨트랙트의 함수를 실행할 경우,
만약 함수에 msg.sender가 있다면 누구의 값이 들어갈것인가?
들어갈 수 있는 주소값은
- call함수를 호출한 사용자(클라이언트)의 EOA
- 함수를 호출하는 스마트 컨트랙트의 CA
- 호출할 함수의 컨트랙트를 배포한 CA
두 가지인데 답은 호출할 함수의 컨트랙트를 배포한 CA이다.
말로 보니 조금은 헷갈리니 그림으로 살펴보도록 하자.
이렇게 실행이 되기 때문에 이걸 이용해서 다양하게 코드를 작성할 수 있다.
스마트 컨트랙트에서 어떤 주소로 실행이 되던간에
외부 스마트 컨트랙트에서는 해당 컨트랙트의 CA이 값이 들어간다.
다음에 살펴볼 delegateCall의 경우 조금 다른 동작을 하게된다.
2. DelegateCall
이번에 살펴볼 것은 DelegatCall이다.
delegateCall은 외부 스마트 컨트랙트의 msg.sender에 본래의 스마트 컨트랙트를 가리키게한다.
delegateCall이 정의된 스마트 컨트랙트가 외부 컨트랙트의 함수들을 마치 자신의 것처럼 사용하게한다.
(단, 외부 스마트 컨트랙과 스마트 컨트랙트는 같은 변수를 가지고 있어야한다.)
call에 대한 결과값 또한 본래의 스마트 컨트랙트에 저장하게 된다.
이렇게 되면 생기는 이점이 있다.
예를들어 배포된 스마트 컨트랙트에 클라이언트들의 정보(포인트, 토큰수)를 가지고 있는 컨트랙트가 있고,
그 컨트랙트는 외부 컨트랙트의 코드를 실행하여 값을 가져온다고 했을 경우가 있다고 가정하자.
외부 스마트 컨트랙트의 로직을 변경해야하는 경우에는 다음의 문제가 발생한다.
정보를 담고 있는 컨트랙트는 외부 스마트 컨트랙트 이기 때문에 재배포가 필요한데 이렇게 되면 기존에 가지고 있던 클라이언트들의 정보가 모두 사라진다.( 한번 배포된 컨트랙트는 바꿀 수 없기 떄문)
delegateCall을 사용하면 정보를 스마트 컨트랙트에 저장이 되기 때문에 로직을 바꾼 외부 스마트 컨트랙트를 실행해주면 간단히 해결이 된다.
스마트 컨트랙트에서 새로운 외부 스마트 컨트랙트의 주소를 받아서 저장하는 변수를 만들어주면 된다.
call을 할 경우 저장된 변수의 값으로 call을 보내기 때문에 간단히 로직을 변경할 수 있다.
외부 CA를 0x0002에서 0x0003으로 바꿔주면 간단히 연결을 끊고 새롭게 로직을 변경하는 패턴이 된다.
'BlockChain > Solidity 깨부수기 ( 유투브 강의 )' 카테고리의 다른 글
Solidity 문법 - (26) enum (0) | 2023.06.04 |
---|---|
Solidity 문법 - (24) fallback (0) | 2023.06.04 |
Solidity 문법 - (23) msg.balance (사용자 잔액) (0) | 2023.06.04 |
Solidity 문법 - (22) payable 키워드 (0) | 2023.06.04 |
Solidity 문법 - (21) modifier (0) | 2023.06.04 |