I'm looking at the OpenZeppelin ERC721 contract, and the function _safeMint is defined twice:

     * @dev Safely mints `tokenId` and transfers it to `to`.
     * Requirements:
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     * Emits a {Transfer} event.
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");

     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
    function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
        _mint(to, tokenId);
        require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");

The comments from both didn't help me understand. What I can see is that they receive different number of parameters, but how could the contract know which one I'm calling?

My question is how does this work? Shouldn't it cause a compilation error or at least one overwriting the other? And why use the same name, is this a feature I'm not aware of?

1 Answer 1


You can have multiple functions with the same name, as long as their signature is not the same. The parameters are also part of the signature, so the function signature of those two functions is different. So the functions do not get mixed up in any way. Whenever you call a contract function, you have to provide the parameters as well. The executed function is chosen based on the name and provided parameters, .

The first function is just a shorthand version of the second hand, since it calls the second function. They could have different names and it would work in the same way, but the same name was probably chosen because the first is just pointing to the second one.

  • 1
    it makes the "data" field optional by using overloading - if data is included, it'll use the 4-arg version, if it's not included, it'll call the three-arg version, which in turn just puts in an empty string for data calling the 4-arg version
    – Linum Labs
    Commented Apr 11, 2021 at 18:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.