diff --git a/docs/pages/cn/how-to/verify-contract.mdx b/docs/pages/cn/how-to/verify-contract.mdx index 9e32d1f..7059f1a 100644 --- a/docs/pages/cn/how-to/verify-contract.mdx +++ b/docs/pages/cn/how-to/verify-contract.mdx @@ -1,6 +1,6 @@ --- source_path: how-to/verify-contract.mdx -source_sha: 6cc73e10bb88685960bc61fa08f4942073bc61bc +source_sha: 203fffb80a0e333188b0fc2122787d3ff82df9d9 title: "验证智能合约" description: "使用 forge verify-contract 在 Stablescan 上验证您的 Stable 合约源代码,以便用户可以读取和与其交互。" diataxis: "how-to" @@ -8,17 +8,29 @@ diataxis: "how-to" # 验证智能合约 -验证会将您的合约源代码上传到区块浏览器,并证明其编译为已部署的字节码。验证后,用户无需重新托管您的代码,即可在 Stablescan 上读取状态、调用函数和审计源代码。本指南将介绍如何在 Stable 上验证 Foundry 部署的合约。 +验证会将您的合约源代码上传到区块浏览器,并证明其编译为已部署的字节码。一旦验证,用户可以在 Stablescan 上读取状态、调用函数和审计源代码,而无需重新托管您的代码。本指南将介绍如何在 Stable 上验证 Foundry 部署的合约。 -## 先决条件 +Stablescan 在 Etherscan 的多链 (V2) API 上运行,因此验证和所有其他浏览器 API 调用都将发送到 `https://api.etherscan.io/v2/api` 并带有 `chainid` 参数: -- 已在 Stable 测试网或主网上部署的合约。如果您尚未部署,请参阅[部署智能合约](/cn/tutorial/smart-contract)。 -- 已安装 Foundry(`forge` 在您的 PATH 中可用)。 -- 来自 `forge create` 输出的已部署合约地址。 +| **网络** | **链 ID** | **验证器 URL** | +| :-------------- | :----------- | :--------------------------------------------- | +| Stable 测试网 | `2201` | `https://api.etherscan.io/v2/api?chainid=2201` | +| Stable 主网 | `988` | `https://api.etherscan.io/v2/api?chainid=988` | -## 1. 确认已部署地址 +:::warning +Stablescan 不提供自己的 API。对 `https://testnet.stablescan.xyz/api` 的请求返回 `{"status":"0","message":"NOTOK","result":"Invalid API URL endpoint"}`,浏览器会被重定向到 `/notavailable`。请改用上面提供的 Etherscan V2 URL。 +::: + +## 前提条件 + +- 已经在 Stable 测试网或主网部署的合约。如果您尚未部署,请参阅[部署智能合约](/cn/tutorial/smart-contract)。 +- 已安装 Foundry(`forge` 在您的 PATH 中可用)。如果 `--verifier custom` 未被识别,请运行 `foundryup`。 +- 您 `forge create` 输出中的已部署合约地址。 +- 来自 [https://etherscan.io/myapikey](https://etherscan.io/myapikey) 的 Etherscan API 密钥。一个密钥涵盖 V2 API 上的所有链,包括两个 Stable 网络。 + +## 1. 确认已部署的地址 -确保您拥有之前部署的“部署到”地址。在[部署智能合约](/cn/tutorial/smart-contract)流程中,这是 `forge create` 后打印的值。 +请确保您拥有之前部署的 `Deployed to` 地址。在[部署智能合约](/cn/tutorial/smart-contract)流程中,这是在 `forge create` 后打印的值。 ```bash cast code 0xDeployedContractAddress --rpc-url https://rpc.testnet.stable.xyz | head -c 20 @@ -30,41 +42,57 @@ cast code 0xDeployedContractAddress --rpc-url https://rpc.testnet.stable.xyz | h 非空字节码确认合约已部署在该地址。 -## 2. 运行 forge verify-contract +## 2. 导出您的 API 密钥 + +Foundry 和 `curl` 都从您的 shell 读取密钥,因此请一次性导出。 + +```bash +export ETHERSCAN_API_KEY=YourApiKey + +curl "https://api.etherscan.io/v2/api?chainid=2201&module=account&action=balance&address=0xDeployedContractAddress&tag=latest&apikey=$ETHERSCAN_API_KEY" +``` + +```text +{"status":"1","message":"OK","result":"0"} +``` + +`"status":"1"` 响应确认密钥在 Stable 测试网上可用。如果您收到 `Missing/Invalid API Key`,则密钥未设置或尚未激活。 + +## 3. 运行 forge verify-contract -Foundry 的验证流程将您的源代码提交给 Stablescan 验证器。 +将 Foundry 指向链 `2201` 的 Etherscan V2 端点。 ```bash forge verify-contract \ 0xDeployedContractAddress \ src/Counter.sol:Counter \ --chain-id 2201 \ - --verifier blockscout \ - --verifier-url https://testnet.stablescan.xyz/api \ + --verifier custom \ + --verifier-url "https://api.etherscan.io/v2/api?chainid=2201" \ + --verifier-api-key $ETHERSCAN_API_KEY \ --watch ``` ```text Start verifying contract `0xDeployedContractAddress` deployed on 2201 -Submitting verification of contract: Counter +Submitting verification for [src/Counter.sol:Counter] 0xDeployedContractAddress. Submitted contract for verification: Response: `OK` GUID: `abc123...` - URL: https://testnet.stablescan.xyz/address/0xDeployedContractAddress Contract verification status: Response: `OK` Details: `Pass - Verified` Contract successfully verified ``` -`--watch` 会一直阻塞直到验证完成,这样您就不需要轮询。在主网上,将链 ID 更改为 `988`,验证器 URL 更改为 `https://stablescan.xyz/api`。 +`--watch` 会阻塞直到验证完成,这样您就不必轮询了。在主网上,将链 ID 切换到 `988`,验证器 URL 切换到 `https://api.etherscan.io/v2/api?chainid=988`。 :::note -**构造函数参数**:如果您的合约接受构造函数参数,请将 `--constructor-args $(cast abi-encode "constructor(uint256,address)" 42 0xSomeAddress)` 添加到命令中。如果没有此标志,任何带有非空构造函数的合约都将验证失败。 +**构造函数参数**:如果您的合约带有构造函数参数,请在命令中添加 `--constructor-args $(cast abi-encode "constructor(uint256,address)" 42 0xSomeAddress)`。如果没有此标志,任何带有非空构造函数的合约验证都将失败。 ::: -## 3. 在 Stablescan 上确认验证 +## 4. 在 Stablescan 上确认验证 在浏览器上打开合约页面。 @@ -72,12 +100,14 @@ Contract successfully verified https://testnet.stablescan.xyz/address/0xDeployedContractAddress ``` -**合约**选项卡现在应该显示源代码,一个绿色的“已验证”徽章,以及完整的 ABI。用户可以在**读取合约**下读取状态,并在**写入合约**下发送交易。 +**Contract** 选项卡现在应该显示源代码、一个绿色的“已验证”徽章和完整的 ABI。用户可以在 **Read Contract** 下读取状态,在 **Write Contract** 下发送交易。 ## 故障排除 -- **“字节码不匹配”**:您的源代码编译成与已部署代码不同的字节码。这通常是由于 Solidity 版本或优化器设置不匹配造成的。明确传递 `--compiler-version` 和 `--optimizer-runs` 以匹配您的 `foundry.toml`。 -- **“GU ID 未找到”**:验证器尚未注册您的提交。使用 `--watch` 重新运行或手动检查响应中打印的 URL。 +- **“Invalid API URL endpoint”**:您正在直接调用浏览器主机。将 `https://testnet.stablescan.xyz/api` 替换为 `https://api.etherscan.io/v2/api?chainid=2201`。 +- **“Missing/Invalid API Key”**:`ETHERSCAN_API_KEY` 在当前 shell 中未设置,或者密钥刚刚创建且尚未激活。重新运行步骤 2 中的 `curl` 检查。 +- **“Bytecode does not match”**:您的源代码编译为与已部署的字节码不同的字节码。最常见的原因是 Solidity 版本或优化器设置不匹配。明确传递 `--compiler-version` 和 `--optimizer-runs` 以匹配您的 `foundry.toml`。 +- **“GUID not found”**:验证器尚未注册您的提交。使用 `--watch` 重新运行或手动检查响应中打印的 URL。 - **合约使用库**:为每个链接的库添加 `--libraries src/Lib.sol:Lib:0xDeployedLibAddress`。 ## 下一步推荐 diff --git a/docs/pages/en/how-to/verify-contract.mdx b/docs/pages/en/how-to/verify-contract.mdx index 6cc73e1..203fffb 100755 --- a/docs/pages/en/how-to/verify-contract.mdx +++ b/docs/pages/en/how-to/verify-contract.mdx @@ -8,11 +8,23 @@ diataxis: "how-to" Verification uploads your contract's source code to the block explorer and proves it compiles to the deployed bytecode. Once verified, users can read state, call functions, and audit the source on Stablescan without re-hosting your code. This guide walks through verifying a Foundry-deployed contract on Stable. +Stablescan runs on Etherscan's multichain (V2) API, so verification and every other explorer API call go to `https://api.etherscan.io/v2/api` with a `chainid` parameter: + +| **Network** | **Chain ID** | **Verifier URL** | +| :------------- | :----------- | :---------------------------------------------- | +| Stable testnet | `2201` | `https://api.etherscan.io/v2/api?chainid=2201` | +| Stable mainnet | `988` | `https://api.etherscan.io/v2/api?chainid=988` | + +:::warning +Stablescan does not serve an API of its own. Requests to `https://testnet.stablescan.xyz/api` return `{"status":"0","message":"NOTOK","result":"Invalid API URL endpoint"}`, and a browser is redirected to `/notavailable`. Use the Etherscan V2 URLs above instead. +::: + ## Prerequisites - A contract already deployed on Stable testnet or mainnet. If you haven't deployed yet, see [Deploy a smart contract](/en/tutorial/smart-contract). -- Foundry installed (`forge` available in your PATH). +- Foundry installed (`forge` available in your PATH). Run `foundryup` if `--verifier custom` is not recognized. - The deployed contract address from your `forge create` output. +- An Etherscan API key from [https://etherscan.io/myapikey](https://etherscan.io/myapikey). One key covers every chain on the V2 API, including both Stable networks. ## 1. Confirm the deployed address @@ -28,41 +40,57 @@ cast code 0xDeployedContractAddress --rpc-url https://rpc.testnet.stable.xyz | h A non-empty bytecode confirms the contract is deployed at that address. -## 2. Run forge verify-contract +## 2. Export your API key + +Foundry and `curl` both read the key from your shell, so export it once. + +```bash +export ETHERSCAN_API_KEY=YourApiKey + +curl "https://api.etherscan.io/v2/api?chainid=2201&module=account&action=balance&address=0xDeployedContractAddress&tag=latest&apikey=$ETHERSCAN_API_KEY" +``` + +```text +{"status":"1","message":"OK","result":"0"} +``` + +A `"status":"1"` response confirms the key works against Stable testnet. If you get `Missing/Invalid API Key`, the key is unset or not yet active. + +## 3. Run forge verify-contract -Foundry's verification flow submits your source to the Stablescan verifier. +Point Foundry at the Etherscan V2 endpoint for chain `2201`. ```bash forge verify-contract \ 0xDeployedContractAddress \ src/Counter.sol:Counter \ --chain-id 2201 \ - --verifier blockscout \ - --verifier-url https://testnet.stablescan.xyz/api \ + --verifier custom \ + --verifier-url "https://api.etherscan.io/v2/api?chainid=2201" \ + --verifier-api-key $ETHERSCAN_API_KEY \ --watch ``` ```text Start verifying contract `0xDeployedContractAddress` deployed on 2201 -Submitting verification of contract: Counter +Submitting verification for [src/Counter.sol:Counter] 0xDeployedContractAddress. Submitted contract for verification: Response: `OK` GUID: `abc123...` - URL: https://testnet.stablescan.xyz/address/0xDeployedContractAddress Contract verification status: Response: `OK` Details: `Pass - Verified` Contract successfully verified ``` -`--watch` blocks until verification finishes so you don't have to poll. On mainnet, swap the chain ID to `988` and the verifier URL to `https://stablescan.xyz/api`. +`--watch` blocks until verification finishes so you don't have to poll. On mainnet, swap the chain ID to `988` and the verifier URL to `https://api.etherscan.io/v2/api?chainid=988`. :::note **Constructor arguments**: If your contract takes constructor arguments, add `--constructor-args $(cast abi-encode "constructor(uint256,address)" 42 0xSomeAddress)` to the command. Without this flag, verification fails for any contract with a non-empty constructor. ::: -## 3. Confirm verification on Stablescan +## 4. Confirm verification on Stablescan Open the contract page on the explorer. @@ -74,6 +102,8 @@ The **Contract** tab should now show source code, a green "Verified" badge, and ## Troubleshooting +- **"Invalid API URL endpoint"**: you're calling the explorer host directly. Replace `https://testnet.stablescan.xyz/api` with `https://api.etherscan.io/v2/api?chainid=2201`. +- **"Missing/Invalid API Key"**: `ETHERSCAN_API_KEY` is unset in the current shell, or the key was just created and isn't active yet. Re-run the `curl` check in step 2. - **"Bytecode does not match"**: your source compiles to different bytecode than what's deployed. Most often caused by mismatched Solidity version or optimizer settings. Pass `--compiler-version` and `--optimizer-runs` explicitly to match your `foundry.toml`. - **"GUID not found"**: the verifier hasn't registered your submission yet. Re-run with `--watch` or manually check the URL printed in the response. - **Contract uses libraries**: add `--libraries src/Lib.sol:Lib:0xDeployedLibAddress` for each linked library. diff --git a/docs/pages/ko/how-to/verify-contract.mdx b/docs/pages/ko/how-to/verify-contract.mdx index 4cb4337..0bbecc4 100644 --- a/docs/pages/ko/how-to/verify-contract.mdx +++ b/docs/pages/ko/how-to/verify-contract.mdx @@ -1,24 +1,36 @@ --- source_path: how-to/verify-contract.mdx -source_sha: 6cc73e10bb88685960bc61fa08f4942073bc61bc +source_sha: 203fffb80a0e333188b0fc2122787d3ff82df9d9 title: "스마트 컨트랙트 검증" -description: "forge verify-contract를 사용하여 Stablescan에서 Stable 컨트랙트 소스를 검증하여 사용자가 코드를 읽고 상호작용할 수 있도록 합니다." +description: "사용자가 읽고 상호 작용할 수 있도록 forge verify-contract를 사용하여 Stablescan에서 Stable 컨트랙트 소스를 검증하세요." diataxis: "how-to" --- # 스마트 컨트랙트 검증 -검증은 컨트랙트의 소스 코드를 블록 탐색기에 업로드하고 배포된 바이트코드로 컴파일되었음을 증명합니다. 일단 검증되면, 사용자는 코드를 다시 호스팅할 필요 없이 Stablescan에서 상태를 읽고, 함수를 호출하고, 소스를 감사할 수 있습니다. 이 가이드는 Stable에 배포된 Foundry 컨트랙트를 검증하는 과정을 안내합니다. +검증은 컨트랙트의 소스 코드를 블록 탐색기에 업로드하고 배포된 바이트코드로 컴파일되었음을 증명합니다. 검증되면 사용자는 코드를 다시 호스팅할 필요 없이 Stablescan에서 상태를 읽고, 함수를 호출하고, 소스를 감사할 수 있습니다. 이 가이드는 Foundry에 배포된 컨트랙트를 Stable에서 검증하는 과정을 안내합니다. + +Stablescan은 Etherscan의 멀티체인(V2) API에서 실행되므로, 검증 및 기타 모든 탐색기 API 호출은 `chainid` 매개변수와 함께 `https://api.etherscan.io/v2/api`로 전송됩니다. + +| **네트워크** | **체인 ID** | **검증기 URL** | +| :--------------- | :----------- | :--------------------------------------------- | +| Stable 테스트넷 | `2201` | `https://api.etherscan.io/v2/api?chainid=2201` | +| Stable 메인넷 | `988` | `https://api.etherscan.io/v2/api?chainid=988` | + +:::warning +Stablescan은 자체 API를 제공하지 않습니다. `https://testnet.stablescan.xyz/api`로의 요청은 `{"status":"0","message":"NOTOK","result":"Invalid API URL endpoint"}`를 반환하고, 브라우저는 `/notavailable`로 리디렉션됩니다. 대신 위에 명시된 Etherscan V2 URL을 사용하십시오. +::: ## 전제 조건 -- Stable 테스트넷 또는 메인넷에 이미 배포된 컨트랙트. 아직 배포하지 않았다면, [스마트 컨트랙트 배포](/ko/tutorial/smart-contract)를 참조하세요. -- Foundry 설치 (`forge`가 PATH에 있어야 함). +- Stable 테스트넷 또는 메인넷에 이미 배포된 컨트랙트. 아직 배포하지 않았다면, [스마트 컨트랙트 배포](/ko/tutorial/smart-contract)를 참조하십시오. +- Foundry가 설치되어 있어야 합니다 (`forge`가 PATH에 있어야 합니다). `--verifier custom`이 인식되지 않으면 `foundryup`을 실행하십시오. - `forge create` 출력에서 얻은 배포된 컨트랙트 주소. +- [https://etherscan.io/myapikey](https://etherscan.io/myapikey)에서 얻은 Etherscan API 키. 하나의 키로 Stable 네트워크를 포함한 V2 API의 모든 체인을 커버할 수 있습니다. ## 1. 배포된 주소 확인 -이전 배포에서 얻은 `Deployed to` 주소를 확인하세요. [스마트 컨트랙트 배포](/ko/tutorial/smart-contract) 흐름에서 이는 `forge create` 이후에 출력된 값이었습니다. +이전 배포에서 얻은 `Deployed to` 주소를 가지고 있는지 확인하세요. [스마트 컨트랙트 배포](/ko/tutorial/smart-contract) 흐름에서 이 값은 `forge create` 후 출력된 값이었습니다. ```bash cast code 0xDeployedContractAddress --rpc-url https://rpc.testnet.stable.xyz | head -c 20 @@ -30,41 +42,57 @@ cast code 0xDeployedContractAddress --rpc-url https://rpc.testnet.stable.xyz | h 비어 있지 않은 바이트코드는 해당 주소에 컨트랙트가 배포되었음을 확인합니다. -## 2. forge verify-contract 실행 +## 2. API 키 내보내기 + +Foundry와 `curl`은 모두 셸에서 키를 읽으므로 한 번 내보냅니다. + +```bash +export ETHERSCAN_API_KEY=YourApiKey + +curl "https://api.etherscan.io/v2/api?chainid=2201&module=account&action=balance&address=0xDeployedContractAddress&tag=latest&apikey=$ETHERSCAN_API_KEY" +``` + +```text +{"status":"1","message":"OK","result":"0"} +``` + +`"status":"1"` 응답은 키가 Stable 테스트넷에서 작동함을 확인합니다. `Missing/Invalid API Key`가 발생하면 키가 설정되지 않았거나 아직 활성화되지 않은 것입니다. + +## 3. forge verify-contract 실행 -Foundry의 검증 흐름은 소스를 Stablescan 검증기에 제출합니다. +Foundry를 체인 `2201`의 Etherscan V2 엔드포인트로 지정합니다. ```bash forge verify-contract \ 0xDeployedContractAddress \ src/Counter.sol:Counter \ --chain-id 2201 \ - --verifier blockscout \ - --verifier-url https://testnet.stablescan.xyz/api \ + --verifier custom \ + --verifier-url "https://api.etherscan.io/v2/api?chainid=2201" \ + --verifier-api-key $ETHERSCAN_API_KEY \ --watch ``` ```text -2201에 배포된 컨트랙트 `0xDeployedContractAddress` 검증 시작 +Start verifying contract `0xDeployedContractAddress` deployed on 2201 -컨트랙트 검증 제출: Counter -검증을 위해 제출된 컨트랙트: - 응답: `OK` +Submitting verification for [src/Counter.sol:Counter] 0xDeployedContractAddress. +Submitted contract for verification: + Response: `OK` GUID: `abc123...` - URL: https://testnet.stablescan.xyz/address/0xDeployedContractAddress -컨트랙트 검증 상태: -응답: `OK` -세부 정보: `Pass - Verified` -컨트랙트가 성공적으로 검증되었습니다. +Contract verification status: +Response: `OK` +Details: `Pass - Verified` +Contract successfully verified ``` -`--watch`는 검증이 완료될 때까지 블록을 유지하므로 폴링할 필요가 없습니다. 메인넷에서는 체인 ID를 `988`로, 검증기 URL을 `https://stablescan.xyz/api`로 변경하세요. +`--watch`는 검증이 완료될 때까지 차단하므로 폴링할 필요가 없습니다. 메인넷에서는 체인 ID를 `988`로, 검증기 URL을 `https://api.etherscan.io/v2/api?chainid=988`로 변경합니다. :::note -**생성자 인수**: 컨트랙트가 생성자 인수를 사용하는 경우, `--constructor-args $(cast abi-encode "constructor(uint256,address)" 42 0xSomeAddress)`를 명령에 추가하세요. 이 플래그가 없으면 비어 있지 않은 생성자를 가진 모든 컨트랙트에 대한 검증이 실패합니다. +**생성자 인수**: 컨트랙트가 생성자 인수를 받는 경우, `--constructor-args $(cast abi-encode "constructor(uint256,address)" 42 0xSomeAddress)`를 명령에 추가하십시오. 이 플래그가 없으면 비어 있지 않은 생성자를 가진 모든 컨트랙트에 대한 검증이 실패합니다. ::: -## 3. Stablescan에서 검증 확인 +## 4. Stablescan에서 검증 확인 탐색기에서 컨트랙트 페이지를 엽니다. @@ -72,13 +100,15 @@ forge verify-contract \ https://testnet.stablescan.xyz/address/0xDeployedContractAddress ``` -이제 **Contract** 탭에 소스 코드, 녹색 "Verified" 배지 및 전체 ABI가 표시되어야 합니다. 사용자는 **Read Contract**에서 상태를 읽고 **Write Contract**에서 트랜잭션을 보낼 수 있습니다. +**Contract** 탭에 이제 소스 코드, 녹색 "Verified" 배지, 전체 ABI가 표시되어야 합니다. 사용자는 **Read Contract**에서 상태를 읽고 **Write Contract**에서 트랜잭션을 보낼 수 있습니다. ## 문제 해결 -- **"바이트코드가 일치하지 않습니다"**: 소스가 배포된 바이트코드와 다르게 컴파일됩니다. 가장 흔한 원인은 솔리디티 버전 또는 최적화 프로그램 설정 불일치입니다. `foundry.toml`과 일치하도록 `--compiler-version` 및 `--optimizer-runs`를 명시적으로 전달하세요. -- **"GUID를 찾을 수 없습니다"**: 검증기가 아직 제출을 등록하지 않았습니다. `--watch`로 다시 실행하거나 응답에 출력된 URL을 수동으로 확인하세요. -- **컨트랙트가 라이브러리를 사용합니다**: 연결된 각 라이브러리에 대해 `--libraries src/Lib.sol:Lib:0xDeployedLibAddress`를 추가하세요. +- **"Invalid API URL endpoint"**: 탐색기 호스트를 직접 호출하고 있습니다. `https://testnet.stablescan.xyz/api`를 `https://api.etherscan.io/v2/api?chainid=2201`로 교체하십시오. +- **"Missing/Invalid API Key"**: `ETHERSCAN_API_KEY`가 현재 셸에 설정되지 않았거나 키가 방금 생성되어 아직 활성화되지 않았습니다. 2단계에서 `curl` 확인을 다시 실행하십시오. +- **"Bytecode does not match"**: 소스가 배포된 바이트코드와 다르게 컴파일됩니다. 대부분 Solidity 버전 또는 옵티마이저 설정 불일치로 인해 발생합니다. `foundry.toml`과 일치하도록 `--compiler-version` 및 `--optimizer-runs`를 명시적으로 전달하십시오. +- **"GUID not found"**: 검증기가 아직 제출을 등록하지 않았습니다. `--watch`로 다시 실행하거나 응답에 출력된 URL을 수동으로 확인하십시오. +- **컨트랙트가 라이브러리를 사용합니다**: 각 연결된 라이브러리에 대해 `--libraries src/Lib.sol:Lib:0xDeployedLibAddress`를 추가하십시오. ## 다음 권장 사항