External function을 delegatecall 을 통해 호출하는 방법

안녕하세요.

바오밥 테스트넷에서, 기존에 민트되었던 NFT를 소각하려고 하는데,
개별 토큰을 caver를 통해 소각하려니, KAS API사용량이 너무 많아질것같아서,
새로운 컨트랙트를 만들어서 KIP17 컨트랙트의 mint 또는 burn 명령어를 for loop을 통해 한번에 진행하고자 합니다.

이 경우 새로 생성된 컨트랙트가 NFT 컨트랙트내의 토큰 소유자가 아니기 때문에 delegatecall을 써야하는것 같아서 수행해봤는데, Scope 의 input data를 보면, Decoded Value에 확인이 되고, 트랜잭션이 성공했음에도 불구하고, 실제 민팅이나 소각이 실행되지 않았습니다.

byte로 인코딩하는 문제에서 생긴것 같은데, 혹시 도움받을수 있을까요?

delegatecall 은 컨트랙트 내에서 다음과 같이 호출했습니다.

contract BurnHelper {
    using SafeMath for uint256;
    address public nftAddress;
    
    constructor(address _nftAddress) public {
        nftAddress = _nftAddress;
    }

    function massMint(uint256 start, uint256 end) external {
        
        for (uint256 i = start; i <= end; i += 1) {
            (bool success, bytes memory data) = 
            nftAddress.delegatecall(abi.encodeWithSignature("burn(uint256)",i));
        }
    }
}

일단 위에 있는 방법을 개선하는 것이 가장 원하는 방법이긴 한데,
혹시 제 접근방법이 틀렸다면, 어떻게 접근하면 좋을지 도움을 구하고 싶습니다.

제가 구현하고 싶은것은 한마디로 말씀드리면, 다른 컨트랙트를 호출하는 새로운 컨트랙트 생성해, 기존에 onlyMinter 혹은 onlyOwner등의 modifier 가 붙은 함수를 그 새로운 컨트랙트를 통해 반복수행하고 싶습니다.

회신 기다리겠습니다.

감사합니다.

1개의 좋아요

안녕하세요.

해당 nftAddress의 데이터를 변경하는 내용이기 때문에 delegatecall이 아닌 call을 사용해야되는게 아닌가 싶습니다. 아래 내용 참고해보시면 어떨까 합니다.

https://solidity-by-example.org/delegatecall/

2개의 좋아요

답변 감사드립니다.

delegation call이 해당 컨트랙트의 값을 변화시킬 때 msg.sender의 권한을 사용하는 것으로 알고있었는데, 내용상으로는 A 컨트랙트에서 delegatecall을 실행 했을 때에 B컨트랙트에 있는 함수 X를 A가 라이브러리 처럼 사용해서 A 컨트랙트 있는 값이 변화된다는 것으로 이해하면 될까요?

만약 그렇다면 제가 내용을 오해하고 있었군요. 정보 감사드립니다!

Hello Ethan,

i tried the example of the delegatecall on klaytn baobab testnet, but the A’s storage is NOT set. Could you please help check?

https://solidity-by-example.org/delegatecall/

@lorance.call did you try that please?

Thanks.