테스트넷에서 되던함수가 메인넷에서는 안됩니다

function withdraw() external onlyOwner{
  msg.sender.transfer(address(this).balance);
}

테스트넷에서는 잘되던것이 메인넷환경에서만 안됩니다. -32000 JSON RPC 에러가 뜨네요…
onlyOwner부분이 문제되는것이 아닌것은 확인했습니다. 뭐가 문제일까요 …

키가 없거나 매칭이 잘 안되 사인이 안되서 생긴 문제일 수 있습니다.
에러메세지 전체를 첨부해주시면 더욱 자세히 답변이 가능합니다.

Error: Returned error: gas required exceeds allowance or always failing transaction
에러메세지가 이렇게뜹니다. 포스 샌딩 하면 클레이튼스코프에서 0x02 에러코드로 나오구요

@Alan_Kim

테스트넷에는 KLAY 가 있으시지만 메인넷에선 없으신 거 같네요.
저희 측에서 재현이 용이하도록 상세한 환경 공유 부탁드립니다. 소유하신 KLAY 도 얼마인지 알려주세요 :slight_smile:

메인넷에서도 6클레이 갖고있습니다. 수수료가 부족한건 아닌거같은게 최대가스리밋 300만으로 해도 1클레이 이하로 나오던데 ㅜㅜㅜㅜ

function withdraw() external onlyOwner{
msg.sender.transfer(address(this).balance);
}

위 펑션이 그냥 단순하게 컨트랙트에 있는 물량을 전부 msg.sender에게 보내는함수거든요.
호출자가 오너인건 몇번이나 확인했구요. 계속 위 에러 뜨면서 작동이 안됩니다 ㅜㅜㅜㅜ

@Alan_Kim

컨트랙트 코드 원문이랑 호출하실 때 어떻게 호출하셨는지 좀 더 상세히 설명 부탁드릴게요.
Txid도 공유 부탁드리고요.

재현 가능하게끔 공유해주시면 저희 쪽에서도 더 빠르게 도와드릴 수 있습니다.

네 알겠습니다. ! 내용이 많아 메세지로 남겼습니다. 확인 부탁드리겠습니다 !

해당 함수에 대해 특정 케이스에서만 안되는 경우를 발견하여 공유 후 질문드립니다 …

현재 해당 함수를 0.5.17 / Instanbul EVM으로 설정하여 싸이프러스 메인넷에서 배포시 (리믹스를 사용하여 배포하였습니다)

함수 작동이 되지 않습니다… 물론 같은 설정으로 바오밥 테스트넷이나, 이더리움 테스트넷 등에서는

모두 작동 하는것을 확인 했습니다. 싸이프러스에서 같은 설정으로 저 함수를 동작시킬떈

함수를 payable로 만들어줘야만 동작하더군요 … 이미 메인넷에 컨트랙트가 올라가있는 상황이고,

따로 수정은 불가한 상황에서 0.5.17 / Instanbul EVM으로 컴파일하여 배포한 해당 컨트랙트를

다른 환경과 같이 동작하게 하는 방법이 있을까요 .? 답변 부탁드리겠습니다… 감사합니다.

소스는

KIP17표준에서 해당 KIP17Full.sol로 컴파일하였습니다.

이 소스를 위의 특정 상황으로 컴파일후 배포하면

withdraw 함수가 동작하지않습니다…

KIP17Custom.sol

pragma solidity ^0.5.0;

import "./KIP17.sol";
import "./KIP17Metadata.sol";
import "./KIP17Enumerable.sol";
import "../../access/roles/MinterRole.sol";
import "../../math/SafeMath.sol";
import "../../utils/String.sol";
import "../../ownership/Ownable.sol";

contract KIP17Custom is KIP17, KIP17Enumerable, KIP17Metadata, MinterRole, Ownable{
    event SetBlacklist(address user, bool status);

    mapping(address => bool) public blacklist;

    bool private _paused;

    constructor () public {
    }

    function setBlacklist(address user, bool status) external onlyOwner {
        blacklist[user] = status;
        emit SetBlacklist(user, status);
    }

    function _transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) internal {
        require(!blacklist[from] && !blacklist[to], "BLACKLIST");
        super._transferFrom(from, to, tokenId);
    }

    function withdraw() external onlyOwner{
      msg.sender.transfer(address(this).balance);
    }

    function isPaused() public view returns(bool) {
      return _paused;
    }

    function pause() public onlyOwner {
      require(!_paused);
        _paused = true;
    }

    function unpause() public onlyOwner {
      require(_paused);
        _paused = false;
    }

    function tokensOfOwner(address owner) external view returns (uint256[] memory) {
        return _tokensOfOwner(owner);
    }

}

KIP17Full.sol

pragma solidity ^0.5.0;

import "./KIP17.sol";
import "./KIP17Enumerable.sol";
import "./KIP17Metadata.sol";
import "../../ownership/Ownable.sol";
import "./KIP17Custom.sol";

/**
 * @title Full KIP-17 Token
 * This implementation includes all the required and some optional functionality of the KIP-17 standard
 * Moreover, it includes approve all functionality using operator terminology
 * @dev see http://kips.klaytn.com/KIPs/kip-17-non_fungible_token
 */

contract KIP17Full is KIP17, KIP17Custom {
    constructor (string memory name, string memory symbol) public KIP17Metadata(name, symbol) {
        // solhint-disable-previous-line no-empty-blocks
    }
}

싸이프러스 메인넷에서만 리믹스상 0.5.17 / Istanbul 로 컴파일하여 배포한 경우
위 코드의 withdraw 함수가 동작하지않습니다…

동작하지 않는 경우 …
0x985c7a3809c88e24ee66cb05256894ca10b38511d85265c69288c6bf951e3955

동작하는 경우 (EVM을 Instalbul외 다른걸로 지정하고 컴파일했을시…)
0x8ca58d1587d4517a1d0e4ea7e29992e82f4453c185e54e137725e55418ae1185

원인이되는 액션은 찾았으나 왜그런지는 아직도 잘 모르겠습니다…

도와주세요 …

안녕하세요 추가 설명을 드리자면,

cypress 네트워크의 경우 아직 Istanbul 하드포크가 activate되지 않았기에, istanbul target version으로 컴파일을 하면 호환되지 않을 수 있습니다.

지금 문의주신 내용을 보면, address(this).address 부분에서 문제가 발생될 수 있을 것 같습니다. 즉, istanbul 이전 target version으로 컴파일하면, selfbalance opcode를 사용하지 않지만, istanbul target version을 사용하면 selfbalance opcode를 사용하도록 컴파일이 됩니다.

제일 확실한 것은, 리믹스에서 디버그를 해보시는 것이며, istanbul로 컴파일된 컨트랙트를 호출한 tx를 디버그 해보았을때, istanbul 하드포크에서 추가된 opcode가 사용되는지 한번 확인해보시기 바랍니다.

다음과 같은 klaytn-docs 내용 등을 보시면, protocol upgrade 내용과 함께 관련 설명이 써져 있으니 참고 바랍니다.

2 Likes

@Alan_Kim

문제를 요약하면,

  • Cypress 메인넷에 Istanbul EVM 으로 컴파일 된 바이트코드를 배포하셔서 문제가 되고 있음.
  • Cypress 메인넷에는 Constantinople EVM 으로 컴파일 한 뒤 바이트코드를 배포 했었어야 함.
  • Cypress 메인넷에 Istanbul EVM 업그레이드 내용이 반영되면, 해당 함수가 잘 동작할 것으로 예상 됨.

입니다.

참고로 IDE에서는 아래 사진 처럼 메인넷에 호환되는 EVM 버전이 명시가 되어 있습니다. 이 점 주의하셔서 사용 부탁드립니다.

도움이 되었길 바랍니다.

답변 감사드립니다. 그럼 이스탄불관련 3.31에 예정된 하드포크 이후에는 해당 기능이 동작할수도 있다는건가요!?
이스탄불 evm이 호환되는 바오밥포함 다른네트웍에선 문제없이 동작하는 상태입니다!

@Alan_Kim

네. 이스탄불 하드포크가 Cypress에도 적용되면 문제 없이 동작할 것으로 예상됩니다.

잘 동작 했으면 좋겠네요.

1 Like

답변 너무 감사드려요 :slight_smile: 다행히 시기가 맞아서 ㅜㅜ 큰일날뻔했네요 정말 감사합니다.