当前位置: 首页 > news >正文

golang验证Etherscan上的智能合约

文章目录

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

golang验证Etherscan上的智能合约

在阅读此文章前,您需要掌握一定的基础知识,如golang与以太坊交互,此篇文章是对其的补充,提供利用代码自动验证智能合约,减少不太必要的人工操作,如果由于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接口的问题。

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

相关文章:

golang验证Etherscan上的智能合约

文章目录 golang验证Etherscan上的智能合约为什么要验证智能合约如何使用golang去验证合约获取EtherscanAPI密钥Verify Source Code接口Check Source Code Verification Status接口演示示例及注意事项网络问题无法调用Etherscan接口&#xff08;最重要的步骤&#xff09; golan…...

Visual Studio编译优化选项

目录 /O1 和 /O2 /Ox 内联函数 虚函数优化 代码重排 循环优化 链接时间优化 代码分割 数学优化 其他优化选项 在Visual Studio中&#xff0c;编译优化选项是用于提高程序性能的重要工具。编译器提供了多种优化级别和选项&#xff0c;可以根据不同的需要进行选择。 在…...

sql业务场景分析思路参考

1、时间可以进行排序&#xff0c;也可以用聚合函数对时间求最大值max&#xff08;时间&#xff09; 例如下面的例子&#xff1a;取最晚入职的人&#xff0c;那就是将入职时间倒序排序&#xff0c;然后limit 1 表&#xff1a; 场景&#xff1a;查找最晚入职员工的所有信息 se…...

Django权限系统如何使用?

Django的权限系统是一个强大而灵活的特性&#xff0c;允许你控制不同用户对应用程序中资源的访问。以下是使用Django权限系统的几个基本步骤&#xff1a; 1. 定义模型权限 在你的models.py文件中&#xff0c;你可以为每个模型定义自定义权限。这通过在模型的Meta类里设置perm…...

基于整体学习的大幅面超高分遥感影像桥梁目标检测(含数据集下载地址)

文章摘要 在遥感图像&#xff08;RSIs&#xff09;中进行桥梁检测在各种应用中起着至关重要的作用&#xff0c;但与其他对象检测相比&#xff0c;桥梁检测面临独特的挑战。在RSIs中&#xff0c;桥梁在空间尺度和纵横比方面表现出相当大的变化。因此&#xff0c;为了确保桥梁的…...

逻辑回归模型(非回归问题,而是解决二分类问题)

目录&#xff1a; 一、Sigmoid激活函数&#xff1a;二、逻辑回归介绍&#xff1a;三、决策边界四、逻辑回归模型训练过程&#xff1a;1.训练目标&#xff1a;2.梯度下降调整参数&#xff1a; 一、Sigmoid激活函数&#xff1a; Sigmoid函数是构建逻辑回归模型的重要激活函数&am…...

QT的OpenGL渲染窗QOpenGLWidget Class

Qt - QOpenGLWidget (class) (runebook.dev) 一、说明 QOpenGLWidget 类是用于渲染 OpenGL 图形的小部件。从Qt 5.4就开始退出&#xff0c;它对于OpenGL有专门的配合设计。 二、QOpenGLWidget类的成员 2.1 Public类函数 QOpenGLWidget(QWidget *parent nullptr&#xff0c;Qt…...

单元测试和集成测试

软件测试中&#xff0c;单元测试和集成测试是比较常见的方法 单元测试&#xff1a;这是一种专注于最小可测试单元&#xff08;通常是函数或方法&#xff09;的测试&#xff0c;用于验证单个组件的行为是否符合预期。它通常由开发者自己完成&#xff0c;可以尽早发现问题&#…...

【JAVA入门】Day15 - 接口

【JAVA入门】Day15 - 接口 文章目录 【JAVA入门】Day15 - 接口一、接口是对“行为”的抽象二、接口的定义和使用三、接口中成员的特点四、接口和类之间的关系五、接口中新增的方法5.1 JDK8开始接口中新增的方法5.1.1 接口中的默认方法5.1.2 接口中的静态方法 5.2 JDK9 开始接口…...

ES6 之 Set 与 Map 数据结构要点总结(一)

Set 数据结构 Set 对象允许你存储任何类型的唯一值&#xff0c;无论是原始值还是对象引用。 特性&#xff1a; 所有值都是唯一的&#xff0c;没有重复。值的顺序是根据添加的顺序确定的。可以使用迭代器遍历 Set。 常用方法&#xff1a; 1. add(value)&#xff1a;添加一个新…...

一文学会用RKE部署高可用Kubernetes集群

k8s架构图 RKE简介 RKE全称Rancher Kubernetes Engine&#xff0c;是一个快速的&#xff0c;多功能的 Kubernetes 安装工具。通过RKE&#xff0c;我们可以快速的安装一个高可用K8S集群。RKE 支持多种操作系统&#xff0c;包括 MacOS、Linux 和 Windows。 K8S原生安装需要的先…...

数据加密的常见方法

数据加密是一门历史悠久的技术&#xff0c;它通过加密算法和加密密钥将明文(原始的或未加密的数据)转变为密文&#xff0c;而解密则是通过解密算法和解密密钥将密文恢复为明文。这一技术的核心是密码学&#xff0c;它利用密码技术对信息进行加密&#xff0c;实现信息隐蔽&#…...

天童美语:推荐给孩子的人文历史纪录片

孩子们都有自己的偏好&#xff0c;有的孩子喜欢打游戏&#xff0c;有的孩子喜欢看剧看电影&#xff0c;有的孩子喜欢看书。针对不同的孩子我们要因材施教&#xff0c;所以&#xff0c;广州天童教育给大家推荐一下适合给孩子看的人文历史类的纪录片&#xff0c;让精美的画面&…...

数字人技术如何推动教育事业可持续创新发展?

数字人技术作为一种新兴的教育手段&#xff0c;无论是幼儿园还是大学课堂&#xff0c;数字人都可以融入于各阶段教育中&#xff0c;结合动作捕捉、AI等技术&#xff0c;提高教育资源的利用。 AI智能交互数字人应用&#xff1a; 数字人结合NLP自然语言处理技术以及AI大模型技术…...

FPGA程序设计

在设计FPGA时&#xff0c;多运用模块化的思想取设计模块&#xff0c;将某一功能设计成module。 设计之前要先画一下模块设计图&#xff0c;列出输入输出接口&#xff0c;再进一步设计内部功能。 状态机要画图&#xff0c;确定每个状态和状态之间怎么切换。状态用localparam定…...

彻底开源,免费商用,上海AI实验室把大模型门槛打下来

终于&#xff0c;业内迎来了首个全链条大模型开源体系。 大模型领域&#xff0c;有人探索前沿技术&#xff0c;有人在加速落地&#xff0c;也有人正在推动整个社区进步。 就在近日&#xff0c;AI 社区迎来首个统一的全链条贯穿的大模型开源体系。 虽然社区有LLaMA等影响力较大…...

MTEB评估基准使用指北

文章目录 介绍评估数据 介绍 文本嵌入通常是在单一任务的少量数据集上进行评估&#xff0c;这些数据集未涵盖其可能应用于其他任务的情况&#xff0c;不清楚在语义文本相似性&#xff08;semantic textual similarity, STS&#xff09;等任务上的最先进嵌入是否同样适用于聚类或…...

31. 1049. 最后一块石头的重量 II, 494.目标和,474.一和零

class Solution { public:int lastStoneWeightII(vector<int>& stones) {int sum 0;for(int stone : stones) sum stone;int bagSize sum /2;vector<int> dp(bagSize 1, 0);for(int i 0; i < stones.size(); i){ //遍历物品for(int j bagSize; j >…...

PDF 中图表的解析探究

PDF 中图表的解析探究 0. 引言1. 开源方案探究 0. 引言 一直以来&#xff0c;对文档中的图片和表格处理都非常有挑战性。这篇文章记录一下最近工作上在这块的探究。图表分为图片和表格&#xff0c;这篇文章主要记录了对表格的探究。还有&#xff0c;我个人主要做日本项目&…...

递推(C语言)

文章目录 1.斐波那契数列2.太波那契数列3.二维递推问题4.实战4.1 力扣509 斐波那契数4.2 力扣70 爬楼梯4.3 力扣119 杨辉三角|| 递推最通俗的理解就是数列&#xff0c;递推和数列的关系就好比 算法 和 数据结构 的关系&#xff0c;数列有点 像数据结构中的线性表(可以是顺序表&…...

Go语言实现DCI架构:用角色扮演解耦对象行为与数据

1. 从“是什么”到“做什么”&#xff1a;DCI架构如何重塑对象行为建模在面向对象编程的世界里&#xff0c;我们总在试图用代码“复刻”现实。一个“人”是什么&#xff1f;我们定义一个People类&#xff0c;拥有姓名、年龄等属性。这个人能做什么&#xff1f;我们为People类添…...

图片去水印怎么做?2026年最全图片去水印工具推荐与方法盘点

在日常工作和生活中&#xff0c;我们常常会遇到带有水印的图片——无论是社交平台的截图、素材库的图片&#xff0c;还是从各类网站下载的资源。水印虽然保护了原作者的权益&#xff0c;但有时也会影响我们对内容本身的使用。那么&#xff0c;图片去水印有哪些实用方法&#xf…...

React Props:深入解析组件间的数据传递

React Props:深入解析组件间的数据传递 在React中,组件间的数据传递是构建复杂应用的关键。Props(属性)是React组件间数据传递的主要方式,它允许父组件向子组件传递数据。本文将深入探讨React Props的概念、使用方法以及注意事项。 一、Props的概念 Props是React组件的…...

【LeetCode刷题日记】617.合并二叉树(空间换安全,还是原地省内存)

&#x1f525;个人主页&#xff1a;北极的代码&#xff08;欢迎来访&#xff09; &#x1f3ac;作者简介&#xff1a;java后端学习者 ❄️个人专栏&#xff1a;苍穹外卖日记&#xff0c;SSM框架深入&#xff0c;JavaWeb ✨命运的结局尽可永在&#xff0c;不屈的挑战却不可须臾或…...

大模型时代的技术人:要么驾驭AI,要么被AI驾驭——致软件测试从业者

测试者的新分水岭当ChatGPT在2022年底横空出世时&#xff0c;很多人还只是把它当作一个更会聊天的玩具。然而&#xff0c;仅仅数月之后&#xff0c;当GitHub Copilot 开始自动补全测试脚本&#xff0c;当AI能够在几秒钟内生成数十条高覆盖率的测试用例&#xff0c;当一张手绘草…...

2026亲测:专业降AI率工具选这款就对了3秒改写无痕迹

2026 年降 AIGC 工具已从“基础语义替换”进化为多维度智能优化系统&#xff0c;核心评估指标涵盖 AI 痕迹清除效率、专业表达准确性、格式结构完整性、长段落逻辑稳定性、内容重合度降低效果及高校检测平台兼容性。本次测评深入分析 5 款主流工具&#xff0c;测试范围包括中英…...

从排名监控到答案诊断:一个算法工程师眼中的GEO工具技术选型标准

本文从工程师视角&#xff0c;剖析生成式搜索优化中的多模型诊断瓶颈&#xff0c;通过异步调度架构与沙盒隔离策略&#xff0c;实现品牌提及率的精准监控与算力可控消耗&#xff0c;为GEO工具选型提供技术验证依据。 传统监控工具在生成式搜索场景面临三重策略瓶颈&#xff1a;…...

BGA翻新安全的核心风险—热损伤与机械失效底层逻辑

BGA&#xff08;球栅阵列&#xff09;芯片翻新是电子制造业降本增效、资源循环的重要工艺&#xff0c;广泛应用于服务器 CPU、手机基带芯片、车载处理器等高价值元器件修复场景。但 BGA 封装结构精密&#xff0c;焊点隐藏在芯片底部&#xff0c;翻新过程需经历多次高温加热、机…...

焊接型球头杆端关节轴承鱼眼接头缺陷检测数据集VOC+YOLO格式3205张4类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件)图片数量(jpg文件个数)&#xff1a;3205标注数量(xml文件个数)&#xff1a;3205标注数量(txt文件个数)&#xff1a;3205标注类别…...

从NPN到FET:一文看懂LDO内部调整管的演进史,以及如何根据你的项目(IoT、可穿戴、汽车电子)选择最优架构

从NPN到FET&#xff1a;LDO调整管技术演进与选型实战指南 在可穿戴设备的心率传感器突然断电的瞬间&#xff0c;工程师们才意识到选错LDO的代价——这恰恰揭示了调整管架构对系统可靠性的决定性影响。从早期笨重的NPN稳压器到如今纳米级MOSFET LDO&#xff0c;电源管理芯片的进…...