Verify a smart contract
Overview
Verifying a smart contract is a crucial step to ensure the integrity and security of the Ronin network. The verification involves inspecting the contract's source code to ensure that it is bug-free, secure, and will perform as expected. We encourage the contract deployers to verify their contract by submitting the source code and metadata to our internal Sourcify service.
Verify using Hardhat
Hardhat is a development environment to compile, deploy, test, and debug your Ethereum software. hardhat-deploy is a deployment plugin for Hardhat that helps you automate the deployment of your smart contracts.
With hardhat-deploy, you can verify the source code of your smart contract using the following methods:
- Using the CLI
- Using the deployment script
Option 1. Using the CLI
If your smart contract project uses hardhat-deploy
as a dependency,
specify the endpoint and network before verifying by
using the hardhat sourcify
command:
hardhat sourcify --endpoint https://sourcify.roninchain.com/server/ --network <ronin>
Do not drop the trailing slash /
in the endpoint URL.
For more information, see hardhat-sourcify.
Option 2. Using the script
- Save the following script to
deploy/verify-contract.ts
.
import { TASK_SOURCIFY } from 'hardhat-deploy';
import { network } from 'hardhat';
import { HardhatRuntimeEnvironment } from 'hardhat/types';
const deploy = async (hre: HardhatRuntimeEnvironment) => {
if (network.name == 'ronin' || network.name == 'saigon') {
await hre.run(TASK_SOURCIFY, {
endpoint: 'https://sourcify.roninchain.com/server',
});
}
};
deploy.tags = ['VerifyContracts'];
deploy.runAtTheEnd = true;
export default deploy;
- Include this script in the actual deployment script's dependencies. For example:
deploy.dependencies = ['VerifyContracts'];
Verify using Foundry
Foundry is a command-line tool that helps you verify the source code of your smart contract on the Ronin network.
To verify your smart contract using Foundry, follow these steps:
- Install Foundry by following the installation guide.
- Run the following command:
forge verify-contract --verifier sourcify --verifier-url https://sourcify.roninchain.com/server/ --chain-id <CHAIN> <ADDRESS> <CONTRACT>
Replace the following placeholders with the actual values:
<CHAIN>
: The chain to which the contract is deployed, such as2021
for the Ronin mainnet or2020
for the Saigon testnet.<ADDRESS>
: The address of the smart contract.<CONTRACT>
: The path to the contract in the format<path>:<contract>
, such assrc/SampleContract.sol:SampleContract
.
You should see output similar to this:
Start verifying contract `0xADDRESS` deployed on 2021
Submitting verification for [SampleContract] "0xADDRESS".
Contract successfully verified
For the full list of options you can use with the forge-verify-contract
command, see the forge verify-contract documentation.
Verify using Sourcify UI
Step 1. Locate smart contract metadata
Smart contract's metadata is automatically generated by the Solidity compiler in the
form of a .json
file. It contains information about the compiled smart contract.
The metadata is located in different locations depending on the tool you use to
compile smart contracts.
Solidity compiler contract metadata
- If you use solc for compiling, then to print out the contract's metadata, run the following command:
solc <CONTRACT>.sol --metadata
Replace <CONTRACT>
with the name of the contract file.
You should see output similar to this:
======= Token.sol:Token =======
Metadata:
{"compiler":{"version":"0.8.20+commit.a1b79de6"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{"balanceOf(address)":{"notice":"Read only function to retrieve the token balance of a given account. The `view` modifier indicates that it doesn't modify the contract's state, which allows us to call it without executing a transaction."},"constructor":{"notice":"Contract initialization."},"transfer(address,uint256)":{"notice":"A function to transfer tokens. The `external` modifier makes a function *only* callable from *outside* the contract."}},"version":1}},"settings":{"compilationTarget":{"Token.sol":"Token"},"evmVersion":"shanghai","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"Token.sol":{"keccak256":"0xa79117cae1147d7d93c6e5653e26d2ce4a6669f211a7de27ffc2ac61c57a115b","license":"UNLICENSED","urls":["bzz-raw://1b28ac474b44450104fc99400a70947517e0869274a3537c9d0ea8047d7b8146","dweb:/ipfs/QmYreFmttckn7Mru8z1oe89sVbWVUBd2WxvX8w12yreaFF"]}},"version":1}
- Copy the JSON object starting at
{”compiler”:...
to a new file and save it asmetadata.json
. - Upload your
metadata.json
file and the source code of your contract in the.sol
format to Sourcify.
Hardhat contract metadata
If you use Hardhat for compiling your smart contract, then after running the
hardhat compile
command,
you can find the metadata file in the artifacts/build-info
directory.
Hardhat includes the source code in the metadata file. You can upload just this
.json
file to Sourcify.
Step 2. Submit information
- After you find the metadata and source code, upload them to Sourcify. If your files are valid, a contract's details form is displayed on the right side of the page.
- To complete the verification process, fill out the smart contract address and select the chain to which it is deployed.
When verification is complete, a Verification successful!
message appears (pictured).
To interact with the example contract on the Ronin app and view its source code, visit https://saigon-app.roninchain.com/address/ronin:6df3a52ca77b2b785b9d9cb454725969e006c718?t=contract.
Verify using API
The following public API endpoints are available for verifying the source code of a smart contract.
POST https://sourcify.roninchain.com/server/verify
POST https://sourcify.roninchain.com/server/verify/create2
For more information on how to use these API endpoints, see Verification API.