Skip to main content

Verify source code with Sourcify

Overview

This guide explain how to verify a smart contract on Ronin by submitting the source code and metadata to Ronin's internal Sourcify service.

Verify using hardhat-deploy

There are two options to verify the contract using hardhat-deploy: invoke the command-line tool and integrate in the deployment script.

Option 1. Command-line tool

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>

For more information, see hardhat-sourcify.

Option 2. Script

  1. Save the following script into deploy/verify-contract.ts.
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;
  1. Include this script in the actual deployment script's dependencies. For example:
deploy/sample-contract.ts
deploy.dependencies = ['VerifyContracts'];

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 run solc with the --metadata option to print the contract's metadata.

The following command prints out the metadata for the Token.sol file.

solc Token.sol --metadata

The output in the terminal is as follows:

======= 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 as metadata.json.

note

The metadata.json generated this way doesn't include the source code. You need to upload both the source code in .sol and the metadata.json file 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 the API

The API endpoint of verification is public and available to all users. This endpoint can be used to verify the authenticity and integrity of data related to your contracts.

Endpoints:

  • POST https://sourcify.roninchain.com/server/verify
  • POST https://sourcify.roninchain.com/server/verify/create2

For further information and instructions on how to use the verify API endpoint, see Verification API.

See also

Was this helpful?
Happy React is loading...