《以太坊技术详解与实战》---第二章:以太坊架构与组成

在这里插入图片描述
以太坊整体架构

  • 底层服务
    以太坊中的区块、交易等数据最终是存在LevelDB数据库中的。分片优化使得可以并行验证交易,大大加快了区块的生成速度
  • 核心层
    以太坊虚拟机-EVM是智能合约的运行环境
  • 顶层应用
    以太坊的DApp通过Web3.js与智能合约层进行信息交换。是最接近用户的一层

共识算法用于解决点对点网络节点之间账本的一致性


区块

  • 区块头:包含前一个区块的散列值(Prev_Hash)、时间戳(Timestamp)、随机数(Nonce)、Merkle树的根值(Tx_Root)和当前区块的散列值等信息。
  • 区块体:包含交易计数与交易详情
    以太坊的区块由区块头、交易列表和叔区块头组成。区块头包含Pre_Hash,叔区块(不在主链上的且被主链上的区块通过Uncles字段收留进区块链的孤块叫做叔区块)的散列值(Uncles Hash)、状态树根散列值(stateRoot)、交易树根散列值(Transaction Root)、收据树根散列值(Recipt Root)、Timestamp,Nonce。

区块保存了三颗Merkle树的根:状态树、交易树、收据树。

以太坊出块时间大概为15s


账户

账户以地址为索引,地址由公钥的最后20字节产生

分为两种账户:外部账户合约账户。外部账户由人创建,可存储以太币,由公私钥控制的账户,合约账户是由外部账户创建的账户。外部账户存储以太币余额状态,而合约账户除了余额还有智能合约及其变量的状态。

一个以太坊的账户包含四部分:

  • 该地址的交易次数
  • 以太币余额
  • 合约二进制代码(合约账户)
  • 账户的存储(默认为空)

(1)外部账户
EOA(externally owned account)外部账户由私钥来控制,是由用户实际控制的账户。外部账户不能包含以太坊虚拟机(EVM)代码。

一个外部账户有以下特性:一定的账户余额、可以发送交易、通过私钥控制、没有相关代码。

可以使用以太坊客户端创建一个外部账户,生成一个账户地址的过程有以下三步:
1)设置账户私钥,即账户密码
2)使用加密算法(secp256k1,椭圆曲线密码算法)由私钥生成对应公钥
3)根据公钥得出相应的账户地址

以太坊使用SHA3由公钥得到账户地址。

以太坊没有让用户重置或者找回密钥的功能。

在以太坊节点之间传输整个目录或者密钥文件是安全的


(2)合约账户
合约账户是一个包含合约代码的账户,由合约代码控制而不是由私钥控制。地址是由合约创建时合约创建者的地址,以及该地址发出的交易共同计算得出的。

具有以下特性:拥有一定的以太币余额,相关联的代码、代码通过交易或者其他合约发送的调用来激活;合约执行时,只能操作合约账户拥有的特定存储。

合约账户与普通账户最大的不同就是它还存有智能合约。

每当合约账户收到一条交易信息时,合约代码将被交易输入的参数调用执行。而合约代码将会在参与到网络中的每一个节点上执行,并且将执行结果作为新块验证的一部分


公私钥对

  • 公钥认证即通过鉴别一个用户的私钥是否正确来鉴别这个用户的真伪。
  • 公钥加密时通过公钥加密文件,然后使用私钥解密文件。

公钥加密是发送者先用公钥加密,接收者再用私钥解密;而公钥认证是发送者先用私钥加密,接受者再用公钥解密以验证。

钥匙文件是json文本文件。钥匙文件可以在以太坊节点数据目录的keystore子目录下找到。


钱包

把管理数字密钥的软件称为钱包。备份钱包其实就是备份账户的私钥文件。
以太坊钱包分类:

  • Mnist以太坊钱包
  • Parity钱包
  • Etherwall钱包
  • Brain钱包等
    由于安装钱包时会运行一个完整的Geth节点,,所以打开钱包应用时就会开始在计算机上同步整个以太坊区块链。

保管私钥的目的是为了防盗(分离备份)、防丢(多处备份)、分散危险 (将资金适当地分散开,同时采取多重签名方式,提取超过事先预定的金额时需要多个密钥授权)

钱包备份有两种方式:

  • 多处和分离备份
  • 纸钱包(将keystore文件或者私钥以纸质的形式保存(通常是二维码))

数据结构与存储

以太坊针对三种对象设计了三颗Merkle树(Merkle Patrcia树),分别是状态树、交易树与收据树。
区块、交易等数据最终都是存储在LevelDB数据库中。LevelDB数据库是一个键值对(key-value)数据库,key一般与散列相关,value是存储内容的RLP编码。

以太坊使用了Merkle Patricia树(简称MPT),作为数据组织形式,用来管理用户的账户状态、交易信息等重要数据。MPT融合了Merkle树和Trie树(前缀树)两种数据类型的优点。
Merkle树具有以下特性

  • 每个数据集对于一个唯一合法的根散列值
  • 容易更新、添加和删除树节点,以及生成新的根根散列值
  • 任何人可以只提供一个到特定节点的分支,并且通过密码学方法证明拥有对应内容的节点确实在树里。

Trie树
Trie树也叫做Radix树。在Radix树中,key代表的是从树根到对应value的一条真实路径。即从根节点开始,key中的每个字符都代表从根节点出发寻找对应value所要经过的子节点。value存储在叶节点中,是每条路径的最终节点。若key中的每个字符都来自一个容量为N且所包含的字母都互不相同的字母表,那么树中的每个节点最多会有N个孩子,树的最大深度为key的最大长度。

Trie树的优点:若有两个value,且拥有基于相同前缀的key,它们相同前缀的长度占自身比例越大,则代表这两个value在树中的位置越靠近,并且Trie树不会有像散列表一样的冲突,即一个key仅仅对应一个value。

Trie树的缺陷:存储不平衡,即给定一个长度较长的key,在树中无其他key与它有相同的前缀,那么在遍历或存储key所代表的value时,将会遍历或存储相当多的节点,因此树是不平衡的。

Merkle Patricia树
为了保证树的加密安全,每个节点通过它的散列值被引用,用于在LevelDB数据库中的查询。对于存储在LevelDB数据库中的非叶节点,其在数据库中的表现形式为:key代表着节点的RLP编码的SHA3散列值,value是节点的RLP编码。要想获得一个节点的内容,只需要根据该节点的散列值访问数据库以获得节点的RLP编码,然后解码即可。

MPT中的节点

  • 空节点(一个空串)
  • 叶节点(一个键值对的列表,key是一种特殊的十六进制编码,value是RLP编码)
  • 扩展节点(键值对的列表,此value是其他节点的散列值,通过此值可以链接到其他人节点)
  • 分支节点(一个长度为17的列表。MPT中的key被编码为一种特殊的十六进制的表示,再加上最后的value,前16个元素对应key中的16个可能的十六进制字符,若有一键值对在此分支节点终止,则最后一个元素代表一个值,即分支节点即可以是搜索路径的终止,也可以是路径的中间结点)

MPT还有一个重要的概念:用于对key进行编码的特殊十六进制前缀编码(HP)。因为字母表中的字符都是十六进制表示的,故每个节点最多只能有16个“孩子”。因为键值对有两种表示形式的节点(叶节点和扩展节点),故需引用一种特殊的终止符标识,用于标识key所对应的值是真实的值还是其他节点的散列值。通过对终止符标识进行赋值,可以区分key所对应的节点的种类,无论key的长度是奇数还是偶数,HP都可以对其进行编码。

以太坊区块链系统中使用了MPT树结构,每个区块头为三种对象设计了三棵树,分别是交易树(Transaction Tree)、状态树(State Tree)、收据树(Receipt Tree)。利用三棵树,可以查询:

  • 交易是否被包含在区块中
  • 查询某个地址在过去30天中发出某种类型事件的所有实例
  • 账户余额
  • 账户的存在性
  • 若在某一合约中进行一笔交易,交易的输出是多少

计算前4项任务简单,只需要服务器根据查询需求找到对象,获得对应的Merkle树分支,即可得到结果并且返回给客户端。对于第五种查询,由状态数来处理。若在根为S的状态树上执行一笔交易T,其结果状态树将是根为S‘,输出为O’‘。服务器会在本地创造一个假的区块,将其状态设为S,并且假装是一个轻客户端,请求执行这笔交易并将执行结果返回给客户端。

以太坊中的状态树包含键值映射,其中键为地址,而值包括账户的声明、账户余额、nonce、代码以及每一个账户的存储。由于账户余额和账户的nonce经常改变,新的账户会频繁插入,存储的键也经常被插入以及删除,所以状态树需要经常更新。

状态树

状态树中的每个节点由16个孩子节点,每一个叶子节点表示一个账户,这些叶子节点的父节点由叶节点的散列值组成,而这些父节点在组成更高一层的父节点,直至形成根节点。状态树包含一个键值映射,其中键是账户地址,值是账户内容,主要是{nonce, balance,codeHash,storageRoot}。nonce是账户余额,codeHash是代码的散列值,storageRoot是另一棵树的根节点。状态树代表访问区块后的整个状态。

以太坊是一个以账户为基础的区块链应用平台,所有的账户状态都是以“状态数据”的形式存储在以太坊的节点中。区块链中的全局状态是账户地址(160位标识符)和账户状态(经过RLP编码序列化的一种数据结构)之间的映射。

状态数据是一种隐式数据,即需要从实际的区块链数据中计算出来,交易包含决定新状态数据的所有字段内容,以太坊区块包含了整个状态树的Merkle树根散列和交易列表。状态树是用来记录各个账户的状态的树,需要经常更新。

交易树

每个区块都有一个独立的交易树。不过矿工一般会根据交易的GasPrice和nonce对交易进行排序。首先会将交易列表中的交易划分到各个发送账户,每个账户的交易根据这些交易的nonce排序。每个账户的交易排序完成后,再通过比较每一个账户的第一笔交易,选出最高价格的交易,这是通过一个堆(heap)来实现的。每挖出一个新块,更新一次交易树。
在交易树包含的键值对中,其中每个键是交易的编号,值是交易内容。

数据树

每个区块都有自己的收据树,不需要更新,代表每笔交易的收据。其键值映射中的键是索引编号,用来指引这条收据相关交易的位置,值是收据的内容。交易的数据是一个RLP编码的数据结构:[medstate, Gas_used, logbloom, logs]。其中,medstate是交易处理后树根的状态;Gas_used是交易处理后Gas的使用量;logs是表格[address, [topic1, topic2, ···], data]元素的列表,表格由交易执行期间调用的操作码LOG0···LOG4生成(包含主调用和子调用),address是生成日志的合约地址,topicn是最多4个32字节的值,data是任意字节大小的数组;logbloom是交易中所有logs的address和topic组成的布隆过滤器(是一个二进制向量数据结构,具有很好的空间和时间效率,可以检测一个元素是不是集合中的一个成员)。区块头也存在一个布隆过滤器,可以减少查询的工作量,使得以太坊协议对轻客户端尽可能的友好。


数据库支持-LevelDB

LevelDB是一个高效的键值对数据库,键值都是二进制的。以太坊有三个LevelDB数据库,分别是BlockDB(保存区块的主体内容,包含区块头和交易)、StateDB(保存账户的状态数据)、ExtrasDB(保存收据信息和其他辅助信息)。

LevelDB的接口很简单,包括put(k, v)、get(k, v)和delete(k, v)。除此之外还有以下特性:

  • key和value都是任意长度的字节数组,一条记录默认是按照key的字典顺序顺序存储的。
  • 支持遍历,包括前向和后向。
  • 支持原子写操作
  • 支持过滤策略
  • 支持数据自动压缩(使用snapp压缩算法)
  • 底层提供了抽象接口,允许用户定制

除此之外还存在一定的限制:

  • 非SQL类型数据库,无关系模型
  • 单极系统无client-server

共识机制

共识机制是区块链事务达成分布式共识的算法。用于P2P网络中存在延迟,故各节点收到事务的顺序可能不一样,所以有必要设置一种机制让节点对在差不多时间内发生的事务顺序实现共识,这就是共识机制。

  • PoW
    因为工作过程繁琐而低效,而其验证忽视工作过程、直接认证结果,这样虽然需要花费一定时间完成工作,但是可以瞬间完成验证。PoW的目的是使区块的创建变得困难,阻止女巫攻击者重新生成区块链,确保网络的安全。女巫攻击是指在对等网络中,单一节点具有多个身份标识,通过控制系统的大部分节点来削弱系统安全性。

哈希函数特征:
免碰撞,不同输入一定对应不同输出
隐匿性,不能逆推输入值
除了穷举,别无他法

比特币的PoW算法:节点打包经过验证的交易,通过不断地更换随机数来探寻合适的散列值(指该值小于系统提供的某一散列值),当节点最先算出合适的散列值,所打包的快如果通过其他共识节点的验证则会被加入到区块链中。

以太坊的PoW算法——Ethash算法,使用后者替换前者是为了解决挖矿中心化问题。现在的情况是一些硬件公司和挖矿机构通过挖矿资源的集中,获得了可以操纵现有网络内经济力量的优势,并获得高利润(如比特币和莱特币)。这些组织可以生产具有超高散列计算性能的ASIC(Application Specific Integrated Circuit,特殊应用的集成电路),为自己赚取利润,打破了区块链的高度去中心化优势。为了抵制ASIC、轻客户端可快速验证,希望减少中心化挖矿在以太坊中获得经济奖励,这就是Ethash算法。

以太坊让挖矿者从区块链状态中获取随机数据,计算从区块链的最后N个区块中随机选择的交易,返回结果散列。好处:1)以太坊合约能包含任意种类的方式,以太坊的ASIC本质是一个提供普通计算的专门集成电路,可视为很好的CPU。2)挖矿需要访问整个区块链,这迫使挖矿者保存完整的区块链。

Ethash算法的特点是挖矿的效率基本与CPU无关,与内存大小、带宽正相关,目的是去除专用硬件的优势,抵抗ASIC。流程如下:

  1. 对每个情况,通过扫描区块头的方式计算出一个seed,这个seed只与该区块有关
  2. 用seed生成一个16MB的伪随机缓存,轻客户端会存储缓存
  3. 基于缓存生成一个1GB的数据集,称其为DAG。数据集中的每一个元素均只依赖于缓存中的某几个元素,即只要有缓存,便可快速计算出DAG特定位置的元素。挖矿者存储数据集,数据集随时间线性增长。
  4. 挖矿即为矿工从DAG中随机选择元素并且对其进行散列的过程,DAG也可理解为一个完整的搜索空间,挖矿就是从DAG中随机选择元素(类似于比特币试探合适nonce)进行散列计算。
  5. 验证者只需花少量内存存储缓存,因为验证者能基于缓存计算得到DAG中自己需要的指定位置的元素,之后验证指定元素的散列值是否小于某个散列值,即验证矿工的工作是否符合要求。

缓存和DAG中每增加30000个区块更新一次,故矿工一般会专注于读取数据集,而不是改变它。

验证过程和DAG产生的过程使用大量的散列计算,是PoW的具体体现。选择16MB的缓存是因为一个基于较小缓存的ASIC更容易生产,16MB的缓存仍然需要非常高的带宽读取,而较小的缓存更容易优化。将DAG的大小设为1GB,使其内存大于大多数专门的存储器和高速缓存器。但是对于普通的计算机而言它仍然足够的小,能利用它挖矿。

  • PoS
    PoS则基于网络参与者目前所有的数字货币的数量和时间进行利益分配,是一种对货币所有权的证明。PoS可以描述为虚拟挖矿,用户所得利益与购买成本成比例,即买的越多收获也就越大,耗电较小。PoS用来区块链自身的代币保证系统安全性。

PPC(Peercoin,点点币)和NXT(未来币)使用的PoS算法表达方式不同。PPC使用PoW/PoS混合模式,用PoW解决货币产出的公平性,用PoS来保证网络安全,在其PoS中,每秒钟选择一个不同的验证者来产生区块。NXT则是100%采用PoS模式,基于账户余额调整用户被选择出块的可能性,并使用一个确定性算法随机选择一个股东来产生下一个区块。

拜占庭容错是对现实网络问题的模型化,由于硬件错误、网络拥塞或者断开以及遭到恶意攻击,计算机和网络可能出现不可预料的行为。拜占庭容错协议必须处理这些失效,并且这些协议还要满足所要解决问题要求的规范。

以太坊的PoS算法可以这样描述:以太坊区块链由一组验证者决定,拥有以太币的用户均可以发起一笔特殊形式的交易,将自己的以太币锁定在一个存储中,从而使自己称为验证者,通过当前验证者均可以参与的共识算法,完成新区块的产生和验证。

有两种类型的PoS:基于链的PoS和BFT(Byzantine Fault Tolerant,拜占庭容错)风格的PoS:

  • 在基于链的PoS中,该算法在每个时隙内伪随机地从验证者集合中选择选择一个验证者,给与验证者创建新区块的权利,但是验证者要确保该区块指向最多的块(指向的上一个块为最长链的最后一个块)
  • 在BFT风格中的PoS中,分配给验证者相对的权利,让其有权提出块并且给被提出的块投票,从而决定新块,并且在每一轮选出新块入链。每一轮验证者都为特定的块投票,所有在线和诚实的验证者都将商量被给定的块是否可以被加入到链中,意见不能变。

以太坊的每个节点都必须承担确认和验证交易的责任,这才是去中心化的管理模式,能够提高利益相关者在网络中的参与度。

未购买以太币的人无法对系统产生威胁,也就是说攻击者在系统中。

PoS的优点:

  • 耗电少。通过发行新币以激励参与者继续参与网络活动的压力会减少。
  • PoS促进区块链技术的发展。矿工从消耗大量资源的挖矿行为解放,将算力转向区块链技术的开发应用上,促使区块链技术的蓬勃发展。
  • 随着规模经济(扩大生产规模引起经济效益增加的现象的消失),中心化带来的风险减少。不会有投入大量资金却收不到相应的回报这种现象的发生。
  • PoS更安全

以太币

ETH,以太币来源包括:矿前+区块奖励+叔区块奖励+叔区块引用奖励:

  • 预付款的贡献者共有6000万个以太币
  • 奖励挖出区块的矿工5个以太币
  • 叔区块——挖出的不在主链的块,如果该块在之后的区块链中作为叔区块被引用,每个叔区块会为挖矿者产出4.375个以太币,即叔区块奖励。引用一个叔区块,可以得到0.15个以太币(最多引用2个)

以太币发行每年是1800万。理论上如果这个发行量是无限期的,则在某种程度每年创造的代币和丢失的差不多(如私钥丢失,持有人死亡),会达到动态平衡。

当前以太币使用幽灵协议(GHOST),自2018年,以太坊使用新的协议算法(Casper)代替当前的工作量证明机制,效率更高且需要更少的挖矿补贴。在Casper协议下以太币的发行率将大大低于幽灵协议下的发行率。

以太币有各种面额,最小的单位是wei(维),下面是主要货币单位:
在这里插入图片描述
以太坊上的账户管理和智能合约的部署都要花费以太币。挖矿奖励有两种:

  • 静态奖励:·每次挖出一个新块,可获得5个以太币
  • 动态奖励:矿工挖出区块包含的所有交易费归矿工所有,若区块有叔区块,可以从叔区块引用获得额外的挖矿奖励的1/32,约0.15个以太币,每个区块最多引用2个叔区块,被引用的叔区块不能重复使用。

以太坊出块时间为15s。

可以通过购买或者挖矿获得以太币,下面介绍几种可以获得以太币的交易所:

  • Coinbase,虽然目前在中国不能交易
  • CEX.io,是比特币交易所了,也支持以太币交易,交易率较高,也就是一个币在此平台上所需花的钱比其他平台上花费的钱要贵,但是它支持全世界交易
  • Bittrex,企业、个人均可以购买或出售最新的加密虚拟货币,可以快速执行交易。对所有的交易和API的使用都要求提供双验证,安全性高,操作简单,随时同步交易,用户体验好

交易

交易是指账户发送到区块链上另一账户的消息的签名数据包,包含发送者的签名、接收者的地址以及交易的以太币的数量。有手续费,用于支付交易所需要的计算开销。引入Gas作为执行开销的基本单位,提供Gas price与以太币进行换算,Gas price随市场波动调整,避免以太币价值受到市场的价格影响

为避免无意义交易,浪费矿工计算资源,所有公有链都采用交易收费,要求为每笔交易付出一定的代价。这笔交易费会由打包交易加入主链的矿工收取。比特币付出的交易费相对固定,而以太坊引入的智能合约,创建和调用的交易所耗费的计算差别较大,因此引入了Gas,Gas price。

  • Gas
    用来衡量交易所耗费的计算资源。对于转账,矿工根据转账的金额对发送方与接受方的余额修改,对于创建和调用智能合约的交易,矿工会根据对应的字节码在EVM执行相应的操作。当所需计算步骤越多、越复杂,就说交易消耗的Gas越多。
    在这里插入图片描述
    部分步骤比其他步骤成本高,是因这些步骤在计算上是昂贵的或者是因为增加了在状态中的需要存储的数据量。根据交易的 计算步骤可以累加得到交易消耗的Gas。
  • Gas price
    Gas价格是一单位Gas需要的手续费(以太币),如假设Gas price为1Gwei/Gas,则交易消耗21000Gas代表交易手续费为0.000021以太币。
    一般矿工会对接受到的交易进行按照Gas price或Gas * Gas price从小到大排序,以确定那些交易被先纳入区块中。为了让矿工尽快接受一笔交易,发送者可以提高交易的Gas price,以激励矿工。
  • Gas Limit
    Gas限制:对于单个交易,Gas Limit表示交易发送者愿意为这笔交易执行所支付的最大Gas数量,需要发送者在发送交易时设置;对于区块来说,Gas Limit是单个区块所允许包含的最大Gas总量。
    Gas Limit可以保护用户免受错误代码影响以致消耗过多的交易费。由于发送者可能无法准确估计交易消耗的Gas,如某个调用智能合约的交易会根据这执行时间触发不同的操作。设置合理的Gas Limit以后后,若实际消耗的Gas小于Gas Limit,则矿工只会收取实际的计算开销对应的交易手续费(Gas used * Gas price);若Gas used大于Gas Limit,则矿工在执行时会发现Gas已被耗尽而交易没有完成,此时矿工会回滚到程序执行前的状态,而且收取Gas Limit 对应的手续费(Gas price x Gas Limit)。也即Gas price x Gas Limit表示用户愿意为交易支付的最高金额。
    若没有Gas Limit限制,恶意用户可能会发送一个数十亿步骤的交易,并且无人处理,因为处理交易会花费很长时间,然而矿工不知道,所以会导致拒绝服务式攻击。

至于区块的Gas Limit,表示区块包含的交易消耗的Gas的上限,由矿工决定其大小。总之,被打包交易的Gas Limit数量之和不能大于区块的Gas Limit。

区块的Gas Limit设置的越大,矿工收取的交易费越多,但是需要更多的带宽,叔区块出现的频率也会增大,使得挖出的区块无法形成最长的交易链。矿工不能随意更改区块的Gas Limit,以太坊规定当前区块的Gas Limit只能基于上一个区块的Gas Limit上下波动的1/1024。

交易内容
以太坊的交易是指存储从外部账户发送到区块链上另外一个账户的信息的签名数据包,可以是数字货币——以太币的转账,可以是包含智能合约的信息。一条交易包含以下:

  • from:发送者的地址,必填
  • to:接受者的地址,为空则意味这是一个创建智能合约的交易
  • value:发送者要转移给接收者的以太币的数量
  • data(/input):存在的数据字段,存在则表明交易是一个创建或者调用智能合约的交易
  • Gas Limit:表明交易允许消耗的最大Gas量
  • Gas price:表示发送者愿意支付给矿工的Gas价格
  • nonce:用来区别同一用户发出的不同交易的标记
  • hash:由以上信息生成的哈希值,作为交易的ID
  • r、s、v:交易签名的三个部分,由发送者的私钥对交易hash进行签名生成

交易有三种类型:

  • 转账交易:只需指定交易的发送者、接受者、交易的以太币数量(在客户端发送交易时,Gas Limit、Gas price、nonce、hash、签名可以按照默认方式生成),如下:
web3.eth.sendTransaction({
	from: "safd7tsadf6tadsfrasd5sadf6t87saf5987asdf"
	to: "asfdadsfasdvy76sadv87dsa6vas76dvcasdfdr5"
	value: 1000000000
});
  • 创建智能合约的交易:创建合约是指将合约部署到区块链上,也是通过发送交易实现的。在创建合约的交易中,"to"是一个空字符串,在"data"中指定初始化合约的二进制代码,在合约被调用时,该代码的执行结果将作为合约代码,如下:
web3.eth.sendTransaction({
	from: "0xsadyf76fdsadfr4a5sdfd9875sadv"
	data: "contact binary code"
});
  • 执行智能合约的交易:该交易是为了执行已经部署在区块链上的智能合约,需要将"to"指定为要调用的智能合约的地址,通过"data"指定要调用的方法以及向该方法传递参数,如下:
web3.eth.sendTransaction({
	from: "0xafds65dsafasdfas45dfasf5387"
	to: "0xads987fadsffvafasdf2as65d7f87"
	data: "hash of the invoked method signature "
})

下面是一个查询交易的例子

web3.eth.getTransaction('0x3sda5c46dsa8cas8d7f9a8ds7f809sadf9')
{
	blockHash: '0xdsa97fasdfasdfa0987dsfa6fdsfdsa',
	blockNumber: 23412,
	from: '0xds6fasdfasdgf45asdf64sadf86asddsafda',
	Gas: 9000,
	Gas price: 50000000000000000000,
	hash: '0xasfdsadf5sadgy5sad46f75dsa98f609dsd';
	input: '0x',
	nonce: 32142,
	to: '0xdasf7df6adsfa45987sadsf6sadf897sadfysad';
	transactionIndex: 0,
	value: 1234123412340000	
}

用户可以使用sendTransaction执行一个交易,下面的代码就是一个简单的发送交易的示例,若想使用其他单位,可以使用web3.toWei进行转换

eth.sendTransaction({from: "0xdsafsadfasdfsa87d597586sadf", to: "0xds64fdsa4f5a86f7a9sd6asd", value: web3.toWei(1, "ether")})

数据编码与压缩

RLP(Recursive Length Prefix,递归长度前缀法)是一种编码方法,用于编码任意的具有嵌套结构的二进制数据,是以太坊数据序列化的主要方法。以太坊中的区块、交易等数据结构会先经过RLP编码处理,然后存储到数据库中。RLP编码只处理两种类型的数据,即字符串和列表,并不包括原子数据类型,如整型、浮点型等。在RLP格式中,对字典数据的编码有两种建议方式:一种是按照字典顺序用含关键字的二维数组来表示,如:[[k1, v1], [k2, v2]… ],另一种是使用更高级的Patricia树来编码。

在以太坊中,当发送数据以及在MPT树中保存状态时,需要使用RLP编码。在用RLP编码处理的数据中,字符串一般指的是一串二进制数据,列表则是一个嵌套递归结构,列表元素可以是字符串或列表,通过这种方式可以实现数据的递归存储,如[“red”, [“blue”, “white”], purple]就是一个具有嵌套递归结构的列表。若要使用RLP编码对其他类型的数据进行处理,必须要将其转换成上述两种类型,RLP没有定义转换规则,用户可以按照自己的规则转换,如结构体可以转换为列表,int可以转换为二进制数(属于字符串一类)。

RLP的编码规则如下:

在这里插入图片描述


以太坊客户端与API

以太坊客户端是由以太坊基金会和以太坊研究组织开发的,供用户使用的人机友好的操作软件。使用客户端,用户可以在本地计算机上创建以太坊节点,还可以执行建立在以太坊上的去中心化应用,进行一些以太坊交易活动。

常用的以太坊客户端:

  • Go-ethereum客户端:由Go语言实现,也称为Geth,是一个命令行界面,可以在Go语言实现的以太坊全节点上执行,是以太坊推出的官方客户端。
  • Parity客户端:Rust语言实现的。
  • CPP-ethereum客户端:C++实现。
  • Pyethapp客户端:Python实现,利用两个以太坊核心部分来实现客户端:pyethereum——核心库,特征是区块链、EVM、挖矿;pydevp2p——点对点网络库,特征是能发现节点、多路复用的多业务传输、连接加密。
  • EthereumJ客户端:由以太坊协议的纯Java方法实现。
  • ethereumjs-lib客户端:由JavaScipt实现,是核心以太坊功能的一个JavaScipt库

除此之外还有EthereumH(Hashell实现),Ruby-ethereum(Ruby语言实现)等以太坊客户端。

API(Application Programming Interface,应用程序编程接口)是一些预定义的函数,目的是提供应用程序与开发人员基于某些软件或硬件直接访问一组程序的能力。用户通过调用API可以直接获得某些服务,而无需了解内部细节。

JSON-RPC是一个无状态、轻量级的远程过程调用(Remote Process Call)协议,这个规范首先定义了几个数据结构及其处理规则,数据格式为JSON。

目前有两种数据类型是通过JSON传递的:无格式字节数组和数,二者均使用十六进制进行编码传递,但是对传递格式有不同的要求。

JSON-RPC API是较低等级的JSON-RPC2.0接口,其功能是与节点进行交互。

通过内部的JavaScipt应用通知一个以太坊节点使用Web3.js库,为RPC方法的使用提供了方便的交互界面。要让应用程序在以太坊上运行,可以使用Web3.js库提供的Web3对象。通过RPC调用Web.js可以与本地节点进行通信,并且能与RPL层次上的任何以太坊节点一起工作。


以太坊域名服务

ENS(Ethereum Name Service,以太坊域名服务)是建立在以太坊区块链上的分布式、开放的命名系统。在以太坊网络中,地址比较长而复杂,记忆困难,为方便用户,以太坊推出可以将散列地址翻译成一个简短易记的地址的ENS命名服务。

ENS由三个主要构件组成,分别是注册表(registry)、解析器(resolver)和注册服务(registrar)。其中注册表是系统的核心不可变的部分,解析器最终由用户实现,注册服务是在ENS中拥有名称并根据规则分配子域的智能合约。ENS是以太坊基金会提供的去中心化应用。ENS做了两件事:1)使用户注册支持智能合约运行的域名;2)利用底层设备标识符解析部分域名。

用户要想获得域名的所有权,主要通过竞拍的方式。

用户注册一个域名需要以下过程:
在这里插入图片描述
在这里插入图片描述
以太坊提倡:用你觉得合理的价位竞标你真正需要的ENS

猜你喜欢

转载自blog.csdn.net/qq_40061206/article/details/91890599
今日推荐