草庐IT

什么是区块链,为什么数据不可被篡改

共知 2023-04-12 原文

一提到区块链,首先想到的就是比特币。确实比特币是第一个区块链项目,也是最成功的项目,目前的价格是60428¥/btc。想想当初用10000个比特币买了2个披萨的程序员Laszlo,估计怎么也想不到比特币能涨到如此之高(毕竟眼光有多远,就只能赚多少钱)。那么到底什么是区块链呢?为什么区块链上的交易不可被篡改呢?

区块链: 我们可以从字面上对这个词语进行拆分,“区块”和“链”。区块链就是由区块线性连接而成的链。

数据不可篡改: 这个是由密码学、哈希函数、矿工算力等保障的

一、区块链

先上一个区块链的结构图

 

1.什么是区块

区块主要是由区块头和区块体构成:

区块头:里面包含了一些基本信息,比如版本号、父区块头的哈希、默克尔树根哈希、时间戳、挖矿难度、随机数。

区块体:主要就是打包的交易,这些交易是资产的拥有者使用私钥签名的数据,代表了资产从哪里转移到哪里。最特殊的一笔交易是由旷工自己写上去的,它的金额是对矿工的奖励加上所有交易者支付的手续费。这笔交易称为币基交易(Coinbase Transaction),比特币就是通过对矿工的奖励来发行货币的。

2. 什么是链

每个区块的头包含了父区块的头的哈希,就这样逐个链接下去,就形成了区块链。

实际上这就是区块链的本质了,但这只是从数据方面看,那么数据的可靠性又是怎么保证的?

二、数据不可篡改

1. 交易不可被篡改

当我们发送一笔交易到区块链节点的时候,节点会验证这个交易的签名,如果签名不对那么数据是会被丢弃的,只有持有私钥匙的人才可以修改这笔交易,其他人是修改不了的,这个问题是由密码学解决的。在比特币中使用的是椭圆曲线算法来对交易进行签名。

任何一个交易的修改都将导致区块体的变化

2. 区块体不可被篡改

区块体中是一笔一笔的交易,这些交易通过默克尔树组织起来,如果其中任何一笔交易被修改,都会造成默克尔树根哈希的变化,这个问题是由哈希函数解决的。在比特币中使用的是sha256算法

区块体的变化将导致区块头的变化

3. 区块头不可被篡改

前面两个问题都是由不可解的数学难题来保证的,区块头的不可修改是由算力保证的,这就是矿工需要干的事情。那么区块头是怎么保证不可被修改的呢?

全世界所有的矿工都会计算区块头的哈希,但是计算出来的哈希要求前面有n个0。如果区块的头信息不变,那么计算出来的哈希也都是一样的。前面我们说过,区块头中包含一个nonce,矿工就是通过修改nonce以此来找到满足要求的哈希(这个过程被称为挖矿)。在比特币的世界中,这个问题需要全世界的矿工计算十分钟左右才能找到一个满足要求的nonce。所以单凭个人要想修改一个区块是完全不可能的。

矿工一旦计算出来这个nonce,就会将这个区块广播给其他节点,这些节点对区块中的数据进行验证,如果验证通过,就会停止此区块的挖矿,将此区块广播给其他的节点,并开始争夺下一个区块的记账权

区块头的变化将导致区块链的变化

4. 区块链不可被篡改

从前面三步可知,如果一个人修改了区块中的交易数据,默克尔树的根哈希会发生变化,接着区块头会发生变化,这个时候区块的随机数(nonce)将变得不合法,需要重新挖矿。假设某个组织拥有大量的计算机,并重新挖出了这个随机数(nonce)。但这又会导致此区块头的哈希发生变化,子区块的区块头中记录了父区块头的哈希,这样,子区块头也发生了变化,子区块的随机数(nonce)也变得不合法了,又需要重新挖子区块的随机数(nonce)。如此下去,将造成连锁反应,任何修改都将造成数据坍塌,需要重新挖矿。在比特币中,如果一笔交易后面被添加了六个区块,那么这笔交易可以认为,将永远不可能被修改。(除非全世界所有的矿机都否认先前的交易,重新开始挖矿)

最后

至此,区块链的存储结构和数据不可篡改就讲解完了,在这个模型当中还存在很多问题需要解决,比如UTXO经济模型、为什么比特币只有2100万个、什么是钱包、什么是挖矿。这些问题等后面再给大家讲解

区块链开发

 

有关什么是区块链,为什么数据不可被篡改的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  3. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  5. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  6. ruby - ruby 中的 TOPLEVEL_BINDING 是什么? - 2

    它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput

  7. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  8. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  9. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

  10. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

随机推荐