说起足球不得不的提起这位退钱哥了!
2019年我老表获得首届欧洲国家联赛得分王奖杯!你看我老表笑的多开心!
最近举办的欧洲杯中,我们也可以看到区块链的身影哦(虽然是广告
6月10日,欧足联(UEFA) 在官方网站宣布,蚂蚁集团旗下蚂蚁链成为2020欧洲杯全球合作伙伴。欧足联与蚂蚁链签署了一项为期五年的合作协议,表示将共同探索应用区块链等技术加速足球产业数字化转型,为全球球迷提供更好更丰富的观赛体验。
得分王奖杯的设计师周一然介绍
" 足球是全世界通用的语言,而区块链也是一种建立人与人之间信任的‘共识语言’,两者十分契合。”
狭义来说
区块链是一种按照时间顺序将数据区块以顺序相连的方式组合成的一种链式数据结构,并以密码学方式保证的不可篡改和不可伪造的分布式账本。
广义来说
区块链技术是利用块链式数据结构来验证和存储数据、利用分布式节点共识算法来生成和更新数据、利用密码学的方式保证数据传输和访问的安全性利用由自动化脚本代码组成的智能合约来编程和操作数据的一种全新的分布式基础架构与计算范式
区块链账本数据主要通过父区块
哈希值
组成链式结构来保证不可篡改性。
哈希算法(散列算法)
主要功能:把任意长度的输入通过一定的计算,生成一个固定长度的字符串,输出的字符串称为该输入的哈希值。
例子:
在百度随便找一个在线Hash算法
这里有很多种哈希算法!我们就用SHA-256为例子!
Go语言代码实现:
MD5
package main
import(
"fmt"
"crypto/md5"
"encoding/hex"
)
func main(){
//方法一
data:=[]byte("hello world")
s:=fmt.Sprintf("%x",md5.Sum(data))
fmt.Println(s)
//方法二
h:=md5.New()
h.Write(data)
s= hex.EncodeToString(h.Sum(nil))
fmt.Println(s)
}
SHA-256
package main
import(
"fmt"
"github.com/nebulasio/go-nebulas/crypto/hash"
"encoding/hex"
"crypto/sha256"
)
func main(){
//方法一 一个方法直接输出
data:=[]byte("hello world")
hash:=hash.Sha256(data)
fmt.Println(hex.EncodeToString(hash))
sha256.New()
//方法二 按照步骤一步一步输出
h:= sha256.New() //创建sha256算法
h.Write(data) //用sha256算法对参数a进行加密,得到8个变量
hashTemp := h.Sum(nil)//将8个变量相加得到最终hash
fmt.Println(hex.EncodeToString(hashTemp))
}
特点:
极短
的时间内快速得到哈希值。天壤之别
。无法
在短时间
内根据哈希值计算出原始
的输入信息,这个特性也是哈希算法安全的基础,也因此是现代密码学的重要组成。很难
可以产生相同
的哈希输出。另外:
通过哈希构建的区块链的链式结构,实现了防篡改。
通过哈希构建的默克尔树,实现内容改变的快速检测。
数字签名在信息安全,包括身份认证、数据完整性、不可否认性以及匿名性有着重要应用,是吸纳带密码学的重要分支。签名隶属于公钥密码学。
签名过程:
发送方用自己的私钥对发送信息进行所谓的加密运算,得到一个hash值,该hash值就是签名。使用时需要将签名和信息发给接收方。接受者用发送方公开的公钥和接收到的信息对签名及逆行验证,通过认证,说明接受到的信息是完整的,准确的,否则说明消息来源不对。
数字签名具体过程:
验证数字签名的流程:
peer to peer,简称p2p,对等网络。处于p2p中的网络中的所有节点地位都是相等的,网络不依赖一个中心。
概念
由于点对点网络下存在较高的网络时延,各个节点所观察到的事务先后顺序不可能完全一致。因此区块链系统需要设置一种机制对在差不多时间内发生的事务的先后顺序达成一致。这种对一个时间窗口内的事务的先后顺序达成共识的算法被称为共识机制。
相当于是生活中的法律
主要有以下这几种共识算法:
几种算法的对比
PoW | PoS | DPoS | Raft | PBFT | |
---|---|---|---|---|---|
场景 | 公链 | 公链、联盟链 | 公链、联盟链 | 联盟链 | 联盟链 |
去中心化 | 完全 | 完全 | 完全 | 半中性化 | 半中性化 |
记账节点 | 全网 | 全网 | 选出若干代表 | 选出一个Leader | 动态决定 |
响应时间 | 10分钟 | 1分钟 | 3秒左右 | 秒级 | 秒级 |
存储效率 | 全账本 | 全账本 | 全账本 | 全账本 | 全账本+部分账本 |
吞吐量 | 约7TPS | 约15TPS | 约300TPS或更高 | 几千甚至上万 | 约10000TPS或更高 |
容错 | 50% | 50% | 50% | 50% | 33% |
定义:
简单来说,智能合约是一种在满足一定条件时,就自动执行的计算机程序。
例如自动售货机可以看作是一个智能合约的系统。客户需要选择商品并完成
特点:
特征:
构成:
防篡改:交易一旦在全网范围内经过验证并添加至区块链,就很难被修改或者抹除。
可追溯:是指区块链上发生的任意一笔交易都是完整记录的,我们可以针对某一状态在区块链上追查与其相关的全部历史交易。
由于区块链系统中的任意节点都包含了完整的区块校验逻辑,所以任意节点都不需要依赖其他节点完成区块链中交易的确认过程,也就是无需额外地信任其他节点。
区块链的区块所需要的字段
字节 | 字段 | 说明 |
---|---|---|
4 | 版本 | 区块版本号,表示本区块遵守的验证规则 |
32 | 父区块头哈希值 | 前一区块的Merkle树根的哈希值,同样采取SHA256计算 |
32 | Merkle根 | 该区块中交易的Merkle树根的哈希值,同样采用SHA256计算 |
4 | 时间戳 | 该区块产生的近似时间,精确到秒的UNIX时间戳,必须严格大于前11各区块的时间的中值,同时全节点也会拒接那些超过自己两个小时的时间戳的区块 |
4 | 难度目标 | 该区块工作量证明算法的难度目标,已经使用特定算法编码 |
4 | Nonce | 未来找到满足难度目标所设定的随机数,为了解决32为随机数在算力飞升的情况下不够用的问题,规定时间戳和coinbase交易信息均改变,以此扩展nonce的位数 |
**注意:**区块不存储hash值,节点接受区块后独立计算并存储在本地。
定义一个区块的结构Block
区块头:6个字段
区块体:字符串表示data
/*
1.定义一个区块的结构Block
a.区块头:6个字段
b.区块体:字符串表示data
*/
//区块
type Block struct {
Version int64 //版本
PerBlockHash []byte //前一个区块的hash值
Hash []byte //当前区块的hash值,是为了简化代码
MerKelRoot []byte //梅克尔根
TimeStamp int64 //时间抽
Bits int64 //难度值
Nonce int64 //随机值
//区块体
Data []byte //交易信息
}
提供一个创建区块的方法
NewBlock(参数)
*/
func NewBlock(data string ,prevBlockHash []byte) *Block {
var block Block
block = Block{
Version: 2,
PerBlockHash: prevBlockHash,
//Hash: []byte{}, //区块不存储hash值,节点接受区块后独立计算并存储在本地。
MerKelRoot: []byte{},
TimeStamp: time.Now().Unix(),
Bits: targetBits,
Nonce: 0,
Data: []byte(data),
}
// block.SetHash() //填充Hash
PoW:= NewProofOfWork(&block)
nonce , hash :=PoW.Run()
block.Nonce=nonce
block.Hash=hash
return &block
}
另外别忘了创世块
func NewGensisBlock() *Block{
return NewBlock("Genesis Block!",[]byte{})
}
/*
3. 定义一个工作量证明的结构ProofOfWork
block
目标值
*/
type ProofOfWork struct {
block *Block
target *big.Int //目标值
}
提供一个创造PoW的方法
NewProofOfWork(参数)
/*
4. 提供一个创造PoW的方法
NewProofOfWork(参数)
*/
const targetBits = 24
func NewProofOfWork(block *Block) *ProofOfWork { //工作量证明
target := big.NewInt(1) //000....001
target.Lsh(target,uint(256-targetBits)) //将1向左移动 //ox00000010000000..00
pow:=ProofOfWork{
block: block,
target: target,
}
return &pow
}
func (pow *ProofOfWork) PrepareData(nonce int64) []byte {
// 源码里面是要传二维切片 func Join(s [][]byte, sep []byte) []byte
block := pow.block
tmp :=[][]byte{
IntToByte(block.Version),
block.PerBlockHash,
block.MerKelRoot,
IntToByte(block.TimeStamp),
IntToByte(block.Bits),
IntToByte(block.Nonce),
}
data:=bytes.Join(tmp,[]byte{}) //之后再计算hash
return data
}
提供一个计算哈希值的方法
Run()
/*
5. 提供一个计算哈希值的方法
Run()
*/
func (pow *ProofOfWork)Run() (int64,[]byte) {
//1.凭借数据
//2.哈希值转成big.Int类型
var hash [32]byte
var nonce int64 = 0
var hashInt big.Int
fmt.Println("开始挖矿了!")
fmt.Printf("难度 target hash : %x\n" ,pow.target.Bytes())
for nonce < math.MaxInt64 {
data:=pow.PrepareData(nonce)
hash = sha256.Sum256(data)
// Cmp compares x and y and returns:
//
// -1 if x < y
// 0 if x == y
// +1 if x > y
//
hashInt.SetBytes(hash[:])
if hashInt.Cmp(pow.target) == -1 {
fmt.Printf("Found ,nonce :%d ,hash :%x \n",nonce,hash)
}else {
//fmt.Printf("Not Found ,current nonce :%d ,hash :%x \n",nonce,hash)
nonce++
}
}
return nonce,hash[:]
}
提供一个校验函数
IsValid()
/*
6. 提供一个校验函数
IsValid()
*/
func (pow *ProofOfWork)IsValid() bool{
var hashInt big.Int
data := pow.PrepareData(pow.block.Nonce)
hash:=sha256.Sum256(data)
hashInt.SetBytes(hash[:])
return hashInt.Cmp(pow.target) == -1 //如果是-1就是找到了就是
}
定义一个区块链结构BlockChain
Block数组
/*
1. 定义一个区块链结构BlockChain
Block数组
*/
type BlockChain struct {
blocks []*Block
}
提供一个创建BlockChain()的方法
NewBlockChain()
/*
2. 提供一个创建BlockChain()的方法
NewBlockChain()
*/
func NewBlockChain() *BlockChain {
block := NewGensisBlock()
return &BlockChain{blocks:[]*Block{block}} //创建只有一个元素的区块链,初始化
}
提供一个添加区块的方法
AddBlock(参数)
/*
3. 提供一个添加区块的方法
AddBlock(参数)
*/
func (bc *BlockChain)AddBlock(data string) {
PerBlockHash := bc.blocks[len(bc.blocks)-1].Hash //这一个区块的哈希是前一块的哈希值
block := NewBlock(data,PerBlockHash)
bc.blocks = append(bc.blocks,block)
}