以太坊源码分析(2)Accounts源码分析与逻辑结构之基本概述与新建账户源码

以太坊源码解读(1)以太坊架构与模块结构 以太坊架构与模块化结构 一:以太坊核心概念 EVM: 以太坊虚拟机,以太坊中智能合约的运行环境 Accounts: 区别去比特币的UTXO,以太坊构建里账户,账户分为两类,内部账户和外部账户,内部账户指合约账户,外部账户指用户账户 Transaction: 在以太坊网络上的任何一个消息的传递都是一次交易 gas: 以太坊网络的运行机制之一,每执行一步合约代码都与要消耗一定的gas,gas的设定一方... 阅读详情

Accounts源码分析与逻辑结构1

众所周知以太坊在比特币的基础上加以引用与改进,比特币使用UTXO来表示状态的转移,而以太坊使用账来表示状态的转移。

accounts包实现了以太坊客户端的钱包和账户管理

在以太坊网络中存在两种账户:

外部账户EOA:一般是属于个人或者用户的账户,被私钥控制没有任何代码与之相关

内部账户CA:给智能合约分配的账户,被合约代码控制,且与合约关联

在源码core/state/state_object.go文件下,账户定义如下:

// Account is the Ethereum consensus representation of accounts.
// These objects are stored in the main account trie.
type Account struct {
   Nonce    uint64
   Balance  *big.Int
   Root     common.Hash // merkle root of the storage trie
   CodeHash []byte
}

Nonce:如果是EOA账户表示发送交易的序号,如果为CA账户,则Nonce表示合约创建的序号

Balance:表示账户的余额,该账户地址对应的账户余额

Root:存储merkle树的根,如果为EOA账户root为nil

CodeHash:账户绑定的EVM Code,如果为EOA则CodeHash为nil

钱包interface,是指包含了一个或多个账户的软件钱包或者硬件钱包:
type Wallet interface {
 // URL 用来获取这个钱包可以访问的规范路径。它会被上层使用用来从所有的后端的钱包来排序。
   URL() URL
    
 // 用来返回一个文本值用来标识当前钱包的状态。同时也会返回一个error用来标识钱包遇到的任何错误。
   Status() (string, error)
    
  //Open初始化对钱包实例的访问。如果你open了一个钱包,你必须close它。
   Open(passphrase string) error
    
 // Close 释放由Open方法占用的任何资源。           
   Close() error
    
  // Accounts用来获取钱包发现了账户列表。对于分层次的钱包,这个列表不会详尽的列出所有的账号,而是只包   //含在帐户派生期间明确固定的帐户。
   Accounts() []Account
    
  //包含返回帐户是否属于此特定钱包的一部分。
   Contains(account Account) bool
    
 //Derive尝试在指定的派生路径上显式派生出分层确定性帐户。如果pin为true,派生帐户将被添加到钱包的跟踪  //帐户列表中。
   Derive(path DerivationPath, pin bool) (Account, error)
    
 //SelfDerive设置一个基本帐户导出路径,从中钱包尝试发现非零帐户,并自动将其添加到跟踪帐户列表中。
   SelfDerive(base DerivationPath, chain ethereum.ChainStateReader)
    
 // SignHash 请求钱包来给传入的hash进行签名。
   SignHash(account Account, hash []byte) ([]byte, error)
    
  // SignTx 请求钱包对指定的交易进行签名。
   SignTx(account Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error)
    
 //SignHashWithPassphrase请求钱包使用给定的passphrase来签名给定的hash
   SignHashWithPassphrase(account Account, passphrase string, hash []byte) ([]byte, error)

   // SignHashWithPassphrase请求钱包使用给定的passphrase来签名给定的
   SignTxWithPassphrase(account Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error)
}
后端Backend,Backend是一个钱包提供器。可以包含一批账号。他们可以根据请求签署交易
type Backend interface {
   // Wallets获取当前能够查找到的钱包
   Wallets() []Wallet

  // 订阅创建异步订阅,以便在后端检测到钱包的到达或离开时接收通知。
   Subscribe(sink chan<- WalletEvent) event.Subscription
}
manager.go:Manager是一个包含所有东西的账户管理工具。可以和所有的Backends来通信来签署交易
type Manager struct {
    // 当前注册的后端索引
	backends map[reflect.Type][]Backend 
    
    // 钱包更新订阅所有后端
	updaters []event.Subscription 
    
   // 钱包更新订阅接收器
	updates  chan WalletEvent           
    
   // 缓存所有钱包从所有注册后端
	wallets  []Wallet          
    
   // 通知到达/离开的钱包事件
	feed event.Feed 
	
    //退出数据管道 错误信息
	quit chan chan error
    
    //读写互斥锁
	lock sync.RWMutex
}

newAccount源码解读

了解了账户的结构以后,我们来看看和账户有关的代码,因为以太坊源码的分离性,数据结构的定义和工具方法逻辑实现比较分离,在整个流程的执行中或调用多层。

首先当用户在console也就是控制台输入personal.newAccount()会创建一个新的账户这个命令的执行流程如下:
1)执行internal/ethapi/api.go文件中的NewAccount方法,返回账户地址

func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error) {
   acc, err := fetchKeystore(s.am).NewAccount(password)
   if err == nil {
      return acc.Address, nil
   }
   return common.Address{}, err
}

internal/ethapi/api.go文件中的NewAccount方法调用fetchKeystore方法从帐户管理器检索加密的密钥存储库获取keystore。

func fetchKeystore(am *accounts.Manager) *keystore.KeyStore {
   return am.Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
}

internal/ethapi/api.go文件中的NewAccount方法获取到keystore后通过keystore调用accounts/keystore/keystore.go中的NewAccoun方法获取account,并将这个账户添加到keystore中,返回account

func (ks *KeyStore) NewAccount(passphrase string) (accounts.Account, error) {
   _, account, err := storeNewKey(ks.storage, crand.Reader, passphrase)
   if err != nil {
      return accounts.Account{}, err
   }
   // Add the account to the cache immediately rather
   // than waiting for file system notifications to pick it up.
   ks.cache.add(account)
   ks.refreshWallets()
   return account, nil
}

调用storeNewKey方法创建一个新的账户,生成一对公私钥,通过私钥以及地址构建一个账户

func storeNewKey(ks keyStore, rand io.Reader, auth string) (*Key, accounts.Account, error) {
   key, err := newKey(rand)
   if err != nil {
      return nil, accounts.Account{}, err
   }
   a := accounts.Account{Address: key.Address, URL: accounts.URL{Scheme: KeyStoreScheme, Path: ks.JoinPath(keyFileName(key.Address))}}
   if err := ks.StoreKey(a.URL.Path, key, auth); err != nil {
      zeroKey(key.PrivateKey)
      return nil, a, err
   }
   return key, a, err
}

Key的生成函数,通过椭圆曲线加密生成的私钥,生成Key

func newKey(rand io.Reader) (*Key, error) {
   privateKeyECDSA, err := ecdsa.GenerateKey(crypto.S256(), rand)
   if err != nil {
      return nil, err
   }
   return newKeyFromECDSA(privateKeyECDSA), nil
}

生成公钥和私钥对,ecdsa.GenerateKey(crypto.S256(), rand) 以太坊采用了椭圆曲线数字签名算法(ECDSA)生成一对公私钥,并选择的是secp256k1曲线

func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) {
   k, err := randFieldElement(c, rand)
   if err != nil {
      return nil, err
   }

   priv := new(PrivateKey)
   priv.PublicKey.Curve = c
   priv.D = k
   priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
   return priv, nil
}
func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error) {
   params := c.Params()
   b := make([]byte, params.BitSize/8+8)
   _, err = io.ReadFull(rand, b)
   if err != nil {
      return
   }

   k = new(big.Int).SetBytes(b)
   n := new(big.Int).Sub(params.N, one)
   k.Mod(k, n)
   k.Add(k, one)
   return
}

以太坊使用私钥通过 ECDSA算法推导出公钥,继而经过 Keccak-256 单向散列函数推导出地址

func newKeyFromECDSA(privateKeyECDSA *ecdsa.PrivateKey) *Key {
   id := uuid.NewRandom()
   key := &Key{
      Id:         id,
      Address:    crypto.PubkeyToAddress(privateKeyECDSA.PublicKey),
      PrivateKey: privateKeyECDSA,
   }
   return key
}

地址代币以太坊的20位地址hash

// Address represents the 20 byte address of an Ethereum account.
type Address [AddressLength]byte

整个过程可以总结为:

从前控制台传入创建账户命令

首先创建随机私钥

通过私钥导出公钥

通过公私钥导出地址

以太坊账户管理源码分析 这篇分析一下以太坊的账户管理。 这部分比较简单,主要分”获取钱包列表“和“订阅钱包事件”两个部分,下面分别介绍。 1. 获取钱包列表 先上一张图,理清组件间的关系: 从图中可以看出wallet、account、address这三者的区别和联系i:wallet中可能包含多个account,而每个account中包含一个address和账户所在路径(URL)。 这里有两个重要接口:Bac... 阅读详情

相关推荐

Huber损失函数中的阈值δ是如何确定的?

Huber损失函数通过阈值δ将误差划分为两部分:当误差小于等于δ时,采用平方损失(MSE),以保持对小误差的敏感性;当误差大于δ时,采用线性损失(MAE),以降低异常值对模型的影响。

百态·数智思维 | 聚焦大数据、量化与未来AI 1926

以太坊学习笔记:私有链搭建操作指南

虽然以太坊是一个公有链系统,但是我们可以通过设置一些参数来运行自己的私有链节点,在自己的私有链上进行开发和测试不需要同步公有链数据,也不需要花钱来买以太币,节省存储空间和成本,而且很灵活很方便。本文介绍使用geth客户端搭建私有链的操作步骤,同时会解释在这个过程中用到的各个命令及选项的含义和作...

chuhuan6596的博客 1241

机器人手眼标定快速精度验证方法

机器人手眼标定快速精度验证方法

laoli_的博客 1万+

以太坊源码分析(6)accounts账户管理分析

##数据结构分析以太坊的账户管理定义在accounts/manager.go中,其数据结构为:```// Manager is an overarching account manager that can communicate with various// backends for signing transactions. type Manager struct { ba...

尹成的技术博客 2035

ollama环境变量配置:修改ollama的数据路径(安装路径)

ollama安装模型,如果很大,会占用C盘空间,影响系统运行速度,通过设置环境变量,来改变ollama放目录的地址。

正经教主是个热衷于正经学习分享的教主。 1万+

QGIS-空间分析-核密度分析

本文在QGIS软件中使用核密度估计法分析全球历年的地震数据,旨在分析出地震频发且严重的区域,为地震防控提供参考依据。全球历年地震数据来源于网络,仅用于技术学习探索。通过核密度分析,可以观察到南美、美国西部海岸线和太平洋北部区域在全球地震分布状态中是最为集中和强烈的。

imxiezy的博客 2467

以太坊源码分析(5)accounts代码分析

## 1.personal.newAccount创建账户方法 用户在控制台输入personal.newAccount会创建一个新的账户,会进入到ethapi.api中的newAccount方法中,这个方法会返回一个地址。 ```  func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error) {   ...

u012149181的博客 509

适合初学者的ROS机器人教程(1): Ubuntu下ROS创建自己的包和使用github下载的包

ROS如何创建自己的包 1. 首先创建catkin工作空间(如果你以及有了请忽略) $ mkdir catkin_ws # 创建一个文件夹里面计划放我们的项目,ws是workspace的缩写 $ cd catkin_ws # 将当前工作文件夹切换到catkin_ws这个文件夹 ~/catkin_ws$ catkin_make # 执行catkin_make创建一ROS项目 此时你的catkin_...

@司南牧|知乎|博客|易懂教程|李韬 3243

从命令行开始解析以太坊新建账户过程(geth account new命令)

从命令行开始解析以太坊新建账户过程(geth account new命令) 如上图是生成一个账户的过程,最后的账户表现为一个地址那么,这个过程的代码是怎么实现的呢,接下来我们从main函数命令行开始解析这个过程的代码。 在cmd/geth/main.go中的init函数中,有一个accountCommand的命令行参数 func init() { // Initialize the ...

Hacker的博客 7045

保姆级教程:ABAP 通过 HTTP POST 调用 OData 服务创建业务数据的具体例子

笔者之前的文章发布之后,有朋友在评论区留言,询问 ABAP 除了 Web Service 之外,是否也支持 HTTP 呢?ABAP 这么强大的语言,支持 HTTP 当然不在话下。网上有很多在 ABAP 系统基于 CL_HTTP_CLIENT 工具类,通过 HTTP 协议和第三方系统交互的代码例子。本文介绍笔者项目中一个实际例子,实现的是在 ABAP 系统 A 通过 HTTP 调用 OData 服务,在 ABAP 系统 B 创建业务数据的需求。下面我们按照这个套路来一步步实现。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 697

32、运算放大器的工作原理与应用

本文详细介绍了运算放大器的工作原理与多种应用场景,涵盖开环与闭环放大器的基本概念、理想运算放大器的特性及其‘黄金规则’。文章深入解析了反相放大器、同相放大器、单位增益跟随器与反相器的配置和增益计算,并探讨了电压比较器及窗口比较器的工作机制。同时提供了运算放大器在实际应用中的选型流程、使用注意事项以及常见故障排查方法,帮助读者全面掌握运算放大器的设计与应用要点。

u5v6w7的博客 162

以太坊源码分析(3)Accounts源码分析与逻辑结构之交易源码

Accounts源码分析与逻辑结构2 listAccounts源码分析 位于internal/ethapi/api.go中的ListAccounts方法 // ListAccounts will return a list of addresses for accounts this node manages. func (s *PrivateAccountAPI) ListAccounts() ...

Debug_lll的博客 743

MCAL中MCU的配置

MCAL配置中MCU配置,PLL计算配置,系统时钟以及各模块参数配置

dhyw12399999的博客 3794

以太坊源码分析(4)accounts包简介

accounts包实现了以太坊客户端的钱包和账户管理。账号的数据结构:    typeAccount struct {    Address common.Address `json:"address"` // Ethereum account addressderived from the key     URLURL `json:"url"` // Optional resource loca...

尹成的技术博客 1671

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Ethereum 源码分析之 accounts

一、Account // Account represents an Ethereum account located at a specific location defined // by the optional URL field. // Account,代表一个位于由可选的URL字段定义的具体位置的以太坊账户 // Address,地址是20个字节,由私钥衍生。。U...

banjuan3729的博客 237

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

如何从零构建以太坊账户系统:Geth私钥生成与地址计算实战

以太坊账户系统是区块链交互的基础,本文将带你快速掌握以太坊账户的核心原理,包括私钥生成、公钥提取和地址计算的完整流程。通过Geth源码解析和实战示例,即使是区块链新手也能轻松理解账户安全的底层逻辑。 ## 以太坊账户的核心构成 以太坊账户分为外部账户(EOA)和合约账户两种类型,其中外部账户由用户直接控制,通过私钥进行交易签名。每个账户都拥有唯一的20字节地址,类似于银行账户的账号,而私钥则相

gitblog_01092的博客 375

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

06.以太坊源码分析(6)accounts账户管理分析

数据结构分析 以太坊的账户管理定义在accounts/manager.go中,其数据结构为: // Manager is an overarching account manager that can communicate with various // backends for signing transactions. type Manager struct { ba...

boss2967的博客 485

区块链教程以太源码分析accounts账户管理分析

   兄弟连区块链教程以太源码分析accounts账户管理分析。 数据结构分析 ETH的账户管理定义在accounts/manager.go中,其数据结构为: //Manag...

congdianquan3478的博客 215

兄弟连区块链教程以太源码分析accounts包简介

accounts包实现了eth客户端的钱包和账户管理。 账号的数据结构: typeAccountstruct{ Addresscommon.Address`json:"address"`//...

congdianquan3478的博客 164

以太坊源码分析(10)CMD深入分析

### cmd包分析 #### cmd下面总共有13个子包,除了util包之外,每个子包都有一个主函数,每个主函数的init方法中都定义了该主函数支持的命令,如   ##### geth包下面的:   ``` func init() {     // Initialize the CLI app and start Geth     app.Action = geth     a...

chunqizhi 980

Go-Ethereum:从单节点到安全签名守护的演进之路

Go-Ethereum(Geth)作为以太坊协议的官方Golang实现,已经从一个简单的以太坊客户端演变为一个功能完备的区块链基础设施。本文将带您了解Geth如何从基础节点运行发展到支持复杂安全架构的完整解决方案,特别关注其**安全签名守护进程Clef**的演进历程。 ## 基础起点:搭建您的第一个以太坊节点 对于大多数开发者来说,接触Go-Ethereum的第一步都是从运行一个简单的以太坊节

gitblog_00346的博客 465

AbstractAccountAuthenticator简介

本文翻译整理自: http://developer.android.com/reference/android/accounts/AbstractAccountAuthenticator.html  Abstract base class for creating AccountAuthenticators. In order to be an authenticator one mus

Robin Hu的专栏 6238

以太坊源代码分析

准备工作 以太坊的源代码是开源的,基于Go语言的版本的源代码获取参考下面的命令。还有用c++开发的源代码,不在本文的探讨范围之内。 git clone https://github.com/ethereum/go-ethereum.git 安装详细还可以参考手把手教你从源代码开始搭建自己的以太坊公链(二)搭建第一个节点 Go语言的开发环境可以参考手把手教你从源代码开始搭建自己的以太坊公链(一)G...

Mark的博客 1万+
上一篇: 以太坊源码解读(1)以太坊架构与模块结构
下一篇: 以太坊源码分析(3)Accounts源码分析与逻辑结构之交易源码
Debug_lll
博客等级 码龄8年 10粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值