以太坊账户详解

news2024/12/24 5:42:51

文章目录

  • 一、账户基本概念
    • 1.1 外部账户
    • 1.2 合约账户
    • 1.3 差异对比
  • 二、帐户创建
    • 2.1 外部账户创建
    • 2.2 合约账户创建
  • 三、账户数据结构
    • 3.1 账户状态
    • 3.2 账户状态结构

对比比特币的 “UTXO” 余额模型,以太坊使用“账户”余额模型。 以太坊丰富了账户内容,除余额外还能自定义存放任意多数据。 并利用账户数据的可维护性,构建智能合约账户。

实际上以太坊是为了实现智能合约而提炼的账户模型。 以账户为单位,安全隔离数据。 账户间信息相互独立,互不干扰。 再配合以太坊虚拟机,让智能合约沙盒运行。

以太坊作为智能合约操作平台,将账户划分为两类:外部账户(EOAs)和合约账户(contract account)。

一、账户基本概念

1.1 外部账户

外部账户(external owned accouts)是由我们通过私钥创建的账户。 是真实世界的金融账户的映射,拥有该账户私钥的任何人都可以控制该账户。 如同银行卡,到ATM机取款时只需要密码输入正确即可交易。 这也是人类与以太坊账本沟通的唯一媒介,因为以太坊中的交易需要签名, 而只能使用拥有私有外部账户签名。

外部账户特点总结:

  1. 拥有以太余额。
  2. 能发送交易,包括转账和执行合约代码。
  3. 被私钥控制。
  4. 没有相关的可执行代码。

1.2 合约账户

合约账户则是含有合约代码的账户。 被外部账户或者合约创建,合约在创建时被自动分配到一个账户地址, 用于存储合约代码以及合约部署或执行过程中产生的存储数据。 合约账户地址是通过SHA3哈希算法产生,而非私钥。 因无私钥,因此无人可以拿合约账户当做外部账户使用。 只能通过外部账户来驱动合约执行合约代码。

合约账户特点总结:

  1. 拥有以太余额。
  2. 有相关的可执行代码(合约代码)。
  3. 合约代码能够被交易或者其他合约消息调用。
  4. 合约代码被执行时可再调用其他合约代码。
  5. 合约代码被执行时可执行复杂运算,可永久地改变合约内部的数据存储。

1.3 差异对比

综上,下面表格列出两类账户差异,合约账户更优于外部账户。 但外部账户是人们和以太坊沟通的唯一媒介,和合约账户相辅相成。

比较项外部账户合约账户
私钥 private Key
余额 balance
代码 code
多重签名
控制方式私钥控制通过外部账户执行合约

上面有列出多重签名,是因为以太坊外部账户只由一个独立私钥创建,无法进行多签。 但合约具有可编程性,可编写符合多重签名的逻辑,实现一个支持多签的账户。

二、帐户创建

2.1 外部账户创建

当你想要创建一个帐户时,大多数库将生成一个随机的私钥。

私钥由 64 个十六进制字符组成,可以用密码加密保存。

例如:

fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036415f

使用椭圆曲线数字签名算法从私钥生成公钥。 通过获取公钥 Keccak-256 哈希的最后 20 个字节并校验码前面添加 0x,可以为帐户获取公共地址。

// PubkeyToAddress 公钥转地址方法
func (p *PublicKey) ToAddress() Address {
	pubBytes := p.FromECDSAPub()
	i := sha3.Keccak256(pubBytes[1:])[12:]
	return BytesToAddress(i)
}

地址具体生成细节可参考: 以太坊地址生成

下面是使用 GETH 的 personal_newAccount 在控制台中创建一个帐户的例子

> personal.newAccount()
Passphrase:  输入账户密码
Repeat passphrase:  再次输入账户密码
"0x0dd26b4f63f9362314b708816a6aa18a04442679"  得到账户地址

> personal.newAccount(123456)
"0x5942bd5c577b569e27dd789b50b7d8824fe399ea"

geth指令详情可查看 geth文档

2.2 合约账户创建

下面是合约地址生成算法:Keccak256(rlp([sender,nonce])[12:]

// https://github.com/ethereum/go-ethereum/blob/master/crypto/crypto.go

func CreateAddress(b common.Address, nonce uint64) common.Address {
    data, _ := rlp.EncodeToBytes([]interface{}{b, nonce})
    return common.BytesToAddress(Keccak256(data)[12:])
}

因为合约由其他账户创建,因此将创建者地址和该交易的随机数进行哈希后截取部分生成。

特别需要注意的是,在EIP1014中提出的另一种生成合约地址的算法。 其目的是为状态通道提供便利,通过确定内容输出稳定的合约地址。 在部署合约前就可以知道确切的合约地址。下面是算法方法:

keccak256( 0xff ++ address ++ salt ++ keccak256(init_code))[12:]

// https://github.com/ethereum/go-ethereum/blob/master/crypto/crypto.go

// CreateAddress2 creates an ethereum address given the address bytes, initial
// contract code hash and a salt.
func CreateAddress2(b common.Address, salt [32]byte, inithash []byte) common.Address {
	return common.BytesToAddress(Keccak256([]byte{0xff}, b.Bytes(), salt[:], inithash)[12:])
}

三、账户数据结构

3.1 账户状态

账户的状态(Acccount State)描述了一个账户当前的情况。以太坊公链时时刻刻跟踪并维护着每一个账户的状态。 一个账户在初次接收或者发出交易后,都会形成初始状态。随着时间的推移,每次针对该账户的交易将不断修改其状态。

注:总结而言,每一个账户在数据结构上具有两个元素:一个公开地址,一个与该地址关联的状态。

在程序逻辑上两类账户的数据结构一致,包含四大元素:

  1. nonce:已执行交易总数,用来标示该账户发出的交易数量;
  2. balance:持币数量,记录用户的以太币余额;
  3. storageRoot hash:存储区的哈希值,指向智能合约账户的存储数据区;
  4. code hash:代码区的哈希值,指向智能合约账户存储的智能合约代码。
//github.com/ethereum/go-ethereum/core/types/account.go

type Account struct {
    Nonce    uint64
    Balance  *big.Int
    Root     common.Hash
    CodeHash []byte
}

以太坊数据以账户为单位组织,账户数据的变更引起账户状态变化。 从而引起以太坊状态变化。

以太坊状态数据:

基于状态机模型,以太坊网络已变成一个依靠矿工维护的去中心化的大型状态机。在任意时刻,只会处于一个状态中,全世界唯一的状态。我们把这个状态机,称之为以太坊世界状态,代表着以太坊网络的全局状态。

世界状态(state)由无数的账户信息组成,每个账户均存在一个唯一的账户信息。账户信息中存储着账户余额、Nonce、合约哈希、账户状态等内容,每个账户信息通过账户地址影射。 从创世状态开始,随着将交易作为输入信息,在预设协议标准(条件)下将世界态推进到下一个新的状态中。

世界状态中存储了哪些内容:

首先,以太坊中有两种级别的状态,一个是顶级的世界状态,另一个是账户级的账户状态。账户状态中存储账户信息:

  1. nonce: 这个值等于由此账户发出的交易数量,或者由这个账户所创建的合约数量(当这个账户有关联代码时)。
  2. balance: 表示这个账户账户余额。
  3. storageRoot: 表示保存了账户存储内容的 MPT 树的根节点的哈希值。
  4. codeHash: 表示账户的 EVM 代码哈希值,当这个地址接收到一个消息调用时,这些代码会被执行; 它和其它字段不同,创建后不可更改。如果 codeHash 为空,则说明该账户是一个简单的外部账户,只存在 nonce 和 balance。

在程序逻辑上两类账户的数据结构一致:

//github.com/ethereum/go-ethereum/core/types/account.go

type Account struct {
    Nonce    uint64
    Balance  *big.Int
    Root     common.Hash
    CodeHash []byte
}

但在数据存储上稍有不同, 因为外部账户无内部存储数据和合约代码,因此外部账户数据中 StateRootHashCodeHash 是一个空默认值。 一旦属于空默认值,则不会存储对应物理数据库中。 在程序逻辑上,存在code则为合约账户。 即 CodeHash 为空值时,账户是一个外部账户,否则是合约账户。

3.2 账户状态结构

下图显示了外部账户与合约账户的账户状态。

外部账户与合约账户的账户状态

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

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

相关文章

AWS Transfer 系列:简化文件传输与管理的云服务

在数字化转型的今天,企业对文件传输、存储和管理的需求日益增长。尤其是对于需要大量数据交换的行业,如何高效、可靠地传输数据成为了一大挑战。为了解决这一难题,AWS 提供了一系列的文件传输服务,统称为 AWS Transfer 系列。这些…

基础I/O -> 如何谈文件与文件系统?

文件的基础理解 空文件也要在磁盘上占据空间。文件 文件内容文件属性。文件操作 对内容的操作 对属性的操作或者是对内容和属性的操作。标定一个文件,必须使用:文件路径 文件名(具有唯一性)。如果没有指明对应的文件路径&…

网络安全检测

实验目的与要求 (1) 帮助学生掌握木马和入侵的防护和检测方法、提高学习能力、应用能力和解决实际问题的能力。 (2) 要求学生掌握方法, 学会应用软件的安装和使用方法, 并能将应用结果展示出来。 实验原理与内容 入侵检测是通过对计算机网络或计算机系统中若干关键点收集信…

谷歌浏览器的资源管理功能详解

谷歌浏览器作为一款广受欢迎的网页浏览器,不仅以其快速、简洁和易用著称,还提供了强大的资源管理功能。本文将详细介绍如何在Chrome浏览器中进行资源管理,包括查看网页的渲染性能、禁用标签页的背景更新以及管理正在下载的文件。(…

ARM异常处理 M33

1. ARMv8-M异常类型及其详细解释 ARMv8-M Exception分为两类:预定义系统异常(015)和外部中断(1616N)。 各种异常的状态可以通过Status bit查看,获取更信息的异常原因: CFSR是由UFSR、BFSR和MMFSR组成: 下面列举HFSR、MMFSR、…

Unity2021.3.16f1可以正常打开,但是Unity2017.3.0f3却常常打开闪退或者Unity2017编辑器运行起来就闪退掉

遇到问题: 从今年开始,不知道咋回事,电脑上的Unity2017像是变了个人似得,突然特别爱闪退掉,有时候还次次闪退,真是让人无语,一直以来我都怀疑是不是电脑上安装了什么别的软件了,导致…

SpringBoot核心:自动配置

有使用过SSM框架的,还记得曾经在spring-mybatis.xml配置了多少内容吗?数据源、连接池、会话工厂、事务管理,而现在Spring Boot告诉你这些都不需要了,简单的几个注解统统搞定,是不是很方便! 前言 SpringBoo…

重温设计模式--享元模式

文章目录 享元模式(Flyweight Pattern)概述享元模式的结构C 代码示例1应用场景C示例代码2 享元模式(Flyweight Pattern)概述 定义: 运用共享技术有效地支持大量细粒度的对象。 享元模式是一种结构型设计模式&#xff0…

Taro小程序开发性能优化实践

我们团队在利用Taro进行秒送频道小程序的同时,一直在探索性能优化的最佳实践。随着需求的不断迭代,项目中的性能问题难免日积月累,逐渐暴露出来影响用户体验。适逢双十一大促,我们趁着这个机会统一进行了Taro性能优化实践&#xf…

纯血鸿蒙APP实战开发——textOverflow长文本省略

介绍 本示例实现了回复评论时,当回复人的昵称与被回复人的昵称长度都过长时,使用textOverflow和maxLines()实现昵称的长文本省略展示的功能。 效果图预览 使用说明 点击评论中的"回复",在输入框中输入回复内容,点击发…

【java面向对象编程】第九弹----抽象类、接口、内部类

笔上得来终觉浅,绝知此事要躬行 🔥 个人主页:星云爱编程 🔥 所属专栏:javase 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 一、抽象类 1.1基本介绍 &…

Qt笔记:网络编程UDP

一、铺垫 1.Qt框架使用的网络结构的基础就是Linux学习的网络编程基础;所以使用Qt写客户端,使用Linux写服务端;两者是可以实现互联的 二、UDP 网络编程UDP使用套路: 1.首先在.pro文件中加上network,使Qt可以搭载网络…

Redis存在安全漏洞

Redis是美国Redis公司的一套开源的使用ANSI C编写、支持网络、可基于内存亦可持久化的日志型、键值(Key-Value)存储数据库,并提供多种语言的API。 Redis存在安全漏洞。攻击者利用该漏洞使用特制的Lua脚本触发堆栈缓冲区溢出漏洞,从…

【潜意识Java】蓝桥杯算法有关的动态规划求解背包问题

目录 背包问题简介 问题描述 输入: 输出: 动态规划解法 动态规划状态转移 代码实现 代码解释 动态规划的时间复杂度 例子解析 输出: 总结 作者我蓝桥杯:2023第十四届蓝桥杯国赛C/C大学B组一等奖,所以请听我…

ReactPress 1.6.0:重塑博客体验,引领内容创新

ReactPress 是一个基于Next.js的博客&CMS系统, Github项目地址:https://github.com/fecommunity/reactpress 欢迎Star。 体验地址:http://blog.gaoredu.com/ 今天,我们自豪地宣布ReactPress 1.6.0版本的正式发布,…

单元测试-Unittest框架实践

文章目录 1.Unittest简介1.1 自动化测试用例编写步骤1.2 相关概念1.3 用例编写规则1.4 断言方法 2.示例2.1 业务代码2.2 编写测试用例2.3 生成报告2.3.1 方法12.3.2 方法2 1.Unittest简介 Unittest是Python自带的单元测试框架,适用于:单元测试、Web自动…

带有 Elasticsearch 和 Langchain 的 Agentic RAG

作者:来自 Elastic Han Xiang Choong 讨论并实现 Elastic RAG 的代理流程,其中 LLM 选择调用 Elastic KB。 更多阅读:Elasticsearch:基于 Langchain 的 Elasticsearch Agent 对文档的搜索。 简介 代理是将 LLM 应用于实际用例的…

[react 3种方法] 获取ant组件ref用ts如何定义?

获取ant的轮播图组件, 我用ts如何定义? Strongly Type useRef with ElementRef | Total TypeScript import React, { ElementRef } from react; const lunboRef useRef<ElementRef<typeof Carousel>>(null); <Carousel autoplay ref{lunboRef}> 这样就…

stm32制作CAN适配器5--WinUsb上位机编写

上次我们要stm32制作了一个基于winusb有canfd适配器&#xff0c;今天我们来制作一个上位机程序来进行报文收发。 上位机还是用以前写好的&#xff0c;只是更改下dll文件。 项目链接器&#xff0c;输入&#xff0c;附加依赖项中增加winusb.lib winusb初始化&#xff1a;#incl…

C/C++圣诞树

系列文章 序号直达链接1C/C爱心代码2C/C跳动的爱心3C/C李峋同款跳动的爱心代码4C/C满屏飘字表白代码5C/C大雪纷飞代码6C/C烟花代码7C/C黑客帝国同款字母雨8C/C樱花树代码9C/C奥特曼代码10C/C精美圣诞树11C/C俄罗斯方块12C/C贪吃蛇13C/C孤单又灿烂的神-鬼怪14C/C闪烁的爱心15C…