# 曲折的Smart Contract验证之路

By [Ramondy](https://paragraph.com/@ramondy) · 2023-07-18

---

1\. 合约验证
--------

我们知道在智能合约的部署之后，需要将部署的合约进行验证，并公开给用户查看。这种作为已经成为一个产品上线后的必备操作。

![](https://storage.googleapis.com/papyrus_images/8d6ea8c7c4baf24c0ba1eee90d6bfe4c7f9ac9e47b8ae1a953dae977387be5bc.png)

**1.1 合约验证方法**

#### 1\. 通过区块链浏览器进行验证

这种方式是区块链部署后，进行验证时候，比较通用的验证方式。

![](https://storage.googleapis.com/papyrus_images/58001c2be7b641b8c489bd82dd3206a086861cbd19bc7590fda28f585ea6213d.png)

我们需要选择编译类型： 通常选择为Solidity(Simgle file) 也就是将所有合约导入到一个合约文件中，也称为合约的扁平化处理

开元许可证类型通常选择MIT Licence(MIT)

> 此时我想你一定在头大，难道需要我们自己一个个的将引入的文件复制到一个文件中吗？（这肯定行不通，因为引入的文件通常很多，一不小心还会出错）

> sol-merger : Merges all imports into single file for solidity contracts

上述插件可以实现将引入的合约导入到一个单独的文件中。是不是很方便。

使用方法还是很简单的：

在package.json 配置添加如下代码：

    {
      "scripts": {
        "build-contracts": "sol-merger \"./contracts/*.sol\" ./build"
      }
    }
    

> 注意此时的合约文件夹的位置。我在验证的时候没有**注意合约文件夹的变动**，导致用到了错位的扁平化代码。

![](https://storage.googleapis.com/papyrus_images/e62e30509f71ada4889f54101a42afd5144ed6245ade3794e7d92e258524d9b0.png)

> 在这个过程我们可以将扁平化代码放入2位置。1的位置要根据Hardhat 编译器的配置进行选择。3的constructor Arguments Abi encoded是系统自动填充的我们不需要进行修改。这块的代码其实是我们进行合约部署时候的参数。

如果你仔细看过部署合约的交易时候会发现，在部署合约的时候我们在input data中看到过一串编译过的代码，如下图看到的：

![](https://storage.googleapis.com/papyrus_images/e001da51f2eebf40364fc7fd8061529e87c24b72e00ef750101de3cfa61ed8fe.png)

上图中中的编译代码就是constructor 含参数进行编译后的数据。我们可以用hex 转文本等看到原始的数据信息。而这个编译码的上面就是整个合约信息。

> 记住： 区块链浏览器说： remix编译通过，验证也应该可以，没错的。

如果顺利的话，你的合约已经可以看到代码了。

但是本文的重点并不是在这里，因为我的合约没能够通过验证。接下来我将通过代码演示我在合约合约验证的过程，以及合约验证的另外两种方式。

如果你的合约也验证失败了，希望这篇文章给你带来帮助。

2\. 合约不验证的影响
------------

之所以将这个标题写在这里，是为了警示大家， 告诉大家合格的产品是必须进行合约曝光的。

作为一个合约开发者，如果你讲重要的合约，比如你们公司正在做一款游戏，你们已经部署了一个ERC721合约，并且已经进行了空投和其他的几轮活动，那么此时这个合约必须马上进行公开，因为合约的公开有助于用户了解到你们产品时候存在后门等情况。

如果此时你忘记了部署时候的合约，那么此时可能已经可以“提桶跑路”了。

> 别慌，稳住。上面说的话虽然是真的，但是也是能够进行补救的。

3\. 合约验证标准
----------

能够将这以下的行为操作称为标准，完全是血的教训。

### 3.1 教训一：及时验证

合约的在部署后，尽快的进行验证，我们知道solidity代码进行代码编译过程是不可逆的，也就说能够拿到合约部署时候的编译码，是不能够进行反编译解码成solidity 代码。这一点一定要记住。

如果因为安全性考虑，没有进行合约验证，此时一定要保存代码，最好也保存一份bytecode。（关键时刻救命）

### 3.2 教训二：部署切勿更改任何remix ide中的代码

我们认为在remix进行合约部署，合约修改是很方便的。但是应该知道remix ide基础浏览器缓存。如果删除缓存，你编辑的代码也就不存在了。

假设你的浏览器还保存着数据，但是如果你在remix进行代码的更改没有同步到本地代码中， 那么此时的验证还是不能够通过。

这两种行为都是在合约验证中致命的存在。

### 3.3 教训三： 时刻进行代码的推送

能够救命的操作，肯定是时刻的进行代码的推送，他也是你还原代码的重要依据，但是，前提是一定不要做上述的操作，否则这种代码推送也只会减少一定验证工作量。

### 3.4 教训四：代码存档

在游戏中如果我想要进入别的故事情节，我可以选择不同的存档时间，在Smart contract 中也需要对生产上的代码数据进行存储，并且，一定不要进行其他的代码更改。（包括你认为的存在引入代码重复操作）

4\. 合约验证方式
----------

### 4.1 hardhat 验证

> [https://hardhat.org/hardhat-runner/docs/guides/verifying](https://hardhat.org/hardhat-runner/docs/guides/verifying)

> [https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-verify](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-verify)

步骤

*   安装依赖
    

    npm install --save-dev @nomicfoundation/hardhat-verify
    

*   获取API key 从不同链的浏览器中
    
*   hardhat.config 添加etherscan配置
    

    import "@nomicfoundation/hardhat-verify";
    
    export default {
      // ...rest of the config...
      etherscan: {
        apiKey: "ABCDE12345ABCDE12345ABCDE123456789",
      },
    };
    

*   npx hardhat verify --network sepolia
    
        npx hardhat verify --network polygon 0x80000000000000000000000000000000 "Tearing Spaces: Celestial Armaments" "Armaments" "0x92b62f87b6a09494acbe0eeddd2ec5f02934c7f4" 500
        
    
    4\. 总结
    ------
    
    本文介绍了智能合约在部署后需要进行合约验证的方法，主要包括通过区块链浏览器进行验证、使用sol-merger插件将所有合约导入到一个单独的文件中等方式。同时，提出了在合约验证过程中需要注意的事项，如及时验证、部署时勿更改任何remix ide中的代码、时刻进行代码的推送以及代码存档等。作者强调，合约的公开有助于用户了解到产品存在后门等情况，因此合约的公开是必须进行的。

---

*Originally published on [Ramondy](https://paragraph.com/@ramondy/smart-contract)*
