怎样在网站做链接,官方网站建设账务处理,wordpress的ico,郑州最好的男科医院哪家好文章目录 golang验证Etherscan上的智能合约为什么要验证智能合约如何使用golang去验证合约获取EtherscanAPI密钥Verify Source Code接口Check Source Code Verification Status接口演示示例及注意事项网络问题无法调用Etherscan接口#xff08;最重要的步骤#xff09; golan… 文章目录 golang验证Etherscan上的智能合约为什么要验证智能合约如何使用golang去验证合约获取EtherscanAPI密钥Verify Source Code接口Check Source Code Verification Status接口演示示例及注意事项网络问题无法调用Etherscan接口最重要的步骤 golang验证Etherscan上的智能合约
在阅读此文章前您需要掌握一定的基础知识如golang与以太坊交互此篇文章是对其的补充提供利用代码自动验证智能合约减少不太必要的人工操作如果由于Etherscan接口的更新导致代码不适用请随时与我联系。
为什么要验证智能合约
出于多种原因您可能希望在公共区块浏览器上开源验证您的智能合约。
在Etherscan或其他类似的区块链浏览器上验证智能合约具有以下几个重要的用途
透明度和信任通过验证智能合约你向社区展示了你的合约代码是公开的、可审查的。这增加了用户和其他开发者对你项目的信任因为他们可以查看代码确认合约行为的逻辑和功能。安全性审查验证后的智能合约会吸引更多人的关注特别是智能合约专家和安全研究人员。他们可以帮助发现潜在的安全漏洞或问题并提供改进建议。这有助于提升你的合约的安全性和可靠性。抵抗黑客攻击通过让更多人审查你的合约代码可以提前发现和修复可能存在的漏洞从而降低黑客攻击的风险。黑客往往会寻找未经审查或有漏洞的智能合约来进行攻击而经过验证的合约能够减少这种风险。开发者社区增长开源并验证的智能合约能够鼓励更多开发者参与到你的项目中来。他们可以基于你的代码进行二次开发、添加新功能或者将你的合约作为基础构建新的应用程序从而推动生态系统的发展和扩展。
总结来说通过在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/jsonfmtiomath/bignet/httpnet/urlreflect
)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?modulecontractactionverifysourcecode 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-filesourceCodestringSolidity 源代码// SPDX-License-Identifier……constructorArgsstring可选如果合约使用构造函数参数则包括nilcontractAddressstring您的合约部署地址0x****************************************contractNamestring合同的名称例如contracts/Verified.sol:VerifiedVerifiedcompilerVersionstring使用的编译器版本例如v0.8.26commit.8a97fa7av0.8.26commit.8a97fa7aoptimizationUsedint是否使用了优化否0是10
补充
获取solc编译器版本打开cmd输入
solc --versionCheck Source Code Verification Status接口
返回合同验证请求的成功或错误状态。 这个接口相对于上一个就好写很多只是简单的一个GET请求我们很容易地写出以下代码。
package utilsimport (encoding/jsonfmtionet/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?modulecontractactioncheckverifystatusguid 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接口的问题。
这篇文章到这里就结束了希望对您有所帮助欢迎点赞、评论加收藏您的支持是对我最大的帮助