Uniswap V2 合约部署全攻略:Web3 实践指南

· 3min · Paxon Qiao

Uniswap V2 合约部署全攻略:Web3 实践指南

去中心化金融(DeFi)浪潮席卷全球,Uniswap V2 作为顶尖的自动化做市商(AMM)协议,是 Web3 开发的必学核心。本教程基于 Solidity 0.8.30,带你一步步在 Hoodi 测试网部署 Uniswap V2 核心合约(Factory、Router02、WETH9 等)及自定义代币,并实现流动性添加。无论你是区块链新手还是资深开发者,本文提供清晰的实操步骤和源码,助你快速上手 DeFi 合约开发,开启 Web3 创新之旅!

本教程详细指导如何基于 Solidity 0.8.30 在 Hoodi 测试网部署 Uniswap V2 核心合约(Factory、Router02、WETH9 等)及 AToken、BToken,涵盖合约编译、部署、验证及流动性添加全流程。所有步骤均经过实操验证,配有完整源码(GitHub: https://github.com/qiaopengjun5162/Uniswap-v2-08),助你快速掌握 DeFi 合约开发。适合 Web3 开发者实践,轻松构建去中心化交易所!

实操

前提准备

编译合约

Uniswap-v2-08 on  main [?] on 🐳 v28.2.2 (orbstack) 
➜ forge build
[⠒] Compiling...
[⠒] Compiling 87 files with Solc 0.8.30
[⠒] Solc 0.8.30 finished in 11.92s
Compiler run successful!

第一步:部署 UniswapV2Factory 合约

Uniswap-v2-08 on  main [✘!?] on 🐳 v28.2.2 (orbstack) took 11.5s 
➜ forge build                                                                              
[⠒] Compiling...
No files changed, compilation skipped

Uniswap-v2-08 on  main [✘!?] on 🐳 v28.2.2 (orbstack) 
➜ source .env                                                                              

Uniswap-v2-08 on  main [✘!?] on 🐳 v28.2.2 (orbstack) 
➜ forge script UniswapV2FactoryScript --rpc-url $HOODI_RPC_URL --broadcast --verify -vvvvv 
[⠒] Compiling...
No files changed, compilation skipped
Traces:
  [132] UniswapV2FactoryScript::setUp()
    └─ ← [Stop]

  [2130098] UniswapV2FactoryScript::run()
    ├─ [0] VM::envUint("PRIVATE_KEY") [staticcall]
    │   └─ ← [Return] <env var value>
    ├─ [0] VM::addr(<pk>) [staticcall]
    │   └─ ← [Return] 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5
    ├─ [0] console::log("Deploying contracts with the account:", 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5) [staticcall]
    │   └─ ← [Stop]
    ├─ [0] VM::startBroadcast(<pk>)
    │   └─ ← [Return]
    ├─ [2078726] → new UniswapV2Factory@0x79D86a83bFe89eC1dc5F65021f8F66A50Cc443CC
    │   └─ ← [Return] 10271 bytes of code
    ├─ [0] console::log("UniswapV2Factory deployed to:") [staticcall]
    │   └─ ← [Stop]
    ├─ [0] console::log(UniswapV2Factory: [0x79D86a83bFe89eC1dc5F65021f8F66A50Cc443CC]) [staticcall]
    │   └─ ← [Stop]
    ├─ [0] VM::toString(0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5) [staticcall]
    │   └─ ← [Return] "0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5"
    ├─ [0] VM::toString(UniswapV2Factory: [0x79D86a83bFe89eC1dc5F65021f8F66A50Cc443CC]) [staticcall]
    │   └─ ← [Return] "0x79D86a83bFe89eC1dc5F65021f8F66A50Cc443CC"
    ├─ [0] VM::writeJson("{\"deployerAddress\": \"0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5\", \"uniswapv2factory\": \"0x79D86a83bFe89eC1dc5F65021f8F66A50Cc443CC\"}", "deployed_addresses.json")
    │   └─ ← [Return]
    ├─ [0] VM::stopBroadcast()
    │   └─ ← [Return]
    └─ ← [Return]


Script ran successfully.

== Logs ==
  Deploying contracts with the account: 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5
  UniswapV2Factory deployed to:
  0x79D86a83bFe89eC1dc5F65021f8F66A50Cc443CC

## Setting up 1 EVM.
==========================
Simulated On-chain Traces:

  [2078726] → new UniswapV2Factory@0x79D86a83bFe89eC1dc5F65021f8F66A50Cc443CC
    └─ ← [Return] 10271 bytes of code


==========================

Chain 560048

Estimated gas price: 1.896721648 gwei

Estimated total gas used for script: 2987623

Estimated amount required: 0.005666689220162704 ETH

==========================

##### hoodi
[Success] Hash: 0x4dc741cbbce957709ca3e19da0369440eeb1ba1290156535575da00677fff723
Contract Address: 0x79D86a83bFe89eC1dc5F65021f8F66A50Cc443CC
Block: 586921
Paid: 0.002541952143867928 ETH (2298172 gas * 1.106075674 gwei)

✅ Sequence #1 on hoodi | Total Paid: 0.002541952143867928 ETH (2298172 gas * avg 1.106075674 gwei)
                                                                                                                                         

==========================

ONCHAIN EXECUTION COMPLETE & SUCCESSFUL.
##
Start verification for (1) contracts
Start verifying contract `0x79D86a83bFe89eC1dc5F65021f8F66A50Cc443CC` deployed on hoodi
EVM version: cancun
Compiler version: 0.8.30
Optimizations:    200
Constructor args: 000000000000000000000000e91e2df7ce50bca5310b7238f6b1dfcd15566be5

Submitting verification for [src/UniswapV2Factory.sol:UniswapV2Factory] 0x79D86a83bFe89eC1dc5F65021f8F66A50Cc443CC.
Submitted contract for verification:
        Response: `OK`
        GUID: `uiqh5lvi61sd2jqc7iq3swuivgwdj3j4pmjyyz35nmkdgc4vva`
        URL: https://hoodi.etherscan.io/address/0x79d86a83bfe89ec1dc5f65021f8f66a50cc443cc
Contract verification status:
Response: `NOTOK`
Details: `Pending in queue`
Warning: Verification is still pending...; waiting 15 seconds before trying again (7 tries remaining)
Contract verification status:
Response: `OK`
Details: `Pass - Verified`
Contract successfully verified
All (1) contracts were verified!

Transactions saved to: /Users/qiaopengjun/Code/Solidity/Uniswap-v2-08/broadcast/UniswapV2Factory.s.sol/560048/run-latest.json

Sensitive values saved to: /Users/qiaopengjun/Code/Solidity/Uniswap-v2-08/cache/UniswapV2Factory.s.sol/560048/run-latest.json

UniswapV2Factory 合约地址:0x79D86a83bFe89eC1dc5F65021f8F66A50Cc443CC

https://hoodi.etherscan.io/address/0x79d86a83bfe89ec1dc5f65021f8f66a50cc443cc

第二步:部署 WETH 合约

Uniswap-v2-08 on  main [✘!?] on 🐳 v28.2.2 (orbstack) took 10.8s 
➜ mkdir -p ./deployments

Uniswap-v2-08 on  main [✘!?] on 🐳 v28.2.2 (orbstack) 
➜ forge build           
[⠒] Compiling...
No files changed, compilation skipped

Uniswap-v2-08 on  main [✘!?] on 🐳 v28.2.2 (orbstack) 
➜ source .env           

Uniswap-v2-08 on  main [✘!?] on 🐳 v28.2.2 (orbstack) 
➜ forge script WETH9Script --rpc-url $HOODI_RPC_URL --broadcast --verify -vvvvv            
[⠒] Compiling...
No files changed, compilation skipped
Traces:
  [132] WETH9Script::setUp()
    └─ ← [Stop]

  [507780] WETH9Script::run()
    ├─ [0] VM::envUint("PRIVATE_KEY") [staticcall]
    │   └─ ← [Return] <env var value>
    ├─ [0] VM::addr(<pk>) [staticcall]
    │   └─ ← [Return] 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5
    ├─ [0] console::log("Deploying contracts with the account:", 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5) [staticcall]
    │   └─ ← [Stop]
    ├─ [0] VM::startBroadcast(<pk>)
    │   └─ ← [Return]
    ├─ [458671] → new WETH9@0x55Ab36d5Ba138478445D31D4d1A316E5D3662F17
    │   └─ ← [Return] 1958 bytes of code
    ├─ [0] console::log("WETH9 deployed to:") [staticcall]
    │   └─ ← [Stop]
    ├─ [0] console::log(WETH9: [0x55Ab36d5Ba138478445D31D4d1A316E5D3662F17]) [staticcall]
    │   └─ ← [Stop]
    ├─ [0] VM::toString(0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5) [staticcall]
    │   └─ ← [Return] "0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5"
    ├─ [0] VM::toString(WETH9: [0x55Ab36d5Ba138478445D31D4d1A316E5D3662F17]) [staticcall]
    │   └─ ← [Return] "0x55Ab36d5Ba138478445D31D4d1A316E5D3662F17"
    ├─ [0] VM::writeJson("{\"deployerAddress\": \"0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5\", \"WETH9\": \"0x55Ab36d5Ba138478445D31D4d1A316E5D3662F17\"}", "./deployments/WETH9.json")
    │   └─ ← [Return]
    ├─ [0] VM::stopBroadcast()
    │   └─ ← [Return]
    └─ ← [Return]


Script ran successfully.

== Logs ==
  Deploying contracts with the account: 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5
  WETH9 deployed to:
  0x55Ab36d5Ba138478445D31D4d1A316E5D3662F17

## Setting up 1 EVM.
==========================
Simulated On-chain Traces:

  [458671] → new WETH9@0x55Ab36d5Ba138478445D31D4d1A316E5D3662F17
    └─ ← [Return] 1958 bytes of code


==========================

Chain 560048

Estimated gas price: 1.807610766 gwei

Estimated total gas used for script: 711925

Estimated amount required: 0.00128688329458455 ETH

==========================

##### hoodi
[Success] Hash: 0x9550621e7c393f9aace08ff55bbf350729cd8093937c7f883ab7fc5090601ca6
Contract Address: 0x55Ab36d5Ba138478445D31D4d1A316E5D3662F17
Block: 587169
Paid: 0.00057881956577445 ETH (547635 gas * 1.05694407 gwei)

✅ Sequence #1 on hoodi | Total Paid: 0.00057881956577445 ETH (547635 gas * avg 1.05694407 gwei)
                                                                                                                                         

==========================

ONCHAIN EXECUTION COMPLETE & SUCCESSFUL.
##
Start verification for (1) contracts
Start verifying contract `0x55Ab36d5Ba138478445D31D4d1A316E5D3662F17` deployed on hoodi
EVM version: cancun
Compiler version: 0.8.30
Optimizations:    200

Submitting verification for [src/WETH9.sol:WETH9] 0x55Ab36d5Ba138478445D31D4d1A316E5D3662F17.
Warning: Could not detect the deployment.; waiting 5 seconds before trying again (4 tries remaining)

Submitting verification for [src/WETH9.sol:WETH9] 0x55Ab36d5Ba138478445D31D4d1A316E5D3662F17.
Warning: Could not detect the deployment.; waiting 5 seconds before trying again (3 tries remaining)

Submitting verification for [src/WETH9.sol:WETH9] 0x55Ab36d5Ba138478445D31D4d1A316E5D3662F17.
Submitted contract for verification:
        Response: `OK`
        GUID: `ihurcwptizd4fatmqmexdbngsfnp44sn394vl3lxgxqjkdjcq3`
        URL: https://hoodi.etherscan.io/address/0x55ab36d5ba138478445d31d4d1a316e5d3662f17
Contract verification status:
Response: `NOTOK`
Details: `Pending in queue`
Warning: Verification is still pending...; waiting 15 seconds before trying again (7 tries remaining)
Contract verification status:
Response: `NOTOK`
Details: `Pending in queue`
Warning: Verification is still pending...; waiting 15 seconds before trying again (6 tries remaining)
Contract verification status:
Response: `OK`
Details: `Pass - Verified`
Contract successfully verified
All (1) contracts were verified!

Transactions saved to: /Users/qiaopengjun/Code/Solidity/Uniswap-v2-08/broadcast/WETH9.s.sol/560048/run-latest.json

Sensitive values saved to: /Users/qiaopengjun/Code/Solidity/Uniswap-v2-08/cache/WETH9.s.sol/560048/run-latest.json

WETH 合约地址:0x55Ab36d5Ba138478445D31D4d1A316E5D3662F17

https://hoodi.etherscan.io/address/0x55ab36d5ba138478445d31d4d1a316e5d3662f17#code

第三步:部署 UniswapV2Router02 合约

Uniswap-v2-08 on  main [✘!?] on 🐳 v28.2.2 (orbstack) took 3.0s 
➜ forge build 
[⠒] Compiling...
No files changed, compilation skipped

Uniswap-v2-08 on  main [✘!?] on 🐳 v28.2.2 (orbstack) 
➜ source .env

Uniswap-v2-08 on  main [✘!?] on 🐳 v28.2.2 (orbstack) 
➜ forge script UniswapV2Router02Script --rpc-url $HOODI_RPC_URL --broadcast --verify -vvvvv        
[⠒] Compiling...
No files changed, compilation skipped
Traces:
  [132] UniswapV2Router02Script::setUp()
    └─ ← [Stop]

  [4317533] UniswapV2Router02Script::run()
    ├─ [0] VM::envAddress("UNISWAPV2FACTORY") [staticcall]
    │   └─ ← [Return] <env var value>
    ├─ [0] VM::envAddress("WETH9") [staticcall]
    │   └─ ← [Return] <env var value>
    ├─ [0] VM::envUint("PRIVATE_KEY") [staticcall]
    │   └─ ← [Return] <env var value>
    ├─ [0] VM::addr(<pk>) [staticcall]
    │   └─ ← [Return] 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5
    ├─ [0] console::log("Deploying contracts with the account:", 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5) [staticcall]
    │   └─ ← [Stop]
    ├─ [0] VM::startBroadcast(<pk>)
    │   └─ ← [Return]
    ├─ [4259571] → new UniswapV2Router02@0x9aB453917cfaEee2B9020537703D30B14f0FDfBa
    │   └─ ← [Return] 21269 bytes of code
    ├─ [0] console::log("UniswapV2Router02 deployed to: ", UniswapV2Router02: [0x9aB453917cfaEee2B9020537703D30B14f0FDfBa]) [staticcall]
    │   └─ ← [Stop]
    ├─ [0] console::log(UniswapV2Router02: [0x9aB453917cfaEee2B9020537703D30B14f0FDfBa]) [staticcall]
    │   └─ ← [Stop]
    ├─ [0] VM::toString(0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5) [staticcall]
    │   └─ ← [Return] "0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5"
    ├─ [0] VM::toString(UniswapV2Router02: [0x9aB453917cfaEee2B9020537703D30B14f0FDfBa]) [staticcall]
    │   └─ ← [Return] "0x9aB453917cfaEee2B9020537703D30B14f0FDfBa"
    ├─ [0] VM::toString(0x79D86a83bFe89eC1dc5F65021f8F66A50Cc443CC) [staticcall]
    │   └─ ← [Return] "0x79D86a83bFe89eC1dc5F65021f8F66A50Cc443CC"
    ├─ [0] VM::toString(0x55Ab36d5Ba138478445D31D4d1A316E5D3662F17) [staticcall]
    │   └─ ← [Return] "0x55Ab36d5Ba138478445D31D4d1A316E5D3662F17"
    ├─ [0] VM::writeJson("{\"deployerAddress\": \"0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5\", \"UniswapV2Router02\": \"0x9aB453917cfaEee2B9020537703D30B14f0FDfBa\", \"UniswapV2Factory\": \"0x79D86a83bFe89eC1dc5F65021f8F66A50Cc443CC\", \"WETH9\": \"0x55Ab36d5Ba138478445D31D4d1A316E5D3662F17\"}", "./deployments/UniswapV2Router02.json")
    │   └─ ← [Return]
    ├─ [0] VM::stopBroadcast()
    │   └─ ← [Return]
    └─ ← [Return]


Script ran successfully.

== Logs ==
  Deploying contracts with the account: 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5
  UniswapV2Router02 deployed to:  0x9aB453917cfaEee2B9020537703D30B14f0FDfBa
  0x9aB453917cfaEee2B9020537703D30B14f0FDfBa

## Setting up 1 EVM.
==========================
Simulated On-chain Traces:

  [4259571] → new UniswapV2Router02@0x9aB453917cfaEee2B9020537703D30B14f0FDfBa
    └─ ← [Return] 21269 bytes of code


==========================

Chain 560048

Estimated gas price: 1.954785257 gwei

Estimated total gas used for script: 6041694

Estimated amount required: 0.011810214358505358 ETH

==========================

##### hoodi
[Success] Hash: 0x932e42cc2f7e8d3ac913c1f2b0742a4e7462da7705c4c08bfcc75e2da2dc890b
Contract Address: 0x9aB453917cfaEee2B9020537703D30B14f0FDfBa
Block: 587280
Paid: 0.005271399471257286 ETH (4647457 gas * 1.134254598 gwei)

✅ Sequence #1 on hoodi | Total Paid: 0.005271399471257286 ETH (4647457 gas * avg 1.134254598 gwei)
                                                                                                                                                                           

==========================

ONCHAIN EXECUTION COMPLETE & SUCCESSFUL.
##
Start verification for (1) contracts
Start verifying contract `0x9aB453917cfaEee2B9020537703D30B14f0FDfBa` deployed on hoodi
EVM version: cancun
Compiler version: 0.8.30
Optimizations:    200
Constructor args: 00000000000000000000000079d86a83bfe89ec1dc5f65021f8f66a50cc443cc00000000000000000000000055ab36d5ba138478445d31d4d1a316e5d3662f17

Submitting verification for [src/UniswapV2Router02.sol:UniswapV2Router02] 0x9aB453917cfaEee2B9020537703D30B14f0FDfBa.
Submitted contract for verification:
        Response: `OK`
        GUID: `bxgxe8jezxazpf8p17vxbn1ghfk3wfwlr2tkyxwwcx4pph8bcv`
        URL: https://hoodi.etherscan.io/address/0x9ab453917cfaeee2b9020537703d30b14f0fdfba
Contract verification status:
Response: `NOTOK`
Details: `Pending in queue`
Warning: Verification is still pending...; waiting 15 seconds before trying again (7 tries remaining)
Contract verification status:
Response: `OK`
Details: `Pass - Verified`
Contract successfully verified
All (1) contracts were verified!

Transactions saved to: /Users/qiaopengjun/Code/Solidity/Uniswap-v2-08/broadcast/UniswapV2Router02.s.sol/560048/run-latest.json

Sensitive values saved to: /Users/qiaopengjun/Code/Solidity/Uniswap-v2-08/cache/UniswapV2Router02.s.sol/560048/run-latest.json

UniswapV2Router02 合约地址:0x9aB453917cfaEee2B9020537703D30B14f0FDfBa

https://hoodi.etherscan.io/address/0x9ab453917cfaeee2b9020537703d30b14f0fdfba#code

第四步:部署 Multicall 合约

Uniswap-v2-08 on  main [!] on 🐳 v28.2.2 (orbstack) took 6.1s 
➜ forge build                                                 
[⠒] Compiling...
[⠃] Compiling 3 files with Solc 0.8.30
[⠊] Solc 0.8.30 finished in 743.59ms
Compiler run successful!

Uniswap-v2-08 on  main [!?] on 🐳 v28.2.2 (orbstack) 
➜ source .env       

Uniswap-v2-08 on  main [!?] on 🐳 v28.2.2 (orbstack) 
➜ forge script MulticallScript --rpc-url $HOODI_RPC_URL --broadcast --verify -vvvvv        
[⠒] Compiling...
No files changed, compilation skipped
Traces:
  [132] MulticallScript::setUp()
    └─ ← [Stop]

  [285769] MulticallScript::run()
    ├─ [0] VM::envUint("PRIVATE_KEY") [staticcall]
    │   └─ ← [Return] <env var value>
    ├─ [0] VM::addr(<pk>) [staticcall]
    │   └─ ← [Return] 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5
    ├─ [0] console::log("Deploying contracts with the account:", 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5) [staticcall]
    │   └─ ← [Stop]
    ├─ [0] VM::startBroadcast(<pk>)
    │   └─ ← [Return]
    ├─ [237082] → new Multicall@0x40a973af60308BEd36964D554A5c644173bc3CbA
    │   └─ ← [Return] 1184 bytes of code
    ├─ [0] console::log("Multicall deployed to:", Multicall: [0x40a973af60308BEd36964D554A5c644173bc3CbA]) [staticcall]
    │   └─ ← [Stop]
    ├─ [0] VM::toString(0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5) [staticcall]
    │   └─ ← [Return] "0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5"
    ├─ [0] VM::toString(Multicall: [0x40a973af60308BEd36964D554A5c644173bc3CbA]) [staticcall]
    │   └─ ← [Return] "0x40a973af60308BEd36964D554A5c644173bc3CbA"
    ├─ [0] VM::writeJson("{\"deployerAddress\": \"0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5\", \"Multicall\": \"0x40a973af60308BEd36964D554A5c644173bc3CbA\"}", "./deployments/Multicall.json")
    │   └─ ← [Return]
    ├─ [0] VM::stopBroadcast()
    │   └─ ← [Return]
    └─ ← [Return]


Script ran successfully.

== Logs ==
  Deploying contracts with the account: 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5
  Multicall deployed to: 0x40a973af60308BEd36964D554A5c644173bc3CbA

## Setting up 1 EVM.
==========================
Simulated On-chain Traces:

  [237082] → new Multicall@0x40a973af60308BEd36964D554A5c644173bc3CbA
    └─ ← [Return] 1184 bytes of code


==========================

Chain 560048

Estimated gas price: 2.231091742 gwei

Estimated total gas used for script: 401811

Estimated amount required: 0.000896477203944762 ETH

==========================

##### hoodi
[Success] Hash: 0x0f9bc647032f267e3c54ab2ae154e509bc6054bf2986388ad4d8ca9c4fe3d33a
Contract Address: 0x40a973af60308BEd36964D554A5c644173bc3CbA
Block: 626316
Paid: 0.000349097648801688 ETH (309086 gas * 1.129451508 gwei)

✅ Sequence #1 on hoodi | Total Paid: 0.000349097648801688 ETH (309086 gas * avg 1.129451508 gwei)
                                                                                                                                              

==========================

ONCHAIN EXECUTION COMPLETE & SUCCESSFUL.
##
Start verification for (1) contracts
Start verifying contract `0x40a973af60308BEd36964D554A5c644173bc3CbA` deployed on hoodi
EVM version: cancun
Compiler version: 0.8.30
Optimizations:    200

Submitting verification for [src/Multicall.sol:Multicall] 0x40a973af60308BEd36964D554A5c644173bc3CbA.
Warning: Could not detect the deployment.; waiting 5 seconds before trying again (4 tries remaining)

Submitting verification for [src/Multicall.sol:Multicall] 0x40a973af60308BEd36964D554A5c644173bc3CbA.
Warning: Could not detect the deployment.; waiting 5 seconds before trying again (3 tries remaining)

Submitting verification for [src/Multicall.sol:Multicall] 0x40a973af60308BEd36964D554A5c644173bc3CbA.
Warning: Could not detect the deployment.; waiting 5 seconds before trying again (2 tries remaining)

Submitting verification for [src/Multicall.sol:Multicall] 0x40a973af60308BEd36964D554A5c644173bc3CbA.
Submitted contract for verification:
        Response: `OK`
        GUID: `ytfkfh78ub4tjl1csntxnu3b93gqjyyfk3fudh8s4ni7r6r6fb`
        URL: https://hoodi.etherscan.io/address/0x40a973af60308bed36964d554a5c644173bc3cba
Contract verification status:
Response: `NOTOK`
Details: `Pending in queue`
Warning: Verification is still pending...; waiting 15 seconds before trying again (7 tries remaining)
Contract verification status:
Response: `OK`
Details: `Pass - Verified`
Contract successfully verified
All (1) contracts were verified!

Transactions saved to: /Users/qiaopengjun/Code/Solidity/Uniswap-v2-08/broadcast/Multicall.s.sol/560048/run-latest.json

Sensitive values saved to: /Users/qiaopengjun/Code/Solidity/Uniswap-v2-08/cache/Multicall.s.sol/560048/run-latest.json

https://hoodi.etherscan.io/address/0x40a973af60308bed36964d554a5c644173bc3cba

https://hoodi.etherscan.io/address/0x40a973af60308bed36964d554a5c644173bc3cba#code

Multicall 合约地址:0x40a973af60308BEd36964D554A5c644173bc3CbA

第五步:部署 AToken 合约

Uniswap-v2-08 on  main [!?] on 🐳 v28.2.2 (orbstack) took 10.2s 
➜ forge build
[⠒] Compiling...
No files changed, compilation skipped

Uniswap-v2-08 on  main [!?] on 🐳 v28.2.2 (orbstack) 
➜ source .env

Uniswap-v2-08 on  main [!?] on 🐳 v28.2.2 (orbstack) 
➜ forge script ATokenScript --rpc-url $HOODI_RPC_URL --broadcast --verify -vvvvv                   
[⠒] Compiling...
No files changed, compilation skipped
Traces:
  [132] ATokenScript::setUp()
    └─ ← [Stop]

  [1152221] ATokenScript::run()
    ├─ [0] VM::envUint("PRIVATE_KEY") [staticcall]
    │   └─ ← [Return] <env var value>
    ├─ [0] VM::addr(<pk>) [staticcall]
    │   └─ ← [Return] 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5
    ├─ [0] console::log("Deploying contracts with the account:", 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5) [staticcall]
    │   └─ ← [Stop]
    ├─ [0] VM::startBroadcast(<pk>)
    │   └─ ← [Return]
    ├─ [1101942] → new AToken@0x5371f1c3410971A4551EbC9F04Fa0210eBCcF620
    │   ├─ emit OwnershipTransferred(previousOwner: 0x0000000000000000000000000000000000000000, newOwner: 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5)
    │   └─ ← [Return] 5153 bytes of code
    ├─ [0] console::log("AToken deployed to:", AToken: [0x5371f1c3410971A4551EbC9F04Fa0210eBCcF620]) [staticcall]
    │   └─ ← [Stop]
    ├─ [0] VM::toString(0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5) [staticcall]
    │   └─ ← [Return] "0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5"
    ├─ [0] VM::toString(AToken: [0x5371f1c3410971A4551EbC9F04Fa0210eBCcF620]) [staticcall]
    │   └─ ← [Return] "0x5371f1c3410971A4551EbC9F04Fa0210eBCcF620"
    ├─ [0] VM::writeJson("{\"deployerAddress\": \"0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5\", \"AToken\": \"0x5371f1c3410971A4551EbC9F04Fa0210eBCcF620\"}", "./deployments/AToken.json")
    │   └─ ← [Return]
    ├─ [0] VM::stopBroadcast()
    │   └─ ← [Return]
    └─ ← [Return]


Script ran successfully.

== Logs ==
  Deploying contracts with the account: 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5
  AToken deployed to: 0x5371f1c3410971A4551EbC9F04Fa0210eBCcF620

## Setting up 1 EVM.
==========================
Simulated On-chain Traces:

  [1101942] → new AToken@0x5371f1c3410971A4551EbC9F04Fa0210eBCcF620
    ├─ emit OwnershipTransferred(previousOwner: 0x0000000000000000000000000000000000000000, newOwner: 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5)
    └─ ← [Return] 5153 bytes of code


==========================

Chain 560048

Estimated gas price: 1.903985052 gwei

Estimated total gas used for script: 1646221

Estimated amount required: 0.003134380176288492 ETH

==========================

##### hoodi
[Success] Hash: 0x4516ac0c913dcf4a008a4806adfc0887f397a7e2164387aa69c34669f4b01c5b
Contract Address: 0x5371f1c3410971A4551EbC9F04Fa0210eBCcF620
Block: 593259
Paid: 0.001398408954341412 ETH (1266324 gas * 1.104305813 gwei)

✅ Sequence #1 on hoodi | Total Paid: 0.001398408954341412 ETH (1266324 gas * avg 1.104305813 gwei)
                                                                                                                                                                           

==========================

ONCHAIN EXECUTION COMPLETE & SUCCESSFUL.
##
Start verification for (1) contracts
Start verifying contract `0x5371f1c3410971A4551EbC9F04Fa0210eBCcF620` deployed on hoodi
EVM version: cancun
Compiler version: 0.8.30
Optimizations:    200
Constructor args: 000000000000000000000000e91e2df7ce50bca5310b7238f6b1dfcd15566be5

Submitting verification for [src/AToken.sol:AToken] 0x5371f1c3410971A4551EbC9F04Fa0210eBCcF620.
Warning: Could not detect the deployment.; waiting 5 seconds before trying again (4 tries remaining)

Submitting verification for [src/AToken.sol:AToken] 0x5371f1c3410971A4551EbC9F04Fa0210eBCcF620.
Warning: Could not detect the deployment.; waiting 5 seconds before trying again (3 tries remaining)

Submitting verification for [src/AToken.sol:AToken] 0x5371f1c3410971A4551EbC9F04Fa0210eBCcF620.
Submitted contract for verification:
        Response: `OK`
        GUID: `tv1qdrzmphul1ftp9qdx2ievw3vufekvshvtsnw6byfaqnwhaf`
        URL: https://hoodi.etherscan.io/address/0x5371f1c3410971a4551ebc9f04fa0210ebccf620
Contract verification status:
Response: `NOTOK`
Details: `Pending in queue`
Warning: Verification is still pending...; waiting 15 seconds before trying again (7 tries remaining)
Contract verification status:
Response: `OK`
Details: `Pass - Verified`
Contract successfully verified
All (1) contracts were verified!

Transactions saved to: /Users/qiaopengjun/Code/Solidity/Uniswap-v2-08/broadcast/AToken.s.sol/560048/run-latest.json

Sensitive values saved to: /Users/qiaopengjun/Code/Solidity/Uniswap-v2-08/cache/AToken.s.sol/560048/run-latest.json

https://hoodi.etherscan.io/address/0x5371f1c3410971a4551ebc9f04fa0210ebccf620#code

AToken 合约地址:0x5371f1c3410971A4551EbC9F04Fa0210eBCcF620

第六步:部署 BToken 合约

Uniswap-v2-08 on  main [!?] on 🐳 v28.2.2 (orbstack) took 58.7s 
➜ forge build                                                                           
[⠒] Compiling...
No files changed, compilation skipped

Uniswap-v2-08 on  main [!?] on 🐳 v28.2.2 (orbstack) 
➜ source .env                                                                           

Uniswap-v2-08 on  main [!?] on 🐳 v28.2.2 (orbstack) 
➜ forge script BTokenScript --rpc-url $HOODI_RPC_URL --broadcast --verify -vvvvv        
[⠒] Compiling...
No files changed, compilation skipped
Traces:
  [132] BTokenScript::setUp()
    └─ ← [Stop]

  [1152221] BTokenScript::run()
    ├─ [0] VM::envUint("PRIVATE_KEY") [staticcall]
    │   └─ ← [Return] <env var value>
    ├─ [0] VM::addr(<pk>) [staticcall]
    │   └─ ← [Return] 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5
    ├─ [0] console::log("Deploying contracts with the account:", 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5) [staticcall]
    │   └─ ← [Stop]
    ├─ [0] VM::startBroadcast(<pk>)
    │   └─ ← [Return]
    ├─ [1101942] → new BToken@0x7AD0921D80CeFC98889a84B960c74866A452Cc2A
    │   ├─ emit OwnershipTransferred(previousOwner: 0x0000000000000000000000000000000000000000, newOwner: 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5)
    │   └─ ← [Return] 5153 bytes of code
    ├─ [0] console::log("BToken deployed to:", BToken: [0x7AD0921D80CeFC98889a84B960c74866A452Cc2A]) [staticcall]
    │   └─ ← [Stop]
    ├─ [0] VM::toString(0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5) [staticcall]
    │   └─ ← [Return] "0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5"
    ├─ [0] VM::toString(BToken: [0x7AD0921D80CeFC98889a84B960c74866A452Cc2A]) [staticcall]
    │   └─ ← [Return] "0x7AD0921D80CeFC98889a84B960c74866A452Cc2A"
    ├─ [0] VM::writeJson("{\"deployerAddress\": \"0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5\", \"BToken\": \"0x7AD0921D80CeFC98889a84B960c74866A452Cc2A\"}", "./deployments/BToken.json")
    │   └─ ← [Return]
    ├─ [0] VM::stopBroadcast()
    │   └─ ← [Return]
    └─ ← [Return]


Script ran successfully.

== Logs ==
  Deploying contracts with the account: 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5
  BToken deployed to: 0x7AD0921D80CeFC98889a84B960c74866A452Cc2A

## Setting up 1 EVM.
==========================
Simulated On-chain Traces:

  [1101942] → new BToken@0x7AD0921D80CeFC98889a84B960c74866A452Cc2A
    ├─ emit OwnershipTransferred(previousOwner: 0x0000000000000000000000000000000000000000, newOwner: 0xE91e2DF7cE50BCA5310b7238F6B1Dfcd15566bE5)
    └─ ← [Return] 5153 bytes of code


==========================

Chain 560048

Estimated gas price: 2.046896987 gwei

Estimated total gas used for script: 1646221

Estimated amount required: 0.003369644804836127 ETH

==========================

##### hoodi
[Success] Hash: 0x4fa2c222d775fc257ec948aa043c533a11bc15320337287d31abf1af75c5a1e8
Contract Address: 0x7AD0921D80CeFC98889a84B960c74866A452Cc2A
Block: 593309
Paid: 0.001443162207066036 ETH (1266324 gas * 1.139646889 gwei)

✅ Sequence #1 on hoodi | Total Paid: 0.001443162207066036 ETH (1266324 gas * avg 1.139646889 gwei)
                                                                                                                                                                           

==========================

ONCHAIN EXECUTION COMPLETE & SUCCESSFUL.
##
Start verification for (1) contracts
Start verifying contract `0x7AD0921D80CeFC98889a84B960c74866A452Cc2A` deployed on hoodi
EVM version: cancun
Compiler version: 0.8.30
Optimizations:    200
Constructor args: 000000000000000000000000e91e2df7ce50bca5310b7238f6b1dfcd15566be5

Submitting verification for [src/BToken.sol:BToken] 0x7AD0921D80CeFC98889a84B960c74866A452Cc2A.
Submitted contract for verification:
        Response: `OK`
        GUID: `iuipdbhwuam6ykxxtikzxmtyk3d4fz7ejzkrn3ujcntnj6svds`
        URL: https://hoodi.etherscan.io/address/0x7ad0921d80cefc98889a84b960c74866a452cc2a
Contract verification status:
Response: `NOTOK`
Details: `Pending in queue`
Warning: Verification is still pending...; waiting 15 seconds before trying again (7 tries remaining)
Contract verification status:
Response: `OK`
Details: `Pass - Verified`
Contract successfully verified
All (1) contracts were verified!

Transactions saved to: /Users/qiaopengjun/Code/Solidity/Uniswap-v2-08/broadcast/BToken.s.sol/560048/run-latest.json

Sensitive values saved to: /Users/qiaopengjun/Code/Solidity/Uniswap-v2-08/cache/BToken.s.sol/560048/run-latest.json

https://hoodi.etherscan.io/address/0x7ad0921d80cefc98889a84b960c74866a452cc2a#code

BToken 合约地址:0x7AD0921D80CeFC98889a84B960c74866A452Cc2A

第七步:添加流动性

一、approve

AToken : https://hoodi.etherscan.io/tx/0xd303f1ed4441fea65dc978edaf505c7b4c58354f8ee7fd28f9c4d47bebcc4753

BToken: https://hoodi.etherscan.io/tx/0x883ca598e6541e3bb02ff6866db907c8022d9b73454caa585060d28491f95b5c

二、添加流动性

https://hoodi.etherscan.io/tx/0x779e949796640f8b916296d578c5772fd03e78dedaca8fa5a3718b3ac5a47fde

https://hoodi.etherscan.io/tx/0x82c3aa88fb8fed3765b39802f5298b049cf831baa786e631a24cd151c6cc1f30

源码参考

https://github.com/qiaopengjun5162/Uniswap-v2-08

总结

本教程带你轻松在 Hoodi 测试网部署 Uniswap V2 核心合约(Factory、Router02、WETH9 等)及 AToken、BToken,基于 Solidity 0.8.30,全程验证通过!通过清晰步骤和源码(GitHub: **https://github.com/qiaopengjun5162/Uniswap-v2-08**),你可快速复现流程,掌握 DeFi 合约开发技能。立即动手实践,加入 Web3 开发浪潮,打造你的去中心化交易所!

参考