하나의 컨트랙에서 다른 컨트랙의 특정 함수를 ‘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));
}
}
첨부해주신 코드에서 // 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를 충분히 높게 설정하여 동작 시켜보면 좋겠습니다.
@sytech
먼저, KlaytnIDE 에서 가스 리밋 조정이 반영안되는 문제가 있어 보입니다. (해당 내용은 관련 팀에 전달드리도록 하겠습니다.)
다시 내용으로 돌아가서, 배포하신 Add Contract (해당 코드 라인 코멘트 해제 한 상태) 에 직접 add 함수를 호출 할 경우 gas를 28637 소모 합니다. (Storage에 sum을 최초로 기록할 경우엔 43637 소모)
최초 기록 시
Tx hash: 0x01c507f7c78782dbf69d1498494764f984810da57ec55b7149e07bcf08e0823f
이후 기록 시
Tx hash: 0xe873a5d1053eb7432bcac37e9514647cf99dcb0cb740eb4ff3731aa8ca019596