如何判断以太坊地址类型?

如何判断以太坊地址类型?

一、账户类型解释

2.1 以太坊外部账户(Externally Owned Account,EOA)

外部账户(EOA)是由私钥控制的账户,在以太坊网络中用来发送交易和执行其他操作。EOA 不是智能合约,它没有合约代码,只能用于发送交易(例如转账以太币)。其主要特点是:

  • 没有合约代码:外部账户没有部署智能合约的代码。
  • 拥有私钥:外部账户由用户的私钥控制,只有拥有该私钥的人才能签署交易。
  • 交易类型:EOA 发起的交易仅限于转账以太币或调用合约。

外部账户的特征:

  • 账户的地址通常是 0x 开头的 40 个十六进制字符。
  • 它不会有与之相关联的合约代码。

2.2 以太坊合约地址(Contract Account)

合约地址是由智能合约创建的账户,它由合约的代码控制。智能合约是部署在以太坊网络上的可编程代码,可以接受交易、存储数据、执行逻辑等。合约地址的主要特点是:

  • 拥有合约代码:合约地址包含了可执行的合约代码,它允许外部地址调用合约的函数。
  • 由合约代码控制:合约地址不能直接由私钥控制,它由智能合约的代码决定。
  • 交易类型:合约地址通过调用合约函数来执行操作,而不仅仅是进行转账。智能合约可以接收来自外部账户的交易并做出响应。

合约地址的特征:

  • 也以 0x 开头,并且长度为 40 个十六进制字符。
  • 它会与特定的智能合约代码相关联。

关于以太坊账户的详细解读,可以查看:以太坊账户详解

二、地址判断

2.1 判断方法

  1. 检查地址的代码是否存在

在以太坊中,合约地址是有部署在区块链上的智能合约代码的,而普通地址(外部账户)没有代码。

步骤:

  • 使用 eth_getCode RPC 调用来检查一个地址的代码。如果返回的是 0x,表示该地址是一个外部账户(普通地址)。如果返回的是非空的代码,表示该地址是一个合约地址。
curl https://eth.com/ \-X POST \-H "Content-Type: application/json" \--data '{"method":"eth_getCode","params":["0xdac17f958d2ee523a2206206994597c13d831ec7","latest"],"id":1,"jsonrpc":"2.0"}'

例如,若返回 "0x",则说明该地址是一个普通地址。如果返回一个非零的代码(例如:0x606060405260043610610196576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde031461019b5780630753c30c14610229578063095ea7b3146102625780630e136b191),表示这是一个合约地址。

  1. 使用 Etherscan 等区块链浏览器

如果你有地址的相关信息,可以通过访问区块链浏览器(如 Etherscan)查看该地址是否被标记为合约地址。Etherscan 会显示“合约”标签,指示该地址是智能合约地址。

  1. 通过交易历史
  • 普通地址通常只会执行简单的交易(例如转账以太币)。
  • 合约地址会有部署合约或调用合约函数的交易记录。如果通过交易记录可以看到该地址与智能合约的交互(如调用 transfermint 等合约函数),则可以确定该地址是合约地址。
  1. 检查地址的活动

合约地址通常会有复杂的交易活动,如调用函数、创建交易等。而普通地址只是参与普通的转账交易,通常没有其他的复杂行为。可以通过查看该地址的交易历史来做一个大致的判断。

通过这些方法,你可以有效地判断一个以太坊地址是普通地址还是合约地址。

2.2 代码示例

我们将使用第一种检查地址的代码是否存在的方法进行判断,并且使用golang的方法进行测试,以下是我们的代码示例

代码示例

package mainimport ("context""encoding/hex""fmt""github.com/ethereum/go-ethereum/common""github.com/ethereum/go-ethereum/ethclient""log"
)func main() {// 连接到以太坊节点client, err := ethclient.Dial("https://rpc.ankr.com/eth")if err != nil {log.Fatalf("Failed to connect to the Ethereum client: %v", err)}// 需要检查的以太坊地址address := common.HexToAddress("0xdac17f958d2ee523a2206206994597c13d831ec7")// 调用 eth_getCode 来检查地址是否是合约地址code, err := client.CodeAt(context.Background(), address, nil) // 第二个参数为 nil,表示查询最新的状态if err != nil {log.Fatalf("Failed to get code at address: %v", err)}// 将字节码转换为十六进制字符串,并以 '0x' 开头codeHex := "0x" + hex.EncodeToString(code)fmt.Println("code is:", codeHex)// 如果返回的代码为空,说明是普通地址;如果有代码,说明是合约地址if len(code) == 0 {fmt.Println("The address is a regular wallet address (EOA).")} else {fmt.Println("The address is a smart contract address.")}
}

2.3 拓展:数据库中查询

通常,我们可能需要从数据库中获取地址,然后并发判断地址类型,以下是我们的golang代码示例

package mainimport ("context""database/sql""fmt""log""sync""github.com/ethereum/go-ethereum/common""github.com/ethereum/go-ethereum/ethclient"_ "github.com/go-sql-driver/mysql"
)// 检查地址是否为合约地址的函数
func checkIfContract(client *ethclient.Client, address string, wg *sync.WaitGroup, results chan<- string) {defer wg.Done()// 将地址转换为eth的地址格式ethAddress := common.HexToAddress(address)// 查询地址的代码code, err := client.CodeAt(context.Background(), ethAddress, nil)if err != nil {results <- fmt.Sprintf("Error checking address %s: %v", address, err)return}// 判断代码是否为空if len(code) == 0 {results <- fmt.Sprintf("Address %s is a regular wallet address (EOA).", address)} else {results <- fmt.Sprintf("Address %s is a smart contract address.", address)}
}// 从数据库中获取以太坊地址
func getEthereumAddresses(db *sql.DB) ([]string, error) {var addresses []string// 执行查询(假设表名为 'eth_addresses',列名为 'address')rows, err := db.Query("SELECT address FROM eth_addresses")if err != nil {return nil, fmt.Errorf("failed to execute query: %w", err)}defer rows.Close()// 遍历查询结果并将地址加入到切片中for rows.Next() {var address stringif err := rows.Scan(&address); err != nil {return nil, fmt.Errorf("failed to scan row: %w", err)}addresses = append(addresses, address)}// 检查是否有错误发生if err := rows.Err(); err != nil {return nil, fmt.Errorf("error while iterating rows: %w", err)}return addresses, nil
}func main() {// 连接到MySQL数据库,使用连接池dsn := "username:password@tcp(localhost:3306)/your_database_name"db, err := sql.Open("mysql", dsn)if err != nil {log.Fatalf("Failed to connect to the database: %v", err)}defer db.Close()// 检查数据库连接是否可用if err := db.Ping(); err != nil {log.Fatalf("Failed to ping the database: %v", err)}// 获取所有以太坊地址addresses, err := getEthereumAddresses(db)if err != nil {log.Fatalf("Failed to get Ethereum addresses from database: %v", err)}// 连接到以太坊节点(使用Infura或Geth节点)client, err := ethclient.Dial("https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID")if err != nil {log.Fatalf("Failed to connect to the Ethereum client: %v", err)}// 并发查询每个地址var wg sync.WaitGroupresults := make(chan string, len(addresses)) // 设置一个缓冲 channel 来存储结果// 启动多个 goroutine 并发查询for _, address := range addresses {wg.Add(1)go checkIfContract(client, address, &wg, results)}// 等待所有查询完成wg.Wait()close(results)// 打印所有结果for result := range results {fmt.Println(result)}
}

以上代码的优化点;

主要优化点:

  1. 数据库连接池使用:通过 sql.Open 创建数据库连接并使用连接池(db.Ping() 用于确保数据库连接可用)。不需要每次查询时都打开新连接。
  2. 错误处理改进:通过 fmt.Errorf 包装错误信息,使其更具可读性,并提供详细的上下文。
  3. sync.WaitGroupchan 并发控制:这些部分没有变化,但确保 goroutines 的执行是并发的且高效的。
  4. 日志:改进了错误日志,提供更清晰的错误上下文。
  5. CodeAt 查询上下文:确保查询时使用 context.Background(),而不是 nil,保持一致性。
  6. db.Ping():用于检查数据库连接是否正常,防止在查询时出现连接问题。

性能考虑:

  • 使用缓冲通道(results)来存储查询结果,避免了在多个 goroutine 中频繁地发生阻塞。
  • sync.WaitGroup 确保所有的并发任务在程序退出之前都已完成。

这种优化方式使得代码更健壮,易于维护,并提高了处理并发任务时的性能。

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

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

相关文章

二十七、资源限制-LimitRange

LimitRange生产必备 在调度的时候 requests 比较重要,在运行时 limits 比较重要。 一、产生原因 生产中只有ResourceQuota是不够的 只配置ResourceQuotas的情况下,pod的yaml文件没有配置resources配置,都是0的话,就可以无限配置,永远达不到limit LimitRange做了什么 如…

docker部署的gitlab迁移

docker部署的gitlab迁移_docker gitlab 迁移-CSDN博客 gitlab-rake gitlab:backup:restore BACKUP 后面一路yes 生活中总是充满了各种选择&#xff0c;点餐纠结&#xff0c;出行选择&#xff0c;聚餐座位&#xff0c;团队投票结果不明&#xff0c;随机抽签一锤定音等等&#xf…

GS论文阅读--GeoTexDensifier

前言 本文是一个关于高斯致密化策略对高斯地图进行优化&#xff0c;他主要关注了几何结构和纹理信息。我最近对于高斯点的分布比较感兴趣&#xff0c;因为高斯点的分布决定了之后重建质量的好坏&#xff0c;初始化高斯很重要&#xff0c;但之后的维护需要致密化与修建策略&…

支持大功率输出高速频闪的图像处理用光源控制器

机器视觉系统中的光源控制器在确保图像质量、提高系统稳定性、降低能耗以及方便系统扩展和升级等方面发挥着重要作用。它可提供稳定光源&#xff0c;调节参数&#xff0c;另外具有操作便捷性。 下面我们来看Gardasoft的光源控制器&#xff0c;Gardasoft拥有作为图像处理用LED光…

Excel 技巧17 - 如何计算倒计时,以及数据条(★)

本文讲如何计算倒计时&#xff0c;以及加数据条。 1&#xff0c;如何计算倒计时 这里也要用公式 D3 - TODAY() 显示为下面这个样子的 然后右键该单元格&#xff0c;选 设置单元格格式 然后点 常规 这样就能显示出还书倒计时的日数了。 下拉适用到其他单元格。 2&#xff0c;…

springboot整合modbus实现通讯

springboot整合modbus4j实现tcp通讯 前言 本文基于springboot和modbus4j进行简单封装&#xff0c;达到开箱即用的目的&#xff0c;目前本方案仅实现了tcp通讯。代码会放在最后&#xff0c;按照使用方法操作后就可以直接使用 介绍 在使用本方案之前&#xff0c;有必要对modb…

iOS-YModel

YModel 是一个高效的 iOS/OSX 的模型转换框架&#xff0c;可以轻松地将 JSON 转换成 Model&#xff0c;或者将 Model 转换成 JSON。以下是详细的使用指南&#xff1a; 导入 YYModel: 确保在你的项目中导入了 YYModel。使用 CocoaPods 的话可以在 Podfile 中加入以下代码&#…

PhyCAGE:符合物理规律的图像到 3D 生成

Paper: Yan H, Zhang M, Li Y, et al. PhyCAGE: Physically Plausible Compositional 3D Asset Generation from a Single Image[J]. arXiv preprint arXiv:2411.18548, 2024. Introduction: https://wolfball.github.io/phycage/ Code: Unreleased PhyCAGE 是一种 image-to-3D…

麒麟操作系统服务架构保姆级教程(十三)tomcat环境安装以及LNMT架构

如果你想拥有你从未拥有过的东西&#xff0c;那么你必须去做你从未做过的事情 之前咱们学习了LNMP架构&#xff0c;但是PHP对于技术来说确实是老掉牙了&#xff0c;PHP的市场占有量越来越少了&#xff0c;我认识一个10年的PHP开发工程师&#xff0c;十年工资从15k到今天的6k&am…

网站HTTP改成HTTPS

您不仅需要知道如何将HTTP转换为HTTPS&#xff0c;还必须在不妨碍您的网站自成立以来建立的任何搜索排名权限的情况下进行切换。 为什么应该从HTTP转换为HTTPS&#xff1f; 与非安全HTTP于不同&#xff0c;安全域使用SSL&#xff08;安全套接字层&#xff09;服务器上的加密代…

大模型GUI系列论文阅读 DAY1:《基于大型语言模型的图形用户界面智能体:综述》(6.6W 字长文)

摘要 图形用户界面&#xff08;Graphical User Interfaces, GUIs&#xff09;长期以来一直是人机交互的核心&#xff0c;为用户提供了直观且以视觉为驱动的方式来访问和操作数字系统。传统上&#xff0c;GUI交互的自动化依赖于基于脚本或规则的方法&#xff0c;这些方法在固定…

实战经验:使用 Python 的 PyPDF 进行 PDF 操作

文章目录 1. 为什么选择 PyPDF&#xff1f;2. 安装 PyPDF3. PDF 文件的合并与拆分3.1 合并 PDF 文件3.2 拆分 PDF 文件 4. 提取 PDF 文本5. 修改 PDF 元信息6. PDF 加密与解密6.1 加密 PDF6.2 解密 PDF 7. 页面旋转与裁剪7.1 旋转页面7.2 裁剪页面 8. 实战经验总结 PDF 是一种非…

MySQL 安装配置(完整教程)

文章目录 一、MySQL 简介二、下载 MySQL三、安装 MySQL四、配置环境变量五、配置 MySQL5.1 初始化 MySQL5.2 启动 MySQL 服务 六、修改 MySQL 密码七、卸载 MySQL八、结语 一、MySQL 简介 MySQL 是一款广泛使用的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;&#…

PostgreSQL的学习心得和知识总结(一百六十六)|深入理解PostgreSQL数据库之\watch元命令的实现原理

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

当当网书籍信息爬虫

1.基本理论 1.1概念体系 网络爬虫又称网络蜘蛛、网络蚂蚁、网络机器人等&#xff0c;可以按照我们设置的规则自动化爬取网络上的信息&#xff0c;这些规则被称为爬虫算法。是一种自动化程序&#xff0c;用于从互联网上抓取数据。爬虫通过模拟浏览器的行为&#xff0c;访问网页…

计算机网络 (50)两类密码体制

前言 计算机网络中的两类密码体制主要包括对称密钥密码体制&#xff08;也称为私钥密码体制、对称密码体制&#xff09;和公钥密码体制&#xff08;也称为非对称密码体制、公开密钥加密技术&#xff09;。 一、对称密钥密码体制 定义&#xff1a; 对称密钥密码体制是一种传…

【PowerQuery专栏】实现JSON数据的导入

Json 格式数据是在互联网数据格式传输使用的非常频繁的一类数据,图7.44为Json数据格式中比较典型的数据格式。 PowerQuery进行Json数据解析使用的是Json.Document进行数据解析,Json.Document目前有2个参数。 参数1为内容数据,数据类型为二进制类型,值为需要解析的Json数据参…

软件授权管理中的软件激活向导示例

软件激活向导示例 在软件许可中&#xff0c;提供许可应该是简单和安全的。这适用于想要在中央许可证服务器上创建新许可证的软件开发人员&#xff0c;也适用于需要在其设备上获得许可证的最终用户。如果所讨论的系统有互联网连接&#xff0c;或是暂时的连接&#xff0c;就可以…

模型部署工具01:Docker || 用Docker打包模型 Build Once Run Anywhere

Docker 是一个开源的容器化平台&#xff0c;可以让开发者和运维人员轻松构建、发布和运行应用程序。Docker 的核心概念是通过容器技术隔离应用及其依赖项&#xff0c;使得软件在不同的环境中运行时具有一致性。无论是开发环境、测试环境&#xff0c;还是生产环境&#xff0c;Do…

【云岚到家】-day03-门户缓存方案选择

【云岚到家】-day03-门户缓存方案选择 1.门户常用的技术方案 什么是门户 说到门户马上会想到门户网站&#xff0c;中国比较早的门户网站有新浪、网易、搜狐、腾讯等&#xff0c;门户网站为用户提供一个集中的、易于访问的平台&#xff0c;使他们能够方便地获取各种信息和服务…