# Deploying, Verifying and Operating Contracts — Blockchain & Smart Contracts (Solidity)

Source: https://www.geekswithgeeks.com/en/solidity/w-deploy

> Deploy reproducibly, verify source code and manage contracts in production.

## From testnet to mainnet

A professional deployment is **scripted and reproducible**: a `forge script` or Hardhat Ignition module deploys contracts, sets configuration and transfers ownership, first on a local fork, then on a **testnet** such as Sepolia, then on mainnet or an L2. **Verify** source code on block explorers (Etherscan and compatible explorers, or Sourcify) so users and tools can read it: `forge verify-contract` or a `--verify` flag during deployment. Record deployed addresses, constructor arguments, compiler version and settings in the repository. **Keys**: use a hardware wallet or encrypted keystore for the deployer, never a raw key in a `.env` file on a shared machine, and immediately **hand admin rights to a multisig** (Safe), possibly behind a timelock. **Operations**: monitor events and balances with alerting, have a documented **incident response** plan (who can pause, how to communicate), track dependencies and compiler bugs, and plan upgrades or migrations. Consider **gas costs** on your target chain, **chain differences** (opcode support and block times on L2s), and legal, tax and regulatory requirements in your jurisdiction before handling users' funds or issuing tokens.

## A deployment script with Foundry

Deploy, configure and hand ownership to a multisig in one reproducible script.

```solidity
// script/DeployMembership.s.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {Script, console} from "forge-std/Script.sol";
import {Membership} from "../src/Membership.sol";

contract DeployMembership is Script {
    function run() external returns (Membership membership) {
        address multisig = vm.envAddress("ADMIN_MULTISIG");
        address issuer = vm.envAddress("ISSUER_ADDRESS");

        vm.startBroadcast();                       // signer comes from CLI flags (keystore or hardware wallet)
        membership = new Membership(multisig, issuer);
        vm.stopBroadcast();

        console.log("Membership deployed at", address(membership));
    }
}

// Dry run against a fork, then broadcast and verify:
//   forge script script/DeployMembership.s.sol --rpc-url $SEPOLIA_RPC_URL
//   forge script script/DeployMembership.s.sol --rpc-url $SEPOLIA_RPC_URL \
//       --account deployer --broadcast --verify
// (--account uses an encrypted keystore created with: cast wallet import deployer --interactive)
```

## Rehearse on a fork

Running the exact deployment script against a fork of the target chain catches wrong addresses, missing permissions and gas surprises before you spend real money or deploy something irreversible.

**Quiz:** Why verify contract source code on a block explorer?

- [ ] It makes the contract cheaper
- [ ] It is required for the contract to run
- [x] So users and tools can read and check the code that is actually deployed
- [ ] It hides the bytecode

*Answer:* So users and tools can read and check the code that is actually deployed. Verification links published source to the on-chain bytecode, enabling public review.
