golang验证Etherscan上的智能合约

文章目录

  • golang验证Etherscan上的智能合约
    • 为什么要验证智能合约
    • 如何使用golang去验证合约
    • 获取EtherscanAPI密钥
    • Verify Source Code接口
    • Check Source Code Verification Status接口
    • 演示示例及注意事项
    • 网络问题无法调用Etherscan接口(最重要的步骤)

golang验证Etherscan上的智能合约

在阅读此文章前,您需要掌握一定的基础知识,如golang与以太坊交互-CSDN博客,此篇文章是对其的补充,提供利用代码自动验证智能合约,减少不太必要的人工操作,如果由于Etherscan接口的更新,导致代码不适用,请随时与我联系。

为什么要验证智能合约

出于多种原因,您可能希望在公共区块浏览器上开源(验证)您的智能合约。

在Etherscan或其他类似的区块链浏览器上验证智能合约具有以下几个重要的用途:

  1. 透明度和信任:通过验证智能合约,你向社区展示了你的合约代码是公开的、可审查的。这增加了用户和其他开发者对你项目的信任,因为他们可以查看代码,确认合约行为的逻辑和功能。
  2. 安全性审查:验证后的智能合约会吸引更多人的关注,特别是智能合约专家和安全研究人员。他们可以帮助发现潜在的安全漏洞或问题,并提供改进建议。这有助于提升你的合约的安全性和可靠性。
  3. 抵抗黑客攻击:通过让更多人审查你的合约代码,可以提前发现和修复可能存在的漏洞,从而降低黑客攻击的风险。黑客往往会寻找未经审查或有漏洞的智能合约来进行攻击,而经过验证的合约能够减少这种风险。
  4. 开发者社区增长:开源并验证的智能合约能够鼓励更多开发者参与到你的项目中来。他们可以基于你的代码进行二次开发、添加新功能或者将你的合约作为基础构建新的应用程序,从而推动生态系统的发展和扩展。

总结来说,通过在Etherscan上验证智能合约,你不仅增加了透明度和安全性,还能吸引更多开发者和用户参与到你的区块链项目中来,推动项目的发展和采纳。

如何使用golang去验证合约

如果你是通过在线工具如Remix或OpenZeppelin的合约向导部署了你的合约,请考虑使用合约验证页面进行验证。Verify & Publish Contract Source Code | Etherscan

如果你是通过开发工具如Hardhat、Foundry、Truffle等部署了你的合约,请考虑使用插件来自动化验证过程。Contract Verification Plugins | Etherscan

如果你是一名使用golang去开发Web3应用的开发者或学习者,我们可以查看Etherscan提供的api接口,然后根据需要,自己造轮子。Contracts | Etherscan

这里我们找到验证合约所必要的两个api接口,Verify Source Code和Check Source Code Verification Status,意如其名,一个是将合约源代码提交给类似 Etherscan 的浏览器进行验证,一个是返回合同验证请求的成功或错误状态。

只要这两个接口都返回成功,我们的智能合约就已经在Etherscan上进行了验证。

获取EtherscanAPI密钥

注册登录->仪表盘->API-KEYs->Add->copy,具体请看链接Getting an API key | Etherscan。

Verify Source Code接口

将合约源代码提交给类似 Etherscan 的浏览器进行验证。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

根据官方提供的api接口详情,我们可以造出以下的代码,但是略有不同,上面表单中没有提供OptimizationUsed这个参数(0没有,1有),但是我在使用postman测试的时候,得到必须添加这个参数的结果,此外,这个接口必须使用POST请求,尽管它更像是GET请求,没有Body,只有Params。

package utilsimport ("encoding/json""fmt""io""math/big""net/http""net/url""reflect"
)type VerifyRequest struct {ApiKey               string   `json:"apiKey"`                          // API密钥ChainId              *big.Int `json:"chainId"`                         // 链IDCodeFormat           string   `json:"codeformat"`                      // 代码格式SourceCode           string   `json:"sourceCode"`                      // 合约源代码ConstructorArguments string   `json:"constructorArguements,omitempty"` // 构造函数参数ContractAddress      string   `json:"contractaddress"`                 // 合约地址ContractName         string   `json:"contractname"`                    // 合约名称CompilerVersion      string   `json:"compilerversion"`                 // 编译器版本OptimizationUsed     int      `json:"OptimizationUsed"`                // 是否使用了优化
}type VerifyResponse struct {Status  string `json:"status"`  // 状态Message string `json:"message"` // 详细信息Result  string `json:"result"`  // 具体结果
}func Verify(apiKey string, chainId *big.Int, codeFormat, sourceCode, constructorArgs, contractAddress, contractName, compilerVersion string, optimizationUsed int) error {// 构造请求数据requestData := VerifyRequest{ApiKey:               apiKey,ChainId:              chainId,CodeFormat:           codeFormat,SourceCode:           sourceCode,ConstructorArguments: constructorArgs,ContractAddress:      contractAddress,ContractName:         contractName,CompilerVersion:      compilerVersion,OptimizationUsed:     optimizationUsed,}// 创建一个 Client 实例client := &http.Client{}// 准备查询参数params := url.Values{}// 使用反射获取requestData结构体中的字段和值val := reflect.ValueOf(requestData)// 如果是指针类型,则获取其指向的值if val.Kind() == reflect.Ptr {val = val.Elem()}for i := 0; i < val.NumField(); i++ {field := val.Type().Field(i)value := val.Field(i).Interface()// 获取标签的值tag := field.Tag.Get("json")if tag == "" {// 如果没有标签,默认使用字段名tag = field.Name}// 将字段名和值添加到查询参数中params.Set(tag, fmt.Sprint(value))}// 构建POST请求的URLapiURL := "https://api.etherscan.io/api?module=contract&action=verifysourcecode&" + params.Encode()// 创建POST请求req, err := http.NewRequest("POST", apiURL, nil)if err != nil {return fmt.Errorf("创建POST请求失败:%v", err)}// 发送POST请求到Etherscan APIresp, err := client.Do(req)if err != nil {return fmt.Errorf("POST请求失败:%v", err)}defer resp.Body.Close()// 读取响应体body, err := io.ReadAll(resp.Body)if err != nil {return fmt.Errorf("读取响应体失败:%v", err)}// 解析JSON响应var verifyResponse VerifyResponseerr = json.Unmarshal(body, &verifyResponse)if err != nil {return fmt.Errorf("解析JSON响应失败:%v", err)}// 检查验证提交状态if verifyResponse.Status != "1" {return fmt.Errorf("验证提交失败:%s,%s\n", verifyResponse.Message, verifyResponse.Result)}fmt.Printf("验证提交成功:%s,%s\n", verifyResponse.Message, verifyResponse.Result)return nil
}

其实在这里,也可以把verifyResponse.Result返回出去,因为接下来的检查验证会用到它。总之根据自己所需,可以随意更改函数形式,代码的灵活性和趣味性不尽也如此了吧。

参数列表:

参数类型描述举例
apiKeystringEtherscan的Api密钥,注册账户免费获取**********************************
chainId*big.Int提交验证的,例如主网1big.NewInt(int64(11155111))
codeFormatstring单个文件,使用solidity-single-file、使用JSON文件solidity-standard-json-inputsolidity-single-file
sourceCodestringSolidity 源代码// SPDX-License-Identifier……
constructorArgsstring可选,如果合约使用构造函数参数,则包括nil
contractAddressstring您的合约部署地址0x****************************************
contractNamestring合同的名称,例如contracts/Verified.sol:VerifiedVerified
compilerVersionstring使用的编译器版本,例如v0.8.26+commit.8a97fa7av0.8.26+commit.8a97fa7a
optimizationUsedint是否使用了优化,否0,是10

补充:

获取solc编译器版本:打开cmd,输入

solc --version

在这里插入图片描述

Check Source Code Verification Status接口

返回合同验证请求的成功或错误状态。

在这里插入图片描述

在这里插入图片描述

这个接口相对于上一个,就好写很多,只是简单的一个GET请求,我们很容易地写出以下代码。

package utilsimport ("encoding/json""fmt""io""net/http"
)type CheckVerificationStatusRequest struct {ApiKey string `json:"apiKey"` // API密钥Guid   string `json:"guid"`   // 从验证请求收到的唯一值
}type CheckVerificationStatusResponse struct {Status  string `json:"status"`  // 状态Message string `json:"message"` // 详细信息Result  string `json:"result"`  // 具体结果
}func CheckVerificationStatus(apiKey, guid string) error {requestData := CheckVerificationStatusRequest{ApiKey: apiKey,Guid:   guid,}// 创建一个 Client 实例client := &http.Client{}// 构建GET请求的URLapiURL := "https://api.etherscan.io/api?module=contract&action=checkverifystatus&guid=" + requestData.Guid + "&apikey=" + requestData.ApiKey// 创建GET请求req, err := http.NewRequest("GET", apiURL, nil)if err != nil {return fmt.Errorf("创建GET请求失败:%v", err)}// 发送GET请求到Etherscan APIresp, err := client.Do(req)if err != nil {return fmt.Errorf("GET请求失败:%v", err)}defer resp.Body.Close()// 读取响应体body, err := io.ReadAll(resp.Body)if err != nil {return fmt.Errorf("读取响应体失败:%v", err)}// 解析JSON响应var checkVerificationStatusResponse CheckVerificationStatusResponseerr = json.Unmarshal(body, &checkVerificationStatusResponse)if err != nil {return fmt.Errorf("解析JSON响应失败:%v", err)}// 检查验证状态if checkVerificationStatusResponse.Status != "1" {return fmt.Errorf("验证失败:%s,%s\n", checkVerificationStatusResponse.Message, checkVerificationStatusResponse.Result)}fmt.Printf("验证成功:%s,%s\n", checkVerificationStatusResponse.Message, checkVerificationStatusResponse.Result)return nil
}

通过这个函数,我们可以查询我们提交的验证是否已经通过了。

参数列表:

参数类型描述举例
apiKeystringEtherscan的Api密钥,注册账户免费获取**********************************
guidstring从验证请求收到的唯一值guidpdresyk3uidtwtcn5qxp3gqyp4ifsughl9hr8xdt3t2iw7acug

演示示例及注意事项

然后我用我在上一篇博客,也就是文章最开始的链接中的这个样例合约(已经部署在Sepolia上,但未进行验证),进行演示。

下面是调用Verify()函数的过程,(注意,因为网络问题,所以我对这个函数进行了小小的修改,所以叫VerifyZh()函数,后面会进行说明的),然后我们得到返回的guid标识。

在这里插入图片描述

接着,下面是调用CheckVerificationStatus()函数的过程,(注意,因为网络问题,所以我对这个函数进行了小小的修改,所以叫CheckVerificationStatusZh()函数,后面会进行说明的),然后我们看到我们的验证已经完成了!

在这里插入图片描述

当然也有可能失败,因为验证是需要排队的,等待一段时间,再次查询就好了。

在这里插入图片描述

然后打开Etherscan,查看我们的合约,可以看到它的Contract上多了一个√,我们点击后,就可以看到我们合约的源代码以及其他信息了。

在这里插入图片描述

在这里插入图片描述

注意

无法验证合约,有很多原因,请根据报错信息自行摸索,或者在下方留言。

此外Etherscan很聪明,如果别人已经验证过一个合约,然后你部署了跟他一模一样的字节码,就可能导致你部署的合约不用验证,就已经验证了。

网络问题无法调用Etherscan接口(最重要的步骤)

打开魔法软件面板,点击设置,查看代理端口。

在这里插入图片描述

或者,打开windows设置,点击网络和Internet->代理->手动设置代理服务器->编辑,查看端口。

在这里插入图片描述

然后将之前的代码中的如下代码

	// 创建一个 Client 实例client := &http.Client{}

替换为(注意端口号!!!)

	// 创建一个自定义的 Transport 实例transport := &http.Transport{Proxy: func(req *http.Request) (*url.URL, error) {return url.Parse("http://127.0.0.1:7897") // 设置代理(注意端口号!!!)},}// 创建一个自定义的 Client 实例client := &http.Client{Transport: transport, // 设置 Transport}

就可以了,我的加了Zh的函数就是修改了这段代码。

上述方法适用于大部分因网络问题,无法调用第三方api接口的问题。

这篇文章到这里就结束了,希望对您有所帮助,欢迎点赞、评论加收藏,您的支持是对我最大的帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/42670.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

归并排序的实现(递归与非递归)

概念 基本思想&#xff1a;归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide andConquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使…

揭秘Conda:Python开发者必备的包管理神器

conda 简介 Conda 是一个开源的包管理系统和环境管理系统&#xff0c;用于安装和管理软件包以及创建和维护不同的软件环境。 它最初是为 Python 语言设计的&#xff0c;但现在已经支持多种编程语言&#xff0c;包括 R、Ruby、Lua、Scala 等。 1、Anaconda&#xff1a;是一个…

GPIO配置-PIN_Speed的理解

在使用STM32的GPIO 口配置时&#xff0c;经常会疑惑应该选用什么样的配置模式&#xff0c;本文谈谈对pin_speed的理解。 根据数据手册可得&#xff0c;STM32提供10MHz,2MHz和50MHz三种输出速度的配置&#xff0c;三种配置的应用场景是怎么样的&#xff1f;。 1.为什么要配置引…

[护网训练]原创应急响应靶机整理集合

前言 目前已经出了很多应急响应靶机了&#xff0c;有意愿的时间&#xff0c;或者正在准备国护的师傅&#xff0c;可以尝试着做一做已知的应急响应靶机。 关于后期&#xff1a; 后期的应急响应会偏向拓扑化&#xff0c;不再是单单一台机器&#xff0c;也会慢慢完善整体制度。…

论文辅助笔记:ST-LLM

1 时间嵌入 2 PFA&#xff08;Partial Frozen Architecture&#xff09; 3 ST_LLM 3.1 初始化 3.2 forward

强化学习中的Double DQN、Dueling DQN和PER DQN算法详解及实战

1. 深度Q网络&#xff08;DQN&#xff09;回顾 DQN通过神经网络近似状态-动作值函数&#xff08;Q函数&#xff09;&#xff0c;在训练过程中使用经验回放&#xff08;Experience Replay&#xff09;和固定目标网络&#xff08;Fixed Target Network&#xff09;来稳定训练过程…

科大讯飞-群聊对话角色要素提取:不微调范式模拟官网评分

不微调范式模拟官网评分 step1: 模型api配置及加载测试step2: 数据加载与数据分析&#xff1a;测试集分析:step3: prompt设计:step4 :大模型推理&#xff1a;step 5: 结果评分测试&#xff1a;评分细则&#xff1a;评估指标 参考&#xff1a; 比赛说明&#xff1a; #AI夏令营 #…

AI与编程:一个学生的心路历程与思考

前言 大家好&#xff0c;本人是在一个在校的大学生&#xff0c;方向是前端语言。爱好是码代码和看一点小新闻&#xff0c;游戏也是喜爱的。其实本篇文章的想法是源于网上一些人对AI以及对前端的看法&#xff0c;看完网上的评论后我也是有感而发。本篇文章的讨论中心也是围绕着A…

Java项目:基于SSM框架实现的智慧城市实验室管理系统分前后台【ssm+B/S架构+源码+数据库+毕业论文】

一、项目简介 本项目是一套基于SSM框架实现的智慧城市实验室管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单…

Http Json参数到x-www-form-urlencoded参数的在线转换工具

Json参数到x-www-form-urlencoded参数的在线转换工具

算法:[动态规划] 斐波那契数列模型

目录 题目一&#xff1a;第 N 个泰波那契数 题目二&#xff1a;三步问题 题目三&#xff1a;最小花费爬楼梯 题目四&#xff1a;解码方法 题目一&#xff1a;第 N 个泰波那契数 泰波那契序列 Tn 定义如下&#xff1a; T0 0, T1 1, T2 1, 且在 n > 0 的条件下 Tn3 …

用vue2+elementUI封装手机端选择器picker组件,支持单选、多选、远程搜索多选

单选注意点&#xff1a; touchmove.prevent: 在 touchmove 事件上添加 .prevent 修饰符&#xff0c;以阻止默认的滚动行为。 handleTouchStart: 记录触摸开始的 Y 坐标和当前的 translateY 值。 handleTouchMove: 计算触摸移动的距离&#xff0c;并更新 translateY 值。 han…

ImportError: DLL load failed while importing _imaging: 操作系统无法运行 %1

解决方案&#xff1a; &#xff08;1&#xff09;搜索打开Anaconda Prompt控制台&#xff0c;进入到自己要安装的环境下面去&#xff0c;卸载Pillow:pip uninstall Pillow 没有安装Pillow的就不用卸载&#xff0c;直接安装&#xff0c; &#xff08;2&#xff09;然后再安装&a…

芯片封装简介

1、背景 所谓“封装技术”是一种将集成电路用绝缘的塑料或陶瓷材料打包的技术。以CPU为例&#xff0c;实际看到的体积和外观并不是真正的CPU内核的大小和面貌&#xff0c;而是CPU内核等元件经过封装后的产品。封装技术对于芯片来说是必须的&#xff0c;也是至关重要的。因为芯片…

Koa2实现多并发文件上传

koa2批量上传文件 目前的是为了实现批量导入md文件&#xff0c;发布文章。这样就不用自己一篇一篇同步文章了。一次可以同步几千篇文章。 实现界面 内容 主要包含上传的文件标题&#xff0c;文件大小&#xff0c;上传状态。 <el-upload ref"uploader" v-model:…

【Java12】封装

封装&#xff08;Encapsulation&#xff09;是面向对象的三大特征之一&#xff08;另两个是继承和多态&#xff09;&#xff0c;指的是将对象的状态信息隐藏在对象内部&#xff0c;不允许外部程序直接访问对象的内部信息&#xff0c;而是通过该类所提供的方法来实现对内部信息的…

找不到x3daudio1_7.dll怎么修复?一招搞定x3daudio1_7.dll丢失问题

当你的电脑突然弹出提示&#xff0c;“找不到x3daudio1_7.dll”&#xff0c;这时候你就需要警惕了。这往往意味着你的电脑中的程序出现了问题&#xff0c;你可能会发现自己无法打开程序&#xff0c;或者即便打开了程序也无法正常使用。因此&#xff0c;接下来我们要一起学习一下…

[数据结构] --- 线性数据结构(数组/链表/栈/队列)

1 线性结构和非线性结构的理解 1.1 线性结构 线性结构是什么&#xff1f; 数据结构中线性结构指的是数据元素之间存在着“一对一”的线性关系的数据结构。线性结构是一个有序数据元素的集合。 线性结构特点&#xff1a; 线性结构有唯一的首元素&#xff08;第一个元素&#…

leetcode力扣_贪心思想

455.分发饼干&#xff08;easy-自己想得出来并写好&#xff09; 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺…

【CUDA】

笔者在学习Softmax实现时遇到了一个问题&#xff0c;很多文章直接将softmax的计算分成了五个过程&#xff0c;而没有解释每个过程的含义&#xff0c;尤其是在阅读这篇文章时&#xff0c;作者想计算最基本的softmax的效率&#xff0c;以展示可行的优化空间&#xff1a; 贴一个g…