区块链学习记录(1)

区块链组成、go语言环境安装及运行

区块链

从科技层面来看,区块链涉及数学、密码学、互联网和计算机编程等很多科学技术问题
从应用视角来看,简单来说,区块链是一个分布式的共享账本和数据库
区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式

区块链组成

区块链是一种按照时间顺序将数据区块以顺序相连的方式组合成的一种链式数据结构

区块组成

区块头(Block Header)和区块体(Block)

区块头

区块头包括三组元数据:
1.用于连接前面的区块、索引自父区块哈希值的数据。
2.挖矿难度、Nonce(随机数,用于工作量证明算法的计数器)、时间戳
3.能够总结并快速归纳校验区块中所有交易数据的Merkle(默克尔)树根数据

1
2
3
4
5
6
7
8
数据项                              目的                            更新时间          大小(字节)

Version 区块版本号 更新软件后 4
hashPrevBlock 前一区块256位Hash值 新的区块链进入 32
hashMerkleBlock 一个区块所有交易Hash值 接受一个交易时 32
Time 从1970-01-01 00:00 UTC开始、以秒为单位的当前时间戳 每几秒更新 4
Bits 压缩格式当前目标Hash值 挖矿难度调整时 4
Nonce 0~32随机数 产生Hash时 4

时间戳

从区块生成起存在于区块中,对应每一次的交易认证,证明交易记录的真实性

Merkle树结构(根节点)

Merkle树的数据结构存放所有叶子节点的值,并以此为基础生成一个统一的哈希值
Merkle的叶子节点存储的是数据信息的哈希值,非叶子节点的存储是对其下面所有叶子节点的组合进行哈希计算后得出的哈希值
区块中任意一个数据的变更都会导致Merkle树结构发生变化,在交易信息验证对比的过程中,只需验证Merkle树结构生成的统一哈希值,因此Merkle树结构能够大大减少数据的计算量

区块体

主要是包含交易数据(Transaction,TX).
Transactions包括一个input和多个output.并且输入和输出相等:input satoshi=output satoshi.已确认的交易(或者说已经花出去的钱)被称为Transaction identifiers(TXIDs),未确认的被称为Unspent Transaction Outputs(UTXOs)

1
2
3
4
5
6
7
数据项                          描述                长度(字节)

Magic no 总是0xD9B4VEF9 4
Blocklize 到区块结束的字节长度 4
Blockheader 包含6个数据项 80
Transaction counter 正整数VI=Varlnt 1~9
Transactions 交易列表(非空) 取决于交易

模板如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 比特币区块结构
class 区块的数据结构:
神奇数 = 4 byte # 区块之间的分割符
区块大小 = 4 byte # 记录当前区块的大小

数据区块头部信息 = 80 byte # 记录当前区块的头部信息,其Hash值是下一个新区块的参数
class 区块头数据结构:
版本号 = 4 byte # 数据块的版本号
前一个区块的信息 = 32 byte # 记录前一个数据区块的Hash值,当前区块的Hash值一定比它小
Merkle树的根值 = 32 byte # 记录当前区块中所有交易Merkle树根节点的Hash值
时间戳 = 4 byte # 记录当前区块的生成时间,按照Unix时间格式
目标值 = 4 byte # 当前区块生成所达到目标值的特征,用于矿工的工作量证明
随机数 = 4 byte # 当前区块工作量证明的参数

交易计数 = 1~9 byte # 当前区块所记录的交易数
交易详情 = 变长 # 记录当前区块保存的所有交易细节

#摘自Nykuvl学长的Blog

散列值

散列函数(Hash function)又称散列算法、哈希函数,是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。
该函数将数据打乱混合,重新创建一个叫做散列值(hash values,hash codes,hash sums,或hashes)的指纹
Hash算法是一个广义的算法,也可以认为是一种思想,使用Hash算法可以提高存储空间的利用率,可以提高数据的查询效率,也可以做数字签名来保障数据传递的安全性。所以Hash算法被广泛地应用在互联网应用中。 [1]
Hash算法也被称为散列算法,Hash算法虽然被称为算法,但实际上它更像是一种思想。Hash算法没有一个固定的公式,只要符合散列思想的算法都可以被称为是Hash算法

散列函数特性

1.单向性。即不可逆,给定明文可以计算出散列值,但是给定散列值不能计算出明文。
2.抗碰撞。不同明文使用同一种散列函数很难得到相同的散列值。
3.抗篡改。两个不同明文只要有很小的区别,得出的散列值差别也会很大。
4.散列值长度固定。不同散列函数计算出的散列值都是有固定长度的

常用Hash函数

散列函数能使对一个数据序列的访问过程更加迅速有效,通过散列函数,数据元素将被更快地定位。常用Hash函数有:
1.直接寻址法。取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a·key + b,其中a和b为常数(这种散列函数叫做自身函数)
2. 数字分析法。分析一组数据,比如一组员工的出生年月日,这时我们发现出生年月日的前几位数字大体相同,这样的话,出现冲突的几率就会很大,但是我们发现年月日的后几位表示月份和具体日期的数字差别很大,如果用后面的数字来构成散列地址,则冲突的几率会明显降低。因此数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。
3. 平方取中法。取关键字平方后的中间几位作为散列地址。
4. 折叠法。将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(去除进位)作为散列地址。
5. 随机数法。选择一随机函数,取关键字作为随机函数的种子生成随机值作为散列地址,通常用于关键字长度不同的场合。
6. 除留余数法。取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p,p<=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生碰撞。

以太坊

以太坊(Ethereum)是一个开源的有智能合约功能的公共区块链平台,通过其专用加密货币以太币(Ether,简称“ETH”)提供去中心化的以太虚拟机(Ethereum Virtual Machine)来处理点对点合约

以太坊设计原则

1、简洁原则
以太坊协议将尽可能简单,即便以某些数据存储和时间上的低效为代价。一个普通的程序员也能够完美地去实现完整的开发说明。这将最终有助于降低任何特殊个人或精英团体可能对协议的影响并且推进以太坊作为对所有人开放的协议的应用前景。添加复杂性的优化将不会被接受,除非它们提供了非常根本性的益处。
2、通用原则
没有“特性”是以太坊设计哲学中的一个根本性部分。取而代之的是,以太坊提供了一个内部的图灵完备的脚本语言以供用户来构建任何可以精确定义的智能合约或交易类型
3、模块化原则
以太坊的不同部分应被设计为尽可能模块化的和可分的。开发过程中,应该能够容易地让在协议某处做一个小改动的同时应用层却可以不加改动地继续正常运行。以太坊开发应该最大程度地做好这些事情以助益于整个加密货币生态系统,而不仅是自身。
4、无歧视原则
协议不应主动地试图限制或阻碍特定的类目或用法,协议中的所有监管机制都应被设计为直接监管危害,不应试图反对特定的不受欢迎的应用。人们甚至可以在以太坊之上运行一个无限循环脚本,只要他愿意为其支付按计算步骤计算的交易费用。

go语言环境安装、初步运行

安装包下载地址
里面有各种系统下的go语言安装包,我选择的是Windows包
下载后安装包,并配置Path环境变量,例如: F:/Go/bin

创建工作空间F:/gogogo
创建文件1.go

1
2
3
4
5
6
7
package main

import"fmt"

func main(){
fmt.Println("Hello World!")
}

go语言在DOS界面运行。进入工作空间,输入 go run 1.go ,成功!