先回顾一下知识:以太坊ethereum是一个去中心化平台,可以在上面运行使用智能合约编写的DApp。使用以太坊的优点是,可以多个智能合约一起构建DApp不用担心交互问题
智能合约:完全按照程序运行,防停机、审查、诈骗还防止第三方干扰。在以太坊部署只能合约需要使用到以太坊的内部货币以太币。
以太坊使用区块链数据结构和工作量证明共识协议
常用的智能合约Solidity、LLL和Serpent。#这里我学习的是Solidity。
节点:分为普通节点和矿工。顾名思义普通节点只是备份了数据,而矿工是通过挖矿创造区块链
1.以太坊账户:要创建以太坊的账户需要一个非对称加密密钥对通过不同的算法生成如(RSA,ECC等)这里不深入了解。以太坊使用256位加密(它的公钥/私钥是一个256位数0。由于处理器不能表示这么大的数所以它被编译成长度位64的十六进制字符串。每一个账户用一个地址表示。有了密钥之后就生成地址:1.生成公钥的keccak-256哈希。会给出一个256数字第二步:去除前96位剩下160位就是20个字节(一个字节8位一个字四位)第三步把地址编译成十六进制的字符串最后得到一个40字符的字符串就是账户地址。任何人可以给你以太币
#难度值公式(current_block_difficulty = previous_block_difficulty + previous_block_difficulty // 2048 *max(1-(current_block_timestamp-previous_blocktimestamp) // 10,-99)+int(2 ** ((current_block_number //1000000)-2))
2.交易: 1.定义 交易是一个签名数据包,从一个账户向另一个账户或一个合约转以太币/调用合约方法或者部署一个新合约。交易采用的是椭圆曲线数字签名算法(ECDSA)
2.签名:ECDSA是一种基于ECC的数字签名算法。
3.交易流程:交易包含了信息接收者,识别发起人和意愿的签名以及要转账的以太币数量。交易执行允许进行的计算资源最大值叫做gas上限(自我理解就是总量的最大值),而交易发起人愿意为单位计算资源支付的费用叫做gas价格(自我理解就是单价)。
若交易的目的是为了调用合约:则还包括了输入数据
如果目的是部署合约: 还包含了初始化代码
将gas*gas价格 = 交易费。为了发送以太币或执行合约方法,需要向网络广播交易。发起人需要用私钥签署交易
交易确定:如确定交易将永远出现在区块链中,就称为交易已确定(文中推荐在假设交易已确定之前,等待15个确定(15个区块产生在交易所在的区块后面))(应该是一种判定办法防止受骗)
4.共识(必备知识):
复习一下区块链知识:区块链的区块没有限制,以太币的总数也没有限制。区块有一个区块头(head)和包含的一系列交易,每一个区块都含有前一个区块的hash至,用此来链接每一个区块。head包含了很多content(内容)是区块包含的交易列表。head含有前一个区块的哈希值,区块序号,随机数(nonce)、目标值(target)、时间戳(timestamp)、难度值(difficulty)、矿工地址address等内容。timestamp是表示区块的初始时间,而随机数nonce是一个没有意义的值,只是一个小于等于目标值的区块哈希。以太坊使用的是ethash算法,随机数的唯一方法是穷尽所有可能,目标是一个256位的数字根据不同的因素计算。head的难度是目标值target的表达方式,target跟随机数成反比,target低则nonce越多发现nonce的时间也就越多。计算问题的难度值公式如下(current_block_difficulty = previous_block_difficulty + previous_block_difficulty // 2048 *max(1-(current_block_timestamp-previous_blocktimestamp) // 10,-99)+int(2 ** ((current_block_number //1000000)-2))。网络中任何节点都可以检查是否合法。首先检查交易在区块链中是否合法已经时间戳的验证然后检查target和nonce和miner是否得到合法的汇报。如果节点收到了两个不同的合法区块那么整体难度高的被视为合法区块
以太坊网络中的每个节点包含区块链的备份,用户需要确保该节点不能串篡改区块链,还得有个机制检查区块是否合法。
以太坊使用工作量证明共识协议来防止区块链被篡改。而工作量证明系统需要解决一个复杂问题来创造一个新的区块需要大量的算力。这个间接使得创建区块非常困难。在这个系统中创建区块称为矿工miner,miner是网络中挖区块的节点。使用工作量证明的DApp不一定用同样的算法,算法取决于矿工。
矿工:对于矿工而言,第一个解决问题的是胜利者可以得到5个以太币已经该节点的所有交易费用。对于矿工而言好的处理器是必要的但不是绝对的。矿工一旦成功挖到区块就会向网络中的所有其他节点广播这个区块。矿工需要解决的问题有:首先要从收到的广播中收集新的/没有被挖出来的交易,然后过滤掉不合法的交易。(合法的交易必须包含:1。争取是使用私钥签名。2.账户有足够的余额。)矿工创建一个有head和内容的的区块。head前面有提到。content是区块包含的交易列表。
Timestamp时间戳:计算target的目标值要用到时间戳。但是时间戳是矿工自己修改的。但区块链早已经准备好了防止miner自己修改timestamp的情况,因为timestamp的验证会失败。细讲验证可以忽略(如果miner使用的timestamp大于当前的timestamp会使得难度值低,因为难度值跟timestamp成反比,而两个区块如果一个比一个难则会认为难的是合法区块。而如果使用大于上一个timestamp而小于现在的timestamp会使得难度值大,很容易被别人挖了。所以基本上没miner修改timestamp)
nonce随机数:nonce是一个64位未签名的证书。miner通过不断的尝试nonce而发现target。但是每一个区块的hash值取决于timestamp和address所以更是靠运气。
区块时间:通过难度公式可以看到使用了一个10s的阈值来确保父区块和子区块的时间差在10s-20s以内。难度值和区块时间成正比(区块时间相当于交易时间)深入则太过复杂
forking分叉:在节点认证区块链发生冲突的时候会发生分叉forking。在网络中有大于一个区块链,且每个区块链都由一些矿工验证了的。分叉分三种:普通forking和软forking以及硬forking
普通分叉:是由于两个或多个miner同时发现了区块引起的暂时冲突,当一个的难度值较高的时间就解决了因为难度值高的为合法区块
软分叉:更改源代码需要有百分之50以上算力的miner升级来解决冲突
硬分叉:需要所有miner升级来解决冲突
genesis block创世区块:是区块链的第一个区块,跟数组一样他的序号是0,是唯一一个不指向前一个区块的区块,也不包含交易。两个对等节点需要同一个创世区块才能够同步。高难度genesis block也不能代替低难度的genesis block。genesis block是被硬编码到客户端里的
以太币的面值:
1以太币=math.pow(10,18)wei=pow(10,15)Kwei=pow(10,12)Mei=(10,9)Gwei=(10,6)Szabo=1000Finney=0.001Kether=(10,-6)Mether=(10,-9)Gether=(10,-12)Tether
以太坊虚拟机(Ethereum Virtual Machine,EVM):是以太坊智能合约节码(byte-code)的执行环境。每一个peer都运行EVM。所有的peer执行使用EVM指向智能合约的全部交易,进行同样的计算和储存同样的数值。每个节点执行并储存最后状态就行了。每个交易需要有计算和存储因此就需要交易费否则全是垃圾交易,而且没有交易费给矿工。介于交易的计算和存储量不同而成本不同。
如何实现EVM,有两中字节码VM和JIT-VM。这两种情况下Solidity代码都被编译成字节码(字节码(Byte-code)是一种包含执行程序,由一序列 op 代码/数据对组成的二进制文件,是一种中间码。字节是电脑里的数据量单位。)JIT-VM的字节码编译更加充分,JIT-VM比VM更高效。
gas(燃料)是计算资源的计量单位。每一个都包含了gas上线和gas价格(每次计算的价格相当于单价)。矿工可以选择接纳交易和收取费用。如果gas小于等于上限则交易继续。如果gas超过了上限则会撤销所有的修改(除了依然合法和miner收到的费用)(费用可以是gas最大值*gas价格)gas价格由miner来决定,如果gas低了miner可以拒绝交易。gas价格以wei为单位。EVM的每个操作都分配了一个numb了来表示可以消耗的gas。交易成本影响账户转给另一个账户的上限如:A账户又2个以太币则不能全部转给另一个账户,因为所有以太币转走了就没有余额支付交易费用了。如果是调用合约,则从调用合约的账户扣除交易费
发现对等节点:peer是网络的一部分,需要跟其他peer连接,这样这个peer才能广播交易/区块,并且监听新的交易/区块。但是节点不用连接每一个节点,只要连接到几个节点,然后 这些节点再连接到其他节点。但是peer应该如何发现其他的peer呢,没有中央服务器如何交换信息?以太坊有自己的节点发现协议用来解决这个问题,这个协议是以Kadelima协议作为基础。在节点发现协议中有一种特殊的peer,叫做Bootstrap(初始启动)节点。Boostrap节点保存了一段时间内与它们连接的所有节点列表,但是它本身不保存区块链。当对等节点连接到以太坊网络的时候,首先连接到bootstrap节点。Bootstrap节点分享在刚才事先定义的时间里连接到的对等节点列表,然后对等节点与对等节点连接同步。bootnade是以太坊Bootsrap节点的热门,想实现自己的bootstrap可以使用bootnode
Whisper和Swarm:Whisper是去中心化的通信协议而Swarm是去中心化的存储平台(去中心化的文件系统)Whisper允许节点互相通信,知错广播,用户到用户以及加密信息但是不能用于传输大数据。Swarm类似与Filecoin。区别在于 Filecoin不惩罚存储,而Swarm惩罚存储因此提高了文件的可用性。Sware没有内部货币用的是以太币来进行激励机制。在以太坊中有智能合约来记录激励情况。但是智能合约能与Swarm通信,而Swarm不能和智能合约通信。因此用户通过智能合约向存储付款,然后支付失效后被释放给了存储,用户还可以向智能合约报失文件。在这种情况下可以惩罚存储。
geth(go-ethereum):是将以太坊、Whisper和Swarm节点的一个实现。geth可以全部实现或者成为一些选定实现的一部分是一种CLI应用,由go语言编写。CLI(command-line interface意思就是命令行实现。可以在众多操作系统中安装:支持二进制和脚本安装。我使用的是linux:
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum
geth为其它应用提供了通信的JSON-RPC API(JSON-RPC,是一个无状态且轻量级的远程过程调用(RPC)传送协议,其传递内容透过 JSON 为主。JSON(JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。)API。geth使用http、WebSocket和其它协议服务于JSON-RPC API JSON-RPC提供的API分成了:admin,debug,eth,miner,net,personal,shh,txpool和web3等类型。geth还体哦那个了和JavaScript操作台用于JavaScript API进行程序交互。#API表示内部自带函数。
geth的子命令和选项:(一些重要的):1.连接至主网网络,ethereum的节点默认用30303端口通信。只需要运行geth命令就可以连接到主网网络:如:
geth --data敌人 "/users/packt/ethereum" --networkid 1 这个例子中--datadir 选项用来指定存储区块链的地址,如果没有默认在“$HOME/.ethereum"中 --networkid用来指定网络id。1表示主网id,如果没有默认是1。2代表的是测试网络ID
2.创建私有网络:
要创建私有网络只需要给出一个随机网络ID。通常创建私有网络的目的是进行开发。geth还提供了多个与日志和调试相关的标记(flag)对于开发很有帮助。可以简单使用--dev标记运行一个私有网络,这个网络允许多个与日志和调试相关的标记而且不用给一个随机网络ID 并且放上多个与日志和调试相关的标记。
3.创建账户:
geth允许创建账户(生成密钥和相关地址)geth account new (需要输入密码如果密码忘记了就不能访问账户了) geth account list可以获得所有账户的列表。密钥默认存储在--datadir路径中的,但是用户可以用--leystore来指定不同的目录
4.挖矿:
默认的geth是不启动挖矿的,提供--mine选项就可以挖矿了。
--mine选项表示开启挖矿 --minerthreads是用来指定哈希过程中使用的线程总数默认八个,ethert、base是回报存入的地址/账户默认是加密的 --unlock是解码账户,解密用于解码账户相关的密钥,而用于挖矿不需要解锁。--unlock可以解锁多个账户 用逗号做分隔符就好 --minergpus用于指定挖矿使用的GPU,可以使用geth gpuinfo命令来得到GPU列表 #GPU(Graphics Processing Unit)图形处理器每个GPU需要1-2G的RAM(Random Access Memory,缩写:RAM),也叫主存,是与CPU直接交换数据的内部存储器,是一个随机存区存储器)默认不适应GPU使用CPU。
2.快速同步:有时候区块链太大直接下载缓慢,以太坊实现了一种快速同步算法可以更快下载区块链(fast synchronization)不下载整个区块只下载区块头交易凭证和最新的状态数据库。需要在geth过程中使用--fast。(出于安全考虑)fast sync只在初始同步时运行,在节点成功与网络同步后就禁用该选项。
以太坊钱包:是一个以太坊UI客户端(User interface是软件和人交互的软件类似QQ啥的)允许创建账户、发送以太币、部署合约、调用合约等。以太坊钱包与geth是捆绑在一起的。运行时会与本地geth连接,如果geth没有运行、就会启动自己的geth节点。ethereum钱包使用IPC与geth通信(Inter-Process Communication表示进程间的通信)在geth运行的时候更改数据目录也就是在改IPC文件路径、为了让以太坊钱包发现并连接到geth需要使用--ipcpath选项指定IPC文件位置为默认位置,这样以太坊钱包可以发现他。通过geth help可以找到--ipcpath选项的默认路径 可以在https://github.com/ethereum/mist/releases上下载以太坊钱包。
浏览器钱包(Mist)是以太坊、Whisper和Swarm的一个客户端,允许在上面交易和发送Whisper信息、检查区块链。Mist和geth的关系就跟以太坊钱包关系一样但是Mist带有浏览器,目前可以使用的JS是web3.js库
以太坊的缺点:一样面临着Dos攻击已经源代码可能有bug:1.采用Sybil攻击。2.如果攻击者掌握了百分之51以上的算力基本上就可以统治该区块链。