https://github.com/ethereumjs/ethereumjs-account

Encoding, decoding and validation of Ethereum's Account schema

以太坊账户概要的编码、解码和验证

账户 = 账户address + 账户状态

这个库处理的是账户状态,然后将账户address作为key,账户状态作为value,添加到state前缀树中,即生成了一个账户

SYNOPSIS概要

This library eases the handling of Ethereum accounts, where accounts can be either external accounts or contracts (seeAccount Types docs).

这个库简化了以太坊账户状态的处理,账户可以是外部账户(即我们日常使用的账户)或合约账户(即合约部署处)

Note that the library is not meant to be used to handle your wallet accounts, use e.g. the web3-eth-personal package from the web3.js library for that. This is just a semantic wrapper to ease the use of account data and provide functionality for reading and writing accounts from and to the Ethereum state trie.

注意这个库不意味着用来处理你的钱包账户,钱包账户应该使用来自web3.js库的web3-eth-personal包。这个只是用来简化账户数据的使用和提供从和给以太坊状态前缀树读写账户的函数的语义封装

INSTALL安装

npm install ethereumjs-account

BROWSER浏览器

This module work with browserify. 该模块browserify一起使用

⚠️账户 = 账户address + 账户状态

这里的account = new Account(data)生成的是账户状态,最后还需要将其与某个address对应起来,对应的方法就是将其作为区块链的state merkle-Patricia树的key = address ,value = account.serialize()-即其的RLP序列化值,然后添加到前缀树中去,这样才真正生成了一个账户,如:

stateTrie.put(address, account.serialize(), cb)

API

new Account([data])

Creates a new account object创建一个账户对象

  • data - an account can be initialized with either a buffer containing the RLP serialized account. Or an Array of buffers relating to each of the account Properties, listed in order below. For example: 一个账户能够带着要么是包含着RLP编码的序列化账户的buffer,或者是关联每个账户属性,就像下面顺序列举一样的buffers数组来进行初始化
var raw = [ //这个是数组格式的初始化
'0x02', //nonce
'0x0384', //balance
'0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', //stateRoot
'0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' //codeHash
]; var account = new Account(raw);

Or lastly an Object containing the Properties of the account:

下面这个例子就是包含着账户属性的对象

var raw = {//这个是object对象格式的初始化
nonce: '',
balance: '0x03e7',
stateRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
codeHash: '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'
}; var account = new Account(raw);

For Object and Array each of the elements can either be a Buffer, hex StringNumber, or an object with a toBuffer method such as Bignum.

对于对象或者数组的每一个元素都要么是Buffer,十六进制字符串,数字,或者带着toBuffer方法的对象,如Bignum

还有RLP编码的序列化格式:

var account = new Account('f84602820384a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470')

Account Properties 账户属性

  • nonce - The account's nonce.
  • balance - The account's balance in wei.
  • stateRoot - The stateRoot for the storage of the contract. 用于合约的存储的stateRoot
  • codeHash - The hash of the code of the contract. 合约代码的hash

注意:如果是外部账户,它的codeHash为空字符串的hash值

Account Methods账户方法

account.isEmpty()

Returns a Boolean determining if the account is empty.

返回一个Boolean值,确定账户是否为空

account.isContract() 看代码是怎么检测的

Returns a Boolean deteremining if the account is a contract.

返回一个Boolean值,确定账户是否为合约账户

account.serialize()

Returns the RLP serialization of the account as a Buffer.

返回Buffer类型的账户的RLP编码序列化,得到的就是上面使用RLP编码的序列化格式方法进行初始化时的RLP序列化的值,如:

'f84602820384a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'

account.toJSON([object])

Returns the account as JSON.

返回JSON类型的账户

  • object - A Boolean that defaults to false. If object is true then this will return an Object, else it will return an Array. 默认为false的Boolean值。如果object为true,那么该方法将返回一个对象,否则他将返回一个数组


account.getCode(trie, cb)

Fetches the code from the trie.

从前缀树中获取代码,得到的是账户中codeHash的值

  • trie - The trie storing the accounts. 存储账户的前缀树
  • cb - The callback. 回调函数

account.setCode(trie, code, cb)

Stores the code in the trie.

在前缀树上存储代码。就是更改账户中codeHash的值,如果改后不为空字符串hash值,则相应存到前缀树的底层数据库上

  • trie - The trie storing the accounts. 存储账户的前缀树
  • code - A Buffer. Buffer值的代码
  • cb - The callback. 回调函数

Example for getCode and setCodegetCodesetCode方法的例子

// Requires manual merkle-patricia-tree install
const SecureTrie = require('merkle-patricia-tree/secure')
const Account = require('./index.js') let code = Buffer.from('73095e7baea6a6c7c4c2dfeb977efac326af552d873173095e7baea6a6c7c4c2dfeb977efac326af552d873157', 'hex') let raw = {
nonce: '',
balance: '0x03e7',
stateRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
codeHash: '0xb30fb32201fe0486606ad451e1a61e2ae1748343cd3d411ed992ffcc0774edd4'
} let account = new Account(raw)
let trie = new SecureTrie() account.setCode(trie, code, function (err, codeHash) {
console.log(`Code with hash 0x${codeHash.toString('hex')} set to trie`)
account.getCode(trie, function (err, code) {//因为上面的setCode会对应更改account中的codeHash,当getCode时查找的就是account中的codeHash对应的code
console.log(`Code ${code.toString('hex')} read from trie`)
})
})

account.getStorage(trie, key, cb)

Fetches key from the account's storage.

从账户的存储中(即从前缀树中)获取key对应的值

account.setStorage(trie, key, val, cb)

Stores a val at the key in the contract's storage.

在合约的存储中对应的key值处存储val值,会导致account的stateRoot值更改

Example for getStorage and setStoragegetStoragesetStorage方法的例子

// Requires manual merkle-patricia-tree install
const SecureTrie = require('merkle-patricia-tree/secure')
const Account = require('./index.js') let raw = {
nonce: '',
balance: '0x03e7',
stateRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
codeHash: '0xb30fb32201fe0486606ad451e1a61e2ae1748343cd3d411ed992ffcc0774edd4'
} let account = new Account(raw)
let trie = new SecureTrie() let key = Buffer.from('', 'hex')
let value = Buffer.from('', 'hex') account.setStorage(trie, key, value, function (err, value) {
account.getStorage(trie, key, function (err, value) {
console.log(`Value ${value.toString('hex')} set and retrieved from trie.`)
})
})

更加详细的理解可看ethereumjs/ethereumjs-account-2-test

实现代码:

index.js

const ethUtil = require('ethereumjs-util')
const rlp = require('rlp')
const Buffer = require('safe-buffer').Buffer var Account = module.exports = function (data) {
// Define Properties,定义账户状态的属性
var fields = [{
name: 'nonce',
default: Buffer.alloc()
}, {
name: 'balance',
default: Buffer.alloc()
}, {
name: 'stateRoot',
length: ,
default: ethUtil.SHA3_RLP
}, {
name: 'codeHash',
length: ,
default: ethUtil.SHA3_NULL
}] ethUtil.defineProperties(this, fields, data)
} Account.prototype.serialize = function () {
return rlp.encode(this.raw)
} Account.prototype.isContract = function () {
return this.codeHash.toString('hex') !== ethUtil.SHA3_NULL_S //即只要账户的codeHash值不是空字符串的hash值即可
} Account.prototype.getCode = function (state, cb) {
if (!this.isContract()) {//不是合约账户则返回0
cb(null, Buffer.alloc())
return
} state.getRaw(this.codeHash, cb) //否则得到的是账户中codeHash的值
} Account.prototype.setCode = function (trie, code, cb) {
var self = this this.codeHash = ethUtil.sha3(code) //其实就是将账户中的codeHash改了 if (this.codeHash.toString('hex') === ethUtil.SHA3_NULL_S) { //如果改了后发现codeHash值变成了空字符串的hash值
cb(null, Buffer.alloc()) //则返回0的Buffer
return
} trie.putRaw(this.codeHash, code, function (err) { //如果不是空字符串的hash值,则设置key = codeHash,value = code存到树的底层数据库中
cb(err, self.codeHash)
})
} Account.prototype.getStorage = function (trie, key, cb) {
var t = trie.copy()
t.root = this.stateRoot
t.get(key, cb)
} Account.prototype.setStorage = function (trie, key, val, cb) {
var self = this
var t = trie.copy()
t.root = self.stateRoot
t.put(key, val, function (err) {
if (err) return cb()
self.stateRoot = t.root //会导致stateRoot值更改
cb()
})
} Account.prototype.isEmpty = function () {
return this.balance.toString('hex') === '' &&
this.nonce.toString('hex') === '' &&
this.stateRoot.toString('hex') === ethUtil.SHA3_RLP_S &&
this.codeHash.toString('hex') === ethUtil.SHA3_NULL_S
}
 
 






ethereumjs/ethereumjs-account-1-简介和API的更多相关文章

  1. IO流 简介 总结 API 案例 MD

    目录 IO 流 简介 关闭流的正确方式 关闭流的封装方法 InputStream 转 String 的方式 转换流 InputStreamReader OutputStreamWriter 测试代码 ...

  2. Servlet基础(一) Servlet简介 关键API介绍及结合源码讲解

    Servlet基础(一) Servlet基础和关键的API介绍 Servlet简介 Java Servlet是和平台无关的服务器端组件,它运行在Servlet容器中. Servlet容器负责Servl ...

  3. WeChat Official Account Admin Platform Message API Guide

    Keyword: WeChat Message API Text Image Location Link Event Music RichMedia Author: PondBay Studio[We ...

  4. Sentinel 简介与API订阅发布

    Sentinel 简介 Redis 的 Sentinel 系统用于管理多个 redis 服务器(instance), 该系统执行以下三个任务: 监控(Monitoring): Sentinel 会不断 ...

  5. API Monitor简介(API监控工具)

    API Monitor是一个免费软件,可以让你监视和控制应用程序和服务,取得了API调用. 它是一个强大的工具,看到的应用程序和服务是如何工作的,或跟踪,你在自己的应用程序的问题. 64位支持 API ...

  6. JavaMail入门第一篇 邮件简介及API概述

    现如今,电子邮件在我们的生活当中扮演着越来越重要的角色,我们每个人几乎都会与其打交道(至少时不时我们都会接收到莫名其妙的垃圾邮件),在工作中,使用邮件进行交流沟通,可以使我们的工作有迹可循,也显的较为 ...

  7. Linux PWM framework简介和API描述【转】

    本文转载自:https://blog.csdn.net/mike8825/article/details/51656400 1. 前言 PWM是Pulse Width Modulation(脉冲宽度调 ...

  8. SQLite3 C/C++ 开发接口简介(API函数)

    from : http://www.sqlite.com.cn/MySqlite/5/251.Html 1.0 总览 SQLite3是SQLite一个全新的版本,它虽然是在SQLite 2.8.13的 ...

  9. ZooKeeper系列4:ZooKeeper API简介及编程

    问题导读: 1.ZooKeeper API 共包含几个包? 2.如何使用ZooKeeper API 创建zookeeper应用程序? 1)ZooKeeper API 简介   ZooKeeper AP ...

  10. ZABBIX API简介及使用

    API简介 Zabbix API开始扮演着越来越重要的角色,尤其是在集成第三方软件和自动化日常任务时.很难想象管理数千台服务器而没有自动化是多么的困难.Zabbix API为批量操作.第三方软件集成以 ...

随机推荐

  1. 编译器错误消息: CS0012: 类型“System.Object”在未被引用的程序集中定义。必须添加对程序集“System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”的引用。

    编译器错误消息: CS0012: 类型“System.Object”在未被引用的程序集中定义.必须添加对程序集“System.Runtime, Version=4.0.0.0, Culture=neu ...

  2. Expression Blend实例中文教程(2) - 界面快速入门

    上一篇主要介绍Expression系列产品,另外概述了Blend的强大功能,本篇将用Blend 3创建一个新Silverlight项目,通过创建的过程,对Blend进行快速入门学习. 在开始使用Ble ...

  3. java 并发(三)---Thread 线程

    Thread 的状态 线程共有五种状态.分别是: (1)新建 (2)就绪 (3)运行 (4)阻塞 (5)死亡 ,下面列列举的状态需要结合状态示意图更好理解.  新建状态(New): 新创建了一个线程对 ...

  4. C# 处理XML的基本操作

    文章部分代码引用参考文章, 文末参考文章已标注 ,本篇文章建立在两篇参考文章基础上,可以先阅读参考文章 XML 相关类 XDocument XmlDocument XmlReader  XmlWrit ...

  5. webservice log4net日志写入失败

    原因1:如果webservice和调用者都部署在一台机器上,日志有可能写到了项目所在目录中,虽然你添加的服务引用是部署在iis下的,但不会写到这.暂时解决办法,把webservice部署到内网服务器上 ...

  6. java线程总结1--线程的一些概念基础以及线程状态

    在编程中,很多时候,我们需要计算机同时处理多件事情,例如说,就拿我相对最熟悉的web服务来说,web程序必须支持多用户访问,要不然如果你的用户只能支持一个用户在线访问,其他用户只能以排队的形式等待,估 ...

  7. 十一、cent OS下搭建SVN服务器

    安装SVN命令:yum install subversion 查看安装位置:rpm -ql subversion,我们看到它在/usr/bin目录下生成了svn的二进制文件 查看svn版本:/usr/ ...

  8. Python基础-面向过程编程实现Linux下cat -rl ‘dir’ |grep ‘keywords’ 功能

    函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计的基本单元. ...

  9. 26_线程池_ThreadPoolExecutor

    [ThreadPoolExecutor简述] 无论是Executors类的newFixedThreadPool().newSingleThreadExecutor(),还是newCachedThrea ...

  10. c++开发ocx入门实践二

    原文:http://blog.csdn.net/yhhyhhyhhyhh/article/details/51374355         IDE:vs2010,c++,测试工具,vs自带的TstCo ...