Verifying CREATE2 code on bscscan/etherscan -- how to do it?

Doesn't seem like replies to older posts come up, so this is a perplexing question (and the source code and bscscan links are there):

https://forum.openzeppelin.com/t/how-to-verify-contract-on-etherscan-deployed-using-create2/5936

@abcoathup Wondering if you have any suggestions? If the address is computed from a hash of the salt, nonce, sender and bytecode, the source that's used in CREATE2 should still be otherwise unaltered. But directly deploying code that verifies in bscscan.com doesn't verify if deployed via CREATE2, none of the bytecode matches so it won't verify the source.

Any suggestions or guidance would be most welcome, and thank you in advance for reply! :slight_smile:

Can you share the address of the contract?
I assume that would be the address returned by this command:

npx oz create2 Vault --salt 12345 --init --args 0xC114C2C34aBa31407fb315e8634b0e6F13BB0eCD --network bscTestnet

Can you share the exact code that you used, without flattening?

It's the vault code from the tutorial, I assume you saw that in the issue you closed?

When I'm back on my desktop I'll paste it anyway.

Thanks for looking into this!

This is from the tutorial, I have local solc 0.5.19 so that's the only change:

// File: @openzeppelin/upgrades/contracts/Initializable.sol

pragma solidity >=0.4.24 <0.7.0;


/**
 * @title Initializable
 *
 * @dev Helper contract to support initializer functions. To use it, replace
 * the constructor with a function that has the `initializer` modifier.
 * WARNING: Unlike constructors, initializer functions must be manually
 * invoked. This applies both to deploying an Initializable contract, as well
 * as extending an Initializable contract via inheritance.
 * WARNING: When used with inheritance, manual care must be taken to not invoke
 * a parent initializer twice, or ensure that all initializers are idempotent,
 * because this is not dealt with automatically as with constructors.
 */
contract Initializable {

  /**
   * @dev Indicates that the contract has been initialized.
   */
  bool private initialized;

  /**
   * @dev Indicates that the contract is in the process of being initialized.
   */
  bool private initializing;

  /**
   * @dev Modifier to use in the initializer function of a contract.
   */
  modifier initializer() {
    require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");

    bool isTopLevelCall = !initializing;
    if (isTopLevelCall) {
      initializing = true;
      initialized = true;
    }

    _;

    if (isTopLevelCall) {
      initializing = false;
    }
  }

  /// @dev Returns true if and only if the function is running in the constructor
  function isConstructor() private view returns (bool) {
    // extcodesize checks the size of the code stored in an address, and
    // address returns the current address. Since the code is still not
    // deployed when running a constructor, any checks on its code size will
    // yield zero, making it an effective way to detect if a contract is
    // under construction or not.
    address self = address(this);
    uint256 cs;
    assembly { cs := extcodesize(self) }
    return cs == 0;
  }

  // Reserved storage space to allow for layout changes in the future.
  uint256[50] private ______gap;
}

// File: contracts/Vault.sol

// contracts/Vault.sol
pragma solidity 0.5.17;


contract Vault is Initializable {
    address payable owner;

    function initialize(address payable _owner) initializer public {
        owner = _owner;
    }

    function withdraw() public {
        require(owner == msg.sender);
        owner.transfer(address(this).balance);
    }

 //  owner = msg.sender;

 function close() public {
  selfdestruct(owner);
 }


}

Yeah sorry, I am not able to verify either. Create2 should not be affecting the ability to verify, so the error must be something else. I would suggest deploying the contract without create2 to make sure you can verify it. Then deploy it using create2 and try verification again.

I would also recommend moving away from the OpenZeppelin CLI as we can't provide good support for it anymore.

Yes, it verifies first try just deploying it.

I'm bummed the cli isn't being updated, it's really elegant and useful. :frowning: That said, the issue isn't oz-cli, it's deploying via contract. I haven't yet had time to dig into it...

Regardless, thank you for responding, I appreciate it! Any pointers if you have them would be most welcome -- it seems deploying from contract with certain constructor variables is the issue.

Regardless, when I solve it I'll post the update here.