Smart Contract / call을 사용한 외부 컨트랙트 호출

안녕하세요,

하나의 컨트랙에서 다른 컨트랙의 특정 함수를 ‘call’ 하는 예시를 작성해보고 있습니다. 작성 중에 궁금한 점이 생겨서 문의드립니다 ㅎㅎㅎ

아래는 제가 사용한 코드입니다.

  • Add contract의 add(a,b) 는 a+b를 수행합니다.
  • AddProxy contract는 'Add contract’의 주소와 a,b를 입력으로 받아 'Add contract’의 ‘add(a,b)’ 함수를 호출합니다.

그런데, Add contract의 add(a,b) 함수에서 ‘sum = a+b;’ 가 주석 처리 될 경우에는, 원하는 대로 수행되어서 event log를 Klaytn IDE에서 확인할 수 있었습니다.
그런데, 'sum = a+b;'를 주석 해제할 경우에는, 원하는 대로 수행이 안되는 것 같습니다. event log도 안남고, 실제 contract의 ‘sum’ state 값도 변경되지 않았습니다.

아주 오랜 시간을 쓰고도 원인을 알지를 못해서, 너무 답답한 마음에 글을 올려 봅니다 ㅜㅜ… 왜 그런걸까요? 심지어 fallback으로 빠지지도 않네요

pragma solidity ^0.5.3;

contract Add {
    uint public sum;
    
    event FallbackCalledEvent(bytes data);
    event AddEvent(uint a, uint b, uint result);

    function() external{
        emit FallbackCalledEvent(msg.data);
    }
    
    function add(uint a, uint b) public returns(uint){
        uint _result = a + b;
        emit AddEvent(a, b, _result);
        // sum = _result;
        return _result;
    }
    
    function getBlockNumber() public view returns (uint256) {
        return block.number;
    }
}

contract AddProxy {
    uint public sum;
    
    function callAddlTest(address other, uint a, uint b) public {
        other.call(abi.encodeWithSignature("add(uint256,uint256)",a,b));
    }
    
}

@sytech
안녕하세요.

첨부해주신 코드에서 // sum = _result; 부분의 주석을 제거하여도 문제 없는 코드로 보이고, 이벤트 발생까지 정상 작동 합니다.
직접 동작 시켰을 때 Tx는 revert가 되지 않았지만 other.call(…) 호출한 내용으로 event 발생도 하지 않고, sum값이 업데이트 되지 않았다면 low level call 부분(other.call(abi.encodeWithSignature("add(uint256,uint256)",a,b));)이 fail 된 것으로 보입니다.
코드에 문제가 없어보이니 한가지 가능성은 call 동작을 위한 gas가 충분하지 않아 low level call 동작을 끝까지 수행시키지 못하고 fail 된 상태로 종료 되었을것 같습니다.
Transaction 생성시 gas를 충분히 높게 설정하여 동작 시켜보면 좋겠습니다.

만약 계속해서 정상동작 하지 않는다면, Tx hash를 함께 첨부하여 주세요.

감사합니다.

답변 감사드립니다. 그런데, 가스 리미트를 올리고 해도 같네요…

아래에 자세한 내용을 추가했으니, 한 번 봐주실 수 있을까요~

KlaytnIDE을 통해 Baobab에서 테스트 하였습니다.

(1) Add Contract (해당 코드 라인 코멘트 된 상태): 0x7d47322Bc7a5B83d8EE3a19A547b1F9dfDf635C2

(2) Add Contract (해당 코드 라인 코멘트 해제 한 상태): 0xB4cA121E862Cd11999AD913aeA9f7c97B530B5EF

(3) AddProxy Contract 0xd071d72A8bAE836bF5319A5af1e13D258a3eC03E

(3)을 통해, (1)을 호출
Transacion hash: 0x6f03a8cdf31b21bfc3b878fc0864b62ce9eca1e6bc84fead08804dae50f1ebe5

(3)을 통해, (2)를 호출,
Transaction hash: 0x474e4a61a3f822385eedbcb440ebdd3076a3b94318fcdacb0e7bf2a34d586926

@sytech
먼저, KlaytnIDE 에서 가스 리밋 조정이 반영안되는 문제가 있어 보입니다. (해당 내용은 관련 팀에 전달드리도록 하겠습니다.)
다시 내용으로 돌아가서, 배포하신 Add Contract (해당 코드 라인 코멘트 해제 한 상태) 에 직접 add 함수를 호출 할 경우 gas를 28637 소모 합니다. (Storage에 sum을 최초로 기록할 경우엔 43637 소모)
최초 기록 시
Tx hash: 0x01c507f7c78782dbf69d1498494764f984810da57ec55b7149e07bcf08e0823f

이후 기록 시
Tx hash: 0xe873a5d1053eb7432bcac37e9514647cf99dcb0cb740eb4ff3731aa8ca019596

캡쳐해주신 트랜잭션 내용을 보았을 때 가스가 26596로 설정이 되어있는데, AddProxy contract에서 call 로 해당 내용을 호출하는 트랜잭션의 경우 gas가 28637 보다 많이 소모되어야 할 것입니다.

배포해주신 컨트랙트들을 이용하여 Gas limit을 높여 AddProxy Contract를 수행하였을 때 아래 Tx로 정상적으로 수행됨을 확일 할 수 있습니다. 이벤트 로그 탭을 확인하여 주세요.
0x69d3359356449541fe11c4f0746160e6a15f0ff54dc309b16f58e05069caef1a

Low level call 테스트는 KlaytnIDE에서 해당 문제가 해결되기 전까지는 다른 방법으로 테스트 해보시길 추천 드립니다.

2개의 좋아요

아… IDE에 그런 문제가… 있었군요…

분노가 일순간 생겼지만,
너무나 친절하신 설명에 감사드립니다~

2개의 좋아요