Kaiascan에서 토큰명과 심볼이 조회가 안되어서 문의드립니다

안녕하세요.

Hardhat을 통해서 컴파일된 Solidity파일을 Java로 deploy를 진행하고 있었습니다.

성공적으로 배포가 되었는데 그때 배포성공한 링크는 주소입니다.

Kaiascan에서 조회했을 때 토큰명과 심볼이 노출이 안되어서 디버깅을 하다가 해결이 안되어 문의드립니다.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";
import "@openzeppelin/contracts/access/extensions/AccessControlEnumerable.sol";

interface IKIP7Receiver {
    function onKIP7Received(
        address operator,
        address from,
        uint256 amount,
        bytes calldata data
    ) external returns (bytes4);
}

contract SampleTokenDirect is
    ERC20,
    Pausable,
    AccessControlEnumerable
{
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");

    bytes32 public constant ACTION_TRANSFER = keccak256("ACTION_TRANSFER");
    bytes32 public constant ACTION_MINT = keccak256("ACTION_MINT");
    bytes32 public constant ACTION_BURN = keccak256("ACTION_BURN");
    bytes32 public constant ACTION_SAFE_TRANSFER = keccak256("ACTION_SAFE_TRANSFER");
    bytes32 public constant ACTION_SAFE_TRANSFER_FROM = keccak256("ACTION_SAFE_TRANSFER_FROM");

    event ActionExecuted(
        bytes32 indexed action,
        address indexed operator,
        address indexed from,
        address to,
        uint256 amount,
        bytes data
    );

    function _emitAction(
        bytes32 action, address operator, address from,
        address to, uint256 amount, bytes memory data
    ) internal {
        emit ActionExecuted(action, operator, from, to, amount, data);
    }

    string public version;

    constructor(
        string memory name_,
        string memory symbol_,
        uint256 initialSupply_,
        address admin_
    ) ERC20(name_, symbol_) {
        require(admin_ != address(0), "admin is zero");

        _grantRole(DEFAULT_ADMIN_ROLE, admin_);
        _grantRole(MINTER_ROLE, admin_);
        _setRoleAdmin(MINTER_ROLE, DEFAULT_ADMIN_ROLE);
        _grantRole(BURNER_ROLE, admin_);
        _setRoleAdmin(BURNER_ROLE, DEFAULT_ADMIN_ROLE);
        _grantRole(PAUSER_ROLE, admin_);
        _setRoleAdmin(PAUSER_ROLE, DEFAULT_ADMIN_ROLE);

        version = "DIRECT-V5.0";

        if (initialSupply_ > 0) {
            _mint(admin_, initialSupply_);
        }
    }

    // ERC20 standard
    function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
        _mint(to, amount);
        _emitAction(ACTION_MINT, _msgSender(), address(0), to, amount, bytes(""));
    }

    function burn(uint256 amount) public {
        _burn(_msgSender(), amount);
        _emitAction(ACTION_BURN, _msgSender(), _msgSender(), address(0), amount, bytes(""));
    }

    function transfer(address to, uint256 value) public override returns (bool) {
        bool ok = super.transfer(to, value);
        if (ok) _emitAction(ACTION_TRANSFER, _msgSender(), _msgSender(), to, value, bytes(""));
        return ok;
    }

    function pause() public onlyRole(PAUSER_ROLE) { _pause(); }
    function unpause() public onlyRole(PAUSER_ROLE) { _unpause(); }

    // KIP7 safeTransfer
    function safeTransfer(address recipient, uint256 amount) public {
        address owner = _msgSender();
        _safeTransfer(owner, recipient, amount, "");
        _emitAction(ACTION_SAFE_TRANSFER, owner, owner, recipient, amount, bytes(""));
    }

    function safeTransfer(address recipient, uint256 amount, bytes memory data) public {
        address owner = _msgSender();
        _safeTransfer(owner, recipient, amount, data);
        _emitAction(ACTION_SAFE_TRANSFER, owner, owner, recipient, amount, data);
    }

    function safeTransferFrom(address from, address to, uint256 amount) public {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _safeTransfer(from, to, amount, "");
        _emitAction(ACTION_SAFE_TRANSFER_FROM, spender, from, to, amount, bytes(""));
    }

    function safeTransferFrom(address from, address to, uint256 amount, bytes memory data) public {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _safeTransfer(from, to, amount, data);
        _emitAction(ACTION_SAFE_TRANSFER_FROM, spender, from, to, amount, data);
    }

    function _safeTransfer(address from, address to, uint256 amount, bytes memory data) internal {
        _transfer(from, to, amount);
        require(
            _checkOnKIP7Received(from, to, amount, data),
            "KIP7: transfer to non IKIP7Receiver implementer"
        );
    }

    function _checkOnKIP7Received(
        address from, address to, uint256 amount, bytes memory data
    ) private returns (bool) {
        if (to.code.length > 0) {
            try IKIP7Receiver(to).onKIP7Received(_msgSender(), from, amount, data)
                returns (bytes4 retval) {
                return retval == IKIP7Receiver.onKIP7Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("KIP7: transfer to non KIP7Receiver implementer");
                } else {
                    assembly { revert(add(32, reason), mload(reason)) }
                }
            }
        } else {
            return true;
        }
    }

    // Transfer hook: pause enforcement
    function _update(address from, address to, uint256 value) internal override whenNotPaused {
        super._update(from, to, value);
    }

    // KIP7 interface support (0x65787371)
    function supportsInterface(bytes4 interfaceId)
        public view virtual override(AccessControlEnumerable)
        returns (bool)
    {
        return interfaceId == 0x65787371 || super.supportsInterface(interfaceId);
    }
}

위는 제가 배포했을 때의 Solidity파일이고

배포에 사용한 Java 소스는

String encodedConstructor = FunctionEncoder.encodeConstructor(Arrays.asList(
    new Utf8String(tokenName),
    new Utf8String(tokenSymbol),
    new Uint256(initialSupply),
    new Address(ownerAddress)
));

String deployData = bytecode + Numeric.cleanHexPrefix(encodedConstructor);
String txHash = sendContractCreationTx(web3j, walletApi, params, chainId, ownerAddress, deployData);
String contractAddress = waitForContractAddress(web3j, txHash, 60, 1000L);

이 방식으로 배포하였습니다

어떤 문제가 있어서 Kaiascan에서 심볼과 라벨이 조회가 안된 원인이 뭐인지 모르겠습니다

안녕하세요, Kaiascan에서 컨트랙트 코드를 verify 해보시는걸 추천드립니다. 아래 문서 참고 부탁드립니다.

안녕하세요. 답변 감사합니다

알려주신 Verify를 호출해서 성공했습니다.

컨트랙트에 계약소스를 확인했을 때도 정상적인 것을 확인했습니다

궁금한건 이 위에 있는 “라벨”영역에 토큰명과 토큰심볼에 대한 정보가 노출이 안되는데 이거는 어떻게 해결해야하나요??

Hardhat 플러그인을 통한 자동화된 검증 방식은 배포 파이프라인에서 컨트랙트 투명성을 확보하는 데 정말 효율적이네요. 특히 멀티체인 환경에서 ABI 일치 여부를 CLI 레벨에서 즉시 확인할 수 있다는 점이 개발 생산성 측면에서 큰 장점인 것 같습니다.