Giter Site home page Giter Site logo

blockchainpractice's Introduction

BlockChainPractice

Dian_BlockChainPractice

日志

10/1

区块链的应用

根据区块链中存储的信息的不同,区块链所应用的场所也不尽相同。(比如比特币中所应用的区块中就是存储的用户交易信息)

例如:建立食物链。

区块链网络类型

分为四种类型:公有区块链、私有区块链、联盟区块链、许可区块链。

主要研究共有区块链技术,另外三种只是部分不同,大体一致。

由于Go语言支持语言层次上的并发操作,所以Go语言非常适合分布式系统(可以简单理解为具有很多个服务器的一个集成系统)

Go语言包的管理机制

包是一系列源代码的集合。每个源文件都要求属于且仅属于一个包。

按照道理说,每个Go语言应用程序都有一个main包,main包中能有一个main方法。但是本次实习为了方便,将所有的.go文件都放到同一个main包中,然后编译运行时,只需要分开单独编译运行即可。

  • GOPATH模式

GOPATH模式最大的问题就是版本管理,GOPATH模式根本就没有版本的概念。导入包时,无法确保导入最新的版本,因为所有的版本都是一样的命名。

  • GO vender 模式

每个Go项目都有一个独立的vender文件夹,可以在文件夹中存放一些包(自己写的或者导入的外部包)。每个项目的vender之间互相不影响。

问题:如果有很多的Go项目都使用了同一个包,那么就会导致在很多地方都需要导入同一个包,这无疑是对磁盘空间的一种浪费。除此之外,也无法对第三方包进行集中的管理。

  • GO mod模式

通过一下命令来打开GO mod模式(将环境变量GO111MODULE修改为on)

$ go env -w GO111MODULE="on"

比较复杂,主要是通过go.mod和go.sum两个文件夹来实现。(以后再深入了解)

PoW算法简单实现

  • PoW算法简述:

PoW,全称为Proof of Work(工作量证明)。由于哈希算法的单向性,计算机只能通过枚举的方式不断尝试。只有运用巨大的算力率先得到满足难度值答案的用户,才算完成了工作量证明,从而有权利进行打包交易,并活得手续费。

  • 实现PoW算法

创世区块中难度值为1(也就是前32位为零) image-20211001144935563

PoS算法

  • PoS算法简介:

权益证明,也就是说谁的权益(持币数乘以持币时间)更大,谁就更有可能称为矿工,进行打包。

  • 实现原理:

PoS实现的重点是如何用数据表示出权益值,暂时先忽略时间因素,只考虑持币数。设定一个切片,切片长度等于总币数,切片的值为该比特币的用户地址。(即该切片表示了每一个比特币的拥有者是谁)然后再数组内产生随机数,实现简易版本的PoS算法。

10/2

预期完成任务:

1)学习使用GO MOD模式(记得仔细阅读一下官方教程)

2)实现PoS简易算法(写道一个新的go文件中,但是记得先搞清楚go语言多文件的一些规则)

3)开始动手进阶任务

PoS算法简易实现

源代码文件放在project01_demo\main\PoS.go中。

关键是如何利用矿工的权益值,通过随机数选出一个幸运矿工。

下面的函数解决了这个问题。

将所有用户的权益比例计算出来后,然后依次存到[0, 1] 之间。再利用随机数产生一个0到1之间的小数,看该小数落到哪一块,哪一位用户就有权力打包。

// ReturnIndex 利用随机数返回一个幸运矿工的序号
func ReturnIndex(users []User) int64 {
	for _, user := range users {
		user.ComputeWeight() //为每一个用户计算权益值
	}
	//随机数算法返回幸运的打包者
	//计算总权重
	var totalWeight int64
	for i := 1; i <= userNum; i++ {
		totalWeight += users[i].weight
	}
	var portion []float64 = make([]float64, userNum) //记录每个用户的比例(portion)
	for i := 1; i <= userNum; i++ {
		// 将每个用户所占的比例计算出来,然后再加上之前的用户的比例(最终所有用户的比例会占满[0, 1])
		portion[i] = float64(users[i].weight)/float64(totalWeight) + portion[i-1]
	}
	rand.Seed(time.Now().Unix())
	var x = rand.Float64()
	for i := 1; i <= userNum; i++ {
		if x > portion[i-1] && x < portion[i] {
			return int64(i)
		}
	}
	return 0
}

进阶任务初步

  • Go语言http包工作原理
  1. 创建 Listen Socket, 监听指定的端口,等待客户端请求到来。

  2. Listen Socket 接受客户端的请求,得到 Client Socket, 接下来通过 Client Socket 与客户端通信。

  3. 处理客户端的请求,首先从 Client Socket 读取 HTTP 请求的协议头,如果是 POST 方法,还可能要读取客户端提交的数据,然后交给相应的 handler 处理请求,handler 处理完毕准备好客户端需要的数据,通过 Client Socket 写给客户端。

  • 理解处理GET请求的代码片段

http几种常用的请求

大致理解了组长给的代码的大致含义(看了一晚上文档,眼睛快没了~~~)

知道了怎么设置handler,怎么设置env,怎么发起http请求等。

10/3

预期完成:

1)通过阅读mux,godotenv,spew三个包的官方文档,了解三个包中一些函数的基本用法

2)熟练掌握上面三个包的用法和功能

3)运用三个包和net/http包中的函数完成验收任务

理解gorilla/mux包的作用

该包主要是提供一个方便操作的路由复用器,这样就不用使用http包里面的ServerMux。(因为ServerMux无法提供一些复杂的路由功能)

理解godotnev和spew两个包的作用

godotnev主要是读取.env文件,设置环境变量,然后获取端口号的作用。

spew代替fmt进行更牛皮的格式化输出

成功完成GET请求,监听端口号为9000

尝试完成POST请求

  • 理解io包的用法,和基本函数。尝试再GET请求实现的基础上完成POST请求

image-20211003205125804

由于不知道为什么一直无法解析(因为请求的格式问题),所以用两个相似的进行比对,最终得出结论。(下图)

image-20211003210657033

可以看出图中的斜线,以及两边的飘点,还有10没有双引号,综上所述,便可得出正确的格式输入!

image-20211003210640751

咦,为啥DATA可以读取,但是Bmp的值却一直为零了。从晚上七点到九点,这个问题让我想不明白。我以为是因为只能读取字符串,然后想把bmp弄成字符串,然后再转换成数字,可惜还是失败了。最后尝试了多种方法仍无果后,我无意间看到了BPM这个有点小奇怪。再仔细一看,我人傻了。输入的请求是BPM,结构体字段内的值为BMP,这当然无法读取了。难受,一个小拼写错误浪费了我两个多钟头!非常得离谱!

最终完成了POST请求。(测试时难度值设为1,设定为10的话,PoW算法需要一点时间算出来)

10/4

预期完成任务:

1)理解PBFT和Raft算法

2)读懂案例代码并补全

理解一些基本知识

Raft算法

Raft算法通过选出一个leader来简化日志副本的管理。Raft能为在计算机集群之间部署有限状态机提供一种通用方法,并确保集群内的任意节点在某种状态转换上保持一致。

正常情况下,只会有一个服务器是Leader,并且所有的外部请求都会被导到Leader处。Leader会每隔一段时间发送消息(心跳),如果Follower超时(timeout)未收到消息,那么集群进入选举状态。

  • Raft算法的三个子问题

1)领导选举

主要变量为计算机集群任期(用term表示),每个服务器的任期编号(用term couter表示)。

状态转移图如下:

状态转移图

赢得超半数票的候选人状态转移至Leader状态,然后开始在新的任期工作。

2)记录复写

记录复写的任务主要由Leader完成,用于保证每个服务器的记录统一,同时合理运行指令。

3)安全性

  • 选举安全性:每个任期最多只能选出一个领袖。
  • 领袖附加性:领袖只会把新指令附加(英语:append)在记录尾端,不会改写或删除已有指令。
  • 记录符合性:如果某个指令在两个记录中的任期和指令序号一样,则保证序号较小的指令也完全一样。
  • 领袖完整性:如果某个指令在某个任期中存储成功,则保证存在于领袖该任期之后的记录中。
  • 状态机安全性:如果某服务器在其状态机上运行了某个指令,其他服务器保证不会在同个状态(也就是the same index of the state machine)上运行不同的指令。
PBFT算法

PBFT算法的提出是用于解决拜占庭将军问题。也就是在网络节点中存在一定数量的“叛徒”结点。

主要分为四个步骤:

  1. 客户端发送请求给主节点

  2. 主节点广播请求给其它节点,节点执行 pbft 算法的三阶段共识流程。
  3. 节点处理完三阶段流程后,返回消息给客户端。
  4. 客户端收到来自 f+1 个节点的相同消息后,代表共识已经正确完成。
理解rpc通信实例代码

也就是服务端创建一个满足rpc规则的方法,然后开启监听对应的端口号。

客户端通过拨号对应的端口,然后输入相应的参数进行调用对应的方法,获得输出。

尝试学习复现Raft算法

先实现三个分布式结点的选举。不同结点之间采用rpc来进行通信。

raft1

  • 两种RPC通信

raft2

  • Ticker结构使用
package main

import (
	"fmt"
	"time"
)

func main() {
	ticker := time.NewTicker(time.Second) // 每隔1s进行一次打印
	for {
        //每隔time.Second时间,就会向ticker.C通道传递一个值。(可以用来模拟结点超时开启候选模式)
		<-ticker.C
		fmt.Println("这是ticker的打印")
	}
}

由于复现Raft算法难度有点大,今天没有能够完成复现任务。明天继续尝试复现,争取完成拓展任务。

10/5

预期完成任务:

1)提升运用Go语言特性(高并发)的能力,做到能够熟练运用Go的协程

2)继续复现Raft算法

继续尝试复现Raft算法

代码推进过程有点困难,在写代码的时候,发现很多关于Raft算法的细节地方理解得不是很清楚。按照道理来说,如果算法了解得很清楚的情况下,代码实现应该不算很困难的一件事情。

所以继续回去阅读Raft算法的一些具体细节。

  • 算法实现过程:

三个结点的共识模块同时被初始化为Follower状态,然后在150~300ms的随机超时时间内,如果该结点还是为Follower且没有收到其他节点成为Leader的消息,则该结点变为Candidate状态,并向其他结点发送VoteRequest通信。

在另外一个文件Listen.go中,应该让三个结点同时开启监听8080号端口,方便收到通信请求。同时,在Listen.go文件中,还应该设计好调用的结构的方法。例如Rect的Area方法和Perimeter方法。(示例文件中提供)

在网上查阅了一些资料之后,花了大半天的时间,最终实现了简单的Raft算法,但是可惜无法用cmd展示。程序可以产生.exe文件,但是只能自己运行,并且没有任何输出,没有多余的时间进行展示部分的优化。

blockchainpractice's People

Contributors

lingwu-hb avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.