以太坊

什么是以太坊 简单来说,以太坊就是一个基于交易的状态机。什么是状态机呢?可以将其理解成一台机器,这台机器维护着一些状态,在以太坊交易发生时,这些状态会从一个状态转化到另一个状态。以太坊时基于区块链构建的,区块链上保存着状态和交易。当我们与以太坊交互时,其实就是在执行交易、改变系统状态。 引用一个公式表示就是: σ′ =Υ(σ,T) Υ是状态转换函数,T是交易,σ是状态,σ′转换后的状态。 从创世区块开始,无尽的交易不断的刷新着系统当前状态,每产生一个区块就对当前状态做一次快照(patricia trie根)存入区块头中。 以太坊可以干什么? 以太坊作为一个开发的区块链平台,它允许任何人在平台中建立和使用通过区块链技术运行的去中心化应用。可将之类比为Internet平台,而我们可以在其上面开发web网站。(但是似乎在以太坊上面只能开发智能合约?) 什么是智能合约? 智能合约就是以太坊平台上运行的程序。一旦事件触发合约中的条款,代码自动执行。智能合约的功能是由开发者自行设计的。 智能合约的工作原理 构建 → 存储 → 执行 智能合约由区块链内的多个用户共同参与制定,可用于用户之间的任何交易行为。协议中明确了双方的权利和义务,开发人员将这些权利和义务以电子化的方式进行编程,代码中包含会触发合约自动执行的条件。比方说,你把一套闲置的房子租给A,那么,这份智能租约中就规定了A必须在每月5号之前给你打房租、你必须在收到房租时马上给对方钥匙[2]等条款。 一旦编码完成,这份智能合约就被上传到区块链网络上,即全网验证节点都会接收到你和A的租房合约。 智能合约会定期检查是否存在 相关事件和触发条件;满足条件的事件将会推送到待验证的队列中。假设A在4号提前打房租给你,这个事件就成了该合约的触发条件(每月5号以前)。 区块链上的验证节点先对该 事件进行签名验证 以确保其有效性;等大多数验证节点对该事件达成共识后,智能合约将成功执行,并通知用户。 成功执行的合约将移出区块。而未执行的合约则继续等待下一轮处理,直至成功执行。 部署到以太坊上的智能合约是要消耗以太币的。就好像把现实中的仲裁人、法官、执行人搬到了区块链上,尽管他们成了一行行的代码,但也是珍贵的计算机资源。智能合约也遵循“Less is more”,逻辑应尽可能地简单。逻辑越复杂,消耗的以太币就越多。 既然执行要消费以太币,如何支付呢?智能合约是预支付,为了合约顺利执行,一般提前多打一点以太币。如果预支付的以太币不足以支撑整个执行过程,就算进行到半路,合约也会回到初始状态;并且消耗的以太币也不会退回给合约发起人。 如何触发智能合约? 智能合约本身规定了触发的条件,只要满足了条件的情况下,合约就会自动触发(比如时间到了自动缴房租)。也可以由外部账户触发。 以太坊的区块结构 区块链上最重要的结构莫过于区块的结构,以太坊的区块结构和区块链的类似,但是又有着诸多不同。 以太坊区块是由三大部分组成:区块头,叔块,交易列表。 区块头由15个字段组成。 叔块其实就是孤块,是由于某个区块上产生了多分支。因以太坊出块速度很快平均十几秒就会打包生成一个块,所以矿工挖矿的竞争性很高,可能同时产出几个都合法的区块,以太坊为了一些安全性起见,允许竞争块也挂在到主链上,同时给与挖出这些孤块的矿工们少许奖励增加工作的公平性。这些孤块最多允许6个高度,这也是6个区块确认主链说法的来源。 交易列表,存储的是本区块中所有的交易内容。 看一下一个实际的区块信息: "blocks" : [ { "blockHeader" : { "bloom" : "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "coinbase" : "0x3535353535353535353535353535353535353535", "difficulty" : "0x020000", "extraData" : "", "gasLimit" : "0x05f5e100", "gasUsed" : "0x014fa1", "hash" : "0x39f4659b079e257df8fd7e699528531e97a6b8a442ca0d11200c4a2f7433c483", "mixHash" : "0x7379f33af4ae2db7e293f808a165135d0b1a99572cc96fb9f7d17ef64a751969", "nonce" : "0x8e08d7aabeee8773", "number" : "0x01", "parentHash" : "0xadbef3bf0b3b7b14f6e7b1a45d240ecc863543a279a86c23f60170e8e7a6bcc3", "receiptTrie" : "0xb21660268480338c0cd0613358315359b619bd527d5850949c4863cddaec316b", "stateRoot" : "0xde4ce9b5b2f88ab1680962c64281224b1743bdf94bd6a9e390ea779ff616c1f7", "timestamp" : "0x03e8", "transactionsTrie" : "0x56445ba866f3e41851154fb8700dcec8556a178f1833021e030b8a47b494769d", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, "rlp" : "0xf90308f901f9a0adbef3bf0b3b7b14f6e7b1a45d240ecc863543a279a86c23f60170e8e7a6bcc3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347943535353535353535353535353535353535353535a0de4ce9b5b2f88ab1680962c64281224b1743bdf94bd6a9e390ea779ff616c1f7a056445ba866f3e41851154fb8700dcec8556a178f1833021e030b8a47b494769da0b21660268480338c0cd0613358315359b619bd527d5850949c4863cddaec316bb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018405f5e10083014fa18203e880a07379f33af4ae2db7e293f808a165135d0b1a99572cc96fb9f7d17ef64a751969888e08d7aabeee8773f90108f90105460183030d4094c305c901078781c232a2a521c2af7980f8385ee980b8a430c8d1da000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000001ba021a28cc82b40931239f8653ffa5300e1a506c0ef7fb79a663772cafe6558ab44a075af23441f7f176a2770af41142c77b671391209b15d59144e7a1332179b5e14c0", "transactions" : [ { "data" : "0x30c8d1da000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", "gasLimit" : "0x030d40", "gasPrice" : "0x01", "nonce" : "0x46", "r" : "0x21a28cc82b40931239f8653ffa5300e1a506c0ef7fb79a663772cafe6558ab44", "s" : "0x75af23441f7f176a2770af41142c77b671391209b15d59144e7a1332179b5e14", "to" : "0xc305c901078781c232a2a521c2af7980f8385ee9", "v" : "0x1b", "value" : "0x00" } ], "uncleHeaders" : [ ] } ] 区块头的结构 区块头包含15个字段,介绍如下:...

October 6, 2018 · 2 min · Theme PaperMod

区块链的运转流程

区块链的运转流程 当一笔交易经由某个节点或钱包产生时,这笔交易需要被转播给其他的节点来做验证。 产生一笔新交易 一笔新交易产生时,会被广播到区块链中的其他参与节点 各节点将多笔交易一起放进区块 每个节点会将数笔未验证的交易的hash值收集到区块中,每个区块可以包含数百笔或上千笔交易 决定由谁来打包区块 各个节点进行POW,来决定谁可以获得区块的打包权,由最快算出结果的节点打包该区块 各节点验证打包的区块 其他节点会确认这个区块所包含的交易是否有效,确认没被重复花费且具有有效数位签章后,接受该区块,此时该区块才能正式接上区块链 交易验证完成 所有节点一旦接受该区块后,先前没计算完POW工作的区块将会失效,各节点会重新建立一个区块,并开始下一轮POW计算工作 Q&A 节点如何验证某个区块的有效性? 当某个节点收到某个区块后,需要验证的信息有三个: 区块编号有效 对区块的header进行2次hash计算,计算出来的值就是当前区块的hash值 区块的上一个区块hash值有效 对比区块里的上一个区块hash值和当前节点区块链里的最后一个区块的编号(每个节点都有着一条完整的区块链数据),如果相同则验证通过,如果不同,需要顺着已有链往前查找,直到找到这个编号的页(找到了又怎么样呢?这就代表上一个区块后面已经有别的区块链啊???这就形成了多分支了)。如果没有找到,则验证不通过。 交易清单有效 这里即是确认每笔交易的付款人是否有足够的余额来支付这笔钱。确认交易输入的UTXO是否存在,且在此之前没有支付给别人,另外,产生交易的节点本身并不验证交易输入的UTXO是否有效,即不验证交易输出用户的余额是否充足,余额的验证是让其他节点来做的 当节点收到一笔新交易时,是否会立即开始打包成区块的操作? 矿工是一直在收集交易信息的,但只有等到上一个区块生成后,拿到上一个区块的hash值时,才会将收集到的交易信息打包新的区块,并进行POW工作 当一个区块发现它的上一个区块已经连接上了新的区块后,如何处理? 这就是区块链的多分支问题,当矿工收到两份不一样的区块,它们都基于当前这个矿工节点的链上的最后一个节点,并且内容都合法,都应将其保留,按分支的形式组织起来。区块链规定,任何时刻,都以最长的链作为主链,当某个分支的长度长于另外的分支后,该分支就称为主分支了,其他分支就会被遗忘。 由于多分支问题产生的双花问题该如何解决? 中本聪给出的解决方案是,建议收款人不要在公告挂出时立即确认交易完成,而是应该再看一段时间,等待各个挖矿小组再挂出6张确认账簿,并且之前的账簿没有被取消,才确认钱已到账。 中本聪解释道,之前设定变态的编号规则,正是为了防御这一点。根据前面所述,生成有效账簿页不是那么简单的,要花费大量的人力反复试不同的幸运数 字,而且过程完全是碰运气。如果某账簿页包含你收到钱的确认,并且在后面又延续了6个,那么攻击者想要在落后6页的情况下从另一个分支赶超当前主分支是非 常困难的,除非攻击者拥有非常多的人力,超过其他所有诚实矿工的人力之和。 而且,如果攻击者有如此多人力,与其花这么大力气搞这种攻击,还不如做良民挖矿来的收益大。这就从动机上杜绝了攻击的形成。 每个节点打包到区块里的交易都是一样的吗? 区块的打包是由矿工来做的,矿工可能是随机地选取某几笔交易进行打包,也可能是挑选交易手续费较高的交易进行打包,因此,每个节点产生的区块是不一样的。 如果各个节点打包的区块交易是完全不同的,那会怎么样? 比如,节点A打包了一个区块,所含的交易是1和2;节点B也打包了一个区块,所含的交易是3和4;由于两个节点打包的区块的前驱节点都是一致的,如果这两个区块都合法,且都被其他节点验证通过了,那么就会在链上形成分支。 当一个节点完成POW工作后,广播给其他节点验证时,如果有某个节点此时在进行着其他交易(即不包含相同的交易)的POW工作,会怎么样? 会停止当前工作,先验证区块的有效性 矿工是不间断地进行挖矿工作的吗?可以光挖矿而不打包普通交易吗? 矿工基本上就是在不间断地做POW工作的,矿工的收入主要来源于挖矿和手续费。一般来说,币的数量是有限的,前期矿工应该可以只挖矿,但为了获得更大的收益,都会选择打包有手续费的交易 产生一笔交易的时候,就会产生一个区块吗? 并不是,收集多少笔交易之后开始打包成区块,是由挖矿策略或者挖矿程序决定的。 是否有可能区块生成时,块里没有交易数据? 可能存在区块里有零笔普通交易,但有一个系统给予的挖矿奖励的交易。对于空交易的区块,由于数量量小,算出满足条件的区块hash值更快。据说早期的区块大都是这种。系统给予奖励,矿工们才有挖矿的热情。

October 5, 2018 · 1 min · Theme PaperMod