区块链安全:从web3.0到数字货币
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
互联网发展的三个阶段
web1.0
静态页面内容只能供用户去阅读类似于在网络上读报纸或者看书。
web2.0
动态互联网实现用户之间的互动比如twitterfacebooktitok等。
web2.0中厂商用免费或极低的成本吸引用户通过获取到用户的信息来推流广告从而获得利润。
打个比方就是 厂商在一片地上种了很多草吸引羊来吃趁着羊吃草的功夫把羊身上的毛薅下来拿去卖钱而羊自己并不在意这些毛可以说是一种双向互利的方式。
web3.0
web3.0是一个很模糊的概念随着区块链技术的发展基于区块链的web3.0诞生。
接着用上面的例子来说随着web2.0的发展壮大稀缺的不再是草而是羊毛也就是用户身上的数据。那么羊毛的重要性愈加突出所以提出web3.0的概念也就是拥有自己的一片空间别人无论如何都无法修改也就是将羊毛数据存放在了一个非常安全的地方中相比于web2.0不但实现了动态的交互也实现了数据的“拥有”。
web3的概念非常模糊可以说是一个大方向按照我个人的理解可以说是在互联网创造了一个虚拟的世界这个虚拟的世界拥有和现实世界一样的货币交易系统以及其他体系能够自主维持运转的这样一个“虚拟生态系统”而这个生态系统的生存法则就是“去中心化”。
什么是去中心化
比如现在市面上的app都由一个厂家负责厂商可以随意删除控制用户数据形成了以厂商为中心的服务体系去中心化就是没有中心厂商作为核心而是所有用户形成一个能够自力更生的体系。
密码货币
随着web2.0发展数字货币使用越来越多而在区块链技术的支持下数字货币也出现了全新的存在形式去中心化的密码货币世界上第一种密码货币就是比特币。像纸币有防伪印一样密码货币通过密码学的散列计算出的hash值并且和智能合约进行绑定密码货币基于去中心化的机制与依赖中心监管体系的银行金融系统相对。之后出现的数种密码货币被创造它们通常被称为altcoins。
区块链
区块链的防篡改机制
一个区块中储存了三样东西数据前一个区块的hash值自身的hash值由数据和前一区块的哈希值共同决定如果要更改某一区块的内容那么该区块a区块的hash值就会改变下一区块b区块储存的a区块的hash值无法对应a区块当前哈希值那么这两个区块间的链接就会断开。
如果想要篡改某一区块的数据我们就要将这一区块以及后续所有区块的hash值进行重算比如一条区块链里面有abcde五个区块当我们篡改了b区块的数据那么我们就要带着b区块的新hash值和c区块的数据重新计算出c区块的新hash值然后再带着c区块的新hash值和d区块的数据重新计算d区块的新hash值再带着d区块的新hash值和e区块的数据重新计算e区块的hash值……………………其实在重新计算某一区块的hash值的过程也就相当于创造了一个新的区块因此篡改一个区块以及后续区块所需的时间取决于创造一个区块所需要的时间。
这个看起来对算力要求似乎非常庞大但是现代计算机其实是可以做到这一点的如果我们有一台超大算力的计算机那么是不是轻松就可以改变区块链的内容了为了防止这种情况的出现区块链加入了工作量证明机制proof of work简称 pow
我们用游戏举例说明一下pow我们刚才说到用超大算力计算机来篡改区块链这就好比你拿着满级神装在新手村乱杀区块链是不允许这种情况出现的因此它会上调怪物属性也就是会增加创造一个区块所需的难度使每一新区块被创造时都保持在十分钟左右当然这个时间是可以更改的因此即使是一台超高算力的计算机想要篡改一个区块所需的时间仍然是
创造一个区块的时间✖️n min
。
那我们所说的挖矿是什么呢上面提到的情况是想要篡改区块中的数据那么我没有恶意我只是单纯的创造区块去给自己或者他人使用这个创造区块的过程牺牲了我电脑的算力和一些其他资源所以作为补偿创建区块的人会得到密码货币的奖励这就是我们所说的挖矿。
区块链的点对点网络结构
在传统的web服务中传统的链接对象基本都是客户端和服务端众多客户端访问一个服务端来进行交互而在区块链的点对点网络结构peer to peer中不再有客户端与服务端的概念每一个节点间相互平等并且包含完整的区块链数据存储也就是说每一个节点中都储存了整个区块链网络中的所有信息这样即使一个节点出现故障其他所有节点也在帮他记录信息这些记录了所有节点区块链的节点叫做全节点当然也有只储存了自己信息的轻节点比如区块链用来储存转账记录那么每一节点都储存了所有节点之间的转账记录每一节点储存的内容也是相同的如果某一节点与其他节点出现差异那么该节点或许就有被篡改过的可能了但是被篡改几乎是不可能发生的原因看下面。
点对点网络结构下的所有节点拥有判断区块是否被篡改的能力当一个新区块想要加入某一节点的区块链时该节点会向其他所有节点进行广播所有的节点进行判断如果50%以上的节点都认为该区块没有被篡改那么这个区块就可以成功的加入区块链当中反言之如果想要篡改某一区块的数据你首先要将这一区块后的所有哈希重新计算并且还要更改超过百分之五十节点的这一区块后的所有区块的哈希那么就要拥有超过全网50%以上的算力才可以这付出的代价是相当高的这就是区块链网络系统的少数服从多数原则。
DAPP
Dapp 是什么
APP (Application) 指的是手机里的应用程序像是微信、微博、抖音…等都是日常生活中常会使用到的 App。
而 Dapp 的全名为去中心化应用程序Decentralized Application是建立在区块链系统网络上所提供的服务都具有公开透明、不可篡改的特性。
【----帮助网安学习以下所有学习资料免费领加@v~yj009991备注“ csdn ”获取】
① 网安学习成长路径思维导图
② 60+网安经典常用工具包
③ 100+SRC漏洞分析报告
④ 150+网安攻防实战技术电子书
⑤ 最权威CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂面试题合集含答案
⑧ APP客户端安全检测指南安卓+IOS
以下是 Dapp 所具有的要素
- 代码开源程序代码皆公开透明任何人都可以查阅及审核避免项目方说到没做到。
- 分布式帐本降低数据遗失的风险且没有任何其他第三方有权能够窜改数据。
- 数据所有权除本人私钥持有者外任何人皆无法动用该帐号的数据。
为什么 Dapp 会崛起?
事实上App 都是中心化的应用服务用户所使用的数据都会存储在单一服务器系统里代表公司能掌控用户的所有数据但相关问题也随之浮出水面。
数据所有权归属问题
用户在 App 上的个人资料、搜索浏览纪录等信息都会存储在中心化系统的服务器里这也意味着软件公司能够借由这些数据来营利。
也导致像是微博、抖音等企业能透过搜集的用户数据来投放广告并借此获利。等于企业能用你的信息来赚钱但你却分不到任何好处甚至还可能受到影响例如被疯狂投放广告、或个人资料被平台外泄。
另外传统手游的游戏道具、帐号数据也都属于公司所有一旦宣布停止营运这些资产也会随着官方服务器关闭而消失。
但在 Dapp 中你的游戏道具、帐号都会以 NFT 形式储存在链上因此只要区块链不倒你就能持续拥有这些资产。换句话说Dapp 能够让数据的所有权回归到用户身上。额外提醒虽然你仍拥有这些资产但可能会因为游戏已经关闭导致这些资产的现值趋近于零你能保有的仍以回忆居多。
过度中心化
App 是由中心化服务器来进行管理因此企业有时可以专断独行但用户却没有任何反制的手段例如可以随意植入广告或是删除用户的内容、帐号。
而 Dapp 的数据都存在区块链上因此项目方没办法任意删除用户资料目前也没有任何广告植入的问题但不确定未来是否会有项目开始植入广告。
由于上述几点原因也让许多人开始对传统的 App 感到不满于是就有人打算通过区块链“去中心化”的特性来研发能解决上述问题的 App于是 Dapp 就此诞生。
不过同时也要注意不是每个 Dapp 都一定符合公开、去中心化的规范例如 Opensea 就能下架用户的 NFT 和限制用户登陆。
Dapp 与 App 的差异
App 的应用服务是使用中心化服务器代表软件公司必须要承担存储用户的数据量的营运成本否则将无法持续地运行。
例如抖音服务器的成本就百万以上因此必须想办法创造各种营收管道来支持各项支出像是通过大数据将广告推广到潜在用户面前借此吸引更多广告商进驻。
而 Dapp 是建立在区块链上用户在链上进行交易、换币等行为时是需要自行负担手续费Gas 费的也就代表开发商的运营成本会比传统 App 来得更低不过有些开发商为了吸引用户会帮用户负担使用时的手续费。
Dapp | App | |
---|---|---|
服务器 | 去中心化 | 中心化 |
隐私性 | 有区块链匿名性 | 无还可能被外泄 |
营运成本 | 用户共同负担或开发商负担 | 开发商负担 |
平台获利来源 | 智能合约链上手续费 | 广告商或用户消费 |
数据所有权 | 用户 | 开发商 |
平台控制权 | 开发商或是 DAO 治理 | 开发商 |
系统 | 区块链 | Android、iOS |
代码是否开源 | 代码皆公开可供人参考 | 代码为公司机密擅用者可能会吃上官司 |
智能合约
智能合约是一段写在区块链上的代码一旦某个事件触发合约中的条款代码即自动执行。也就是说满足条件就执行不需要人为操控类似于传统web的后端代码。
简单区块链实现
我们用Javascript来手写一个建议的区块链出来其实和写一个链表很像
const sha256 = require('crypto-js/sha256')
Date = new Date()
class block{
constructor(data,time,previousHash) {
this.data = data
this.time = time
this.previousHash = previousHash
this.myHash = this.currHash()
}
currHash() {
return sha256(this.data + this.time + this.previousHash).toString()
}
}
class blockCahin{
constructor()
{
this.chain = [this.createBlockchain()];
}
createBlockchain()
{
return new block("Genesisblock",Date.toLocaleString(),0o0000000)
}
getLatestblock()
{
return this.chain[this.chain.length - 1]
}
addBlock(newBlock)
{
newBlock.previousHash = this.getLatestblock().myHash
newBlock.myHash = newBlock.currHash()
this.chain.push(newBlock)
}
}
BlockChain = new blockCahin()
BlockChain.addBlock(new block("this is a test",Date.toLocaleDateString(),"anything"))
console.log(BlockChain)
接下来我们用代码实现一下简易的POW
const sha256 = require("crypto-js/sha256")
function proofOfwork(){
let seed = "y1zh3e7"
let x = 1 // x为自增变量
while (true){
if(sha256(seed + x).toString().substring(0,4) != "0000") // 定义难度比如我现在要求通过不断自增x去计算seed+x的哈希值
{ // 当哈希值前四位都为0000时则代表成功 如果想提高难度我们就可以让前x位为xxxx
x += 1
}else{
console.log(sha256(seed + x).toString())
break
}
}
console.log(x) // 输出计算多少次后成功
}
proofOfwork()
实现防篡改机制
/***********************************************
验证区块链防篡改需要检测两项
1.重新计算区块的hash值判断与区块中储存的hash是否相同
2.判断当前区块的previousHash是否和上一区块的hash相同
***********************************************/
function validateBlock(validBlockchain){
if (validBlockchain.chain.length == 1)
{
if(validBlockchain.chain[0].myHash != validBlockchain.calcHash())
{
console.log("数据篡改")
return false
}
}else {
for (let i=1; i<=validBlockchain.chain.length-1; i++)
{
if(validBlockchain.chain[i].myHash != validBlockchain.chain[i].calcHash())
{
console.log("数据篡改")
return false
}
if (validBlockchain.chain[i].previousHash != validBlockchain.chain[i-1].myHash)
{
console.log("前后区块链断裂")
return false
}
}
}
console.log("数据无篡改且区块链结构完整")
return true
}
将完整的POW整合到区块链当中并实现挖矿功能最终实现的完整区块链
const sha256 = require('crypto-js/sha256')
Date = new Date()
class block{
constructor(data,time,previousHash) {
this.data = data
this.time = time
this.nonce = 1
this.previousHash = previousHash
this.myHash = this.calcHash()
}
calcHash() {
return sha256(this.data + this.time + this.previousHash + this.nonce).toString()
}
/** **/
getAnswer(difficulty){
let answer = ""
for(let i=0; i<difficulty; i++)
{
answer += "0"
}
console.log(answer)
return answer
}
/** 引入挖矿功能 **/
mine(difficulty){
let answer = this.getAnswer(difficulty)
let Hash = this.calcHash()
while(true){
if (Hash.substring(0,difficulty) != answer)
{
this.nonce++
Hash = this.calcHash()
}else{
break
}
}
console.log("mine successful!")
console.log(this.nonce)
return Hash
}
}
class blockCahin{
constructor()
{
this.chain = [this.createBlockchain()]
this.difficulty = 5
}
createBlockchain()
{
return new block("Genesisblock",Date.toLocaleString(),0o0000000)
}
getLatestblock()
{
return this.chain[this.chain.length - 1]
}
addBlock(newBlock)
{
newBlock.previousHash = this.getLatestblock().myHash
newBlock.myHash = newBlock.mine(this.difficulty)
this.chain.push(newBlock)
}
}
/***********************************************
验证区块链防篡改需要检测两项
1.重新计算区块的hash值判断与区块中储存的hash是否相同
2.判断当前区块的previousHash是否和上一区块的hash相同
***********************************************/
function validateBlock(validBlockchain){
if (validBlockchain.chain.length == 1)
{
if(validBlockchain.chain[0].myHash != validBlockchain.calcHash())
{
console.log("数据篡改")
return false
}
}else {
for (let i=1; i<=validBlockchain.chain.length-1; i++)
{
if(validBlockchain.chain[i].myHash != validBlockchain.chain[i].calcHash())
{
console.log("数据篡改")
return false
}
if (validBlockchain.chain[i].previousHash != validBlockchain.chain[i-1].myHash)
{
console.log("前后区块链断裂")
return false
}
}
}
console.log("数据无篡改且区块链结构完整")
return true
}
BlockChain = new blockCahin()
BlockChain.addBlock(new block("this is a test",Date.toLocaleDateString(),"anything"))
// console.log(BlockChain)
// BlockChain.chain[1].data = "数据篡改"
// BlockChain.chain[0].myHash = "0012343566688"
// console.log(validateBlock(BlockChain))
数字货币的简单实现
创建自己的数字货币
首先我们要新建一个Transaction类来进行转账记录
class Transaction{
constructor(from, to , amount) {
this.from = from
this.to = to
this.amount = amount
}
}
更改区块中data的含义此时要记录的是转账信息transaction并且由于transaction是一个对象因此在参与计算哈希时要转为字符串这里将时间改为了Date.now这样在区块创造时就记录了这笔转账记录的时间
class Block{
constructor(transaction,previousHash) {
this.transactions = transaction
this.time = Date.now()
this.nonce = 1
this.previousHash = previousHash
this.myHash = this.calcHash()
}
// 计算hash时要将data转换为字符串类型此时的data是一个transaction
calcHash() {
return sha256(JSON.stringify(this.transactions) + this.time + this.previousHash + this.nonce).toString()
}
上面说到奖励货币的发放是通过转账的方式实现的所以我们在链上实现逻辑
class blockChain{
constructor()
{
this.chain = [this.createBlockchain()]
this.difficulty = 5
this.transactionPool = [] //挖矿成功的转账信息
this.mineReward = 50 //每次挖矿成功的奖励货币数
}
mineTransaction(minerAddress)
{
const minerRewardTransaction = new Transaction('', minerAddress, this.mineReward)
this.transactionPool.push(minerRewardTransaction)
}
之前我们是在外部传入一个区块在整个货币系统的实现后区块应该是在挖矿时在区块链内部产生的修改代码
//将Transaction添加到Transaction Pool中
addTransaction(Transaction)
{
this.transactionPool.push(Transaction)
}
mineTransaction(minerAddress)
{
const minerRewardTransaction = new Transaction('', minerAddress, this.mineReward)
this.transactionPool.push(minerRewardTransaction)
//挖矿
/********************************************************
* 这里新区块记录了整个区块链的转账信息但在实际情况中区块的存储
* 容量是有限制的所以在挖矿时记录的转账记录会选择手续费最高的transaction
* 我们这里先不考虑这种情况
*******************************************************/
const newBlock = new Block(this.transactionPool,this.getLatestBlock().myHash)
newBlock.mine()
//添加到区块链并清空Transaction Pool
this.chain.push(newBlock)
this.transactionPool = []
}
整个写好的数字代币
const sha256 = require('crypto-js/sha256')
class Transaction{
constructor(from, to , amount) {
this.from = from
this.to = to
this.amount = amount
}
}
class Block{
constructor(transaction,previousHash) {
this.transactions = transaction
this.time = Date.now()
this.nonce = 1
this.previousHash = previousHash
this.myHash = this.calcHash()
}
// 计算hash时要将data转换为字符串类型此时的data是一个transaction
calcHash() {
return sha256(JSON.stringify(this.transactions) + this.time + this.previousHash + this.nonce).toString()
}
/** 获取相应难度hash **/
getAnswer(difficulty){
let answer = ""
for(let i=0; i<difficulty; i++)
{
answer += "0"
}
return answer
}
/** 引入挖矿功能 **/
mine(difficulty){
let answer = this.getAnswer(difficulty)
let Hash = this.calcHash()
while(true){
if (Hash.substring(0,difficulty) != answer)
{
this.nonce++
Hash = this.calcHash()
}else{
break
}
}
console.log("mine successful!\n")
console.log("计算"+this.nonce+"次后挖矿成功answer为"+Hash)
return Hash
}
}
class blockChain{
constructor()
{
this.chain = [this.createBlockchain()]
this.difficulty = 4
this.transactionPool = [] //挖矿成功的转账信息
this.mineReward = 50 //每次挖矿成功的奖励货币数
}
createBlockchain()
{
return new Block("Genesisblock",null)
}
getLatestBlock()
{
return this.chain[this.chain.length - 1]
}
//将Transaction添加到Transaction Pool中
addTransaction(Transaction)
{
this.transactionPool.push(Transaction)
}
mineTransaction(minerAddress)
{
const minerRewardTransaction = new Transaction('', minerAddress, this.mineReward)
this.transactionPool.push(minerRewardTransaction)
//挖矿
/********************************************************
* 这里新区块记录了整个区块链的转账信息但在实际情况中区块的存储
* 容量是有限制的所以在挖矿时记录的转账记录会选择手续费最高的transaction
* 我们这里先不考虑这种情况
*******************************************************/
const newBlock = new Block(this.transactionPool,this.getLatestBlock().myHash)
newBlock.mine(this.difficulty)
//添加到区块链并清空Transaction Pool
this.chain.push(newBlock)
this.transactionPool = []
}
}
/***********************************************
验证区块链防篡改需要检测两项
1.重新计算区块的hash值判断与区块中储存的hash是否相同
2.判断当前区块的previousHash是否和上一区块的hash相同
***********************************************/
function validateBlock(validBlockchain){
if (validBlockchain.chain.length == 1)
{
if(validBlockchain.chain[0].myHash != validBlockchain.calcHash())
{
console.log("数据篡改")
return false
}
}else {
for (let i=1; i<=validBlockchain.chain.length-1; i++)
{
if(validBlockchain.chain[i].myHash != validBlockchain.chain[i].calcHash())
{
console.log("数据篡改")
return false
}
if (validBlockchain.chain[i].previousHash != validBlockchain.chain[i-1].myHash)
{
console.log("前后区块链断裂")
return false
}
}
}
console.log("数据无篡改且区块链结构完整")
return true
}
Y1Coin = new blockChain()
const Transaction1 = new Transaction('add1', 'add2', 20)
const Transaction2 = new Transaction('add1', 'add2', 5)
Y1Coin.addTransaction(Transaction1)
Y1Coin.addTransaction(Transaction2)
Y1Coin.mineTransaction("add3")
console.log(Y1Coin)
console.log(Y1Coin.chain[1].transactions)