区块链学习

news2024/11/19 13:30:07

在这里插入图片描述

hash函数

  • 一种算法
  • 任意长度的二进制数据映射为固定长度的二进制数据

hash函数的特点

  • 确定性------对同一个输入数据每次都能得到相同的结果
  • 单向性------对一个数据可以很容易计算出hash值,但是对于一个hash值非常难反推出数据
  • 隐秘性------没有可行的方法算出hash函数的输入值
  • 抗篡改------对于数据一个bit位的改动,对hash值的改动也是非常大
  • 抗碰撞------对于两个不同的数据,hash值相同的可能性很小

hash值的实现

  • MD系列
  • SHA系列,推荐SHA256,SHA3

代码实现

package main

import "fmt"

import (
	"crypto/sha256"
	"encoding/hex"
	"log"
)

func calculateHash(toBeHashed string) string {
    hashInBytes :=sha256.Sum256([]byte(toBeHashed))
    hashInStr:=hex.EncodeToString(hashInBytes[:])
    log.Printf(toBeHashed,hashInStr)
    return hashInStr
}
func main() {
   fmt.Println("Hello, World!")
   calculateHash("test1")
   calculateHash("test1")
   calculateHash("testl")
}

运行结果

在这里插入图片描述

连式结构

在这里插入图片描述如果区块1的数据发生改变,区块2不发生相应的改变,则指向区块2的hash指针不在有效。如果要使得引用有效,则就要改变区块2的hash值,后面的区块都要发生改变。

构建自己的区块链

  • 实现链式结构
  • 实现一个简单的http server,对外暴露读写接口

步骤

  • 创建block
  • 创建blockchain
  • 创建http server

创建Block

  • 新建工程demochain
  • 创建Block文件
  • 创建Block结构体与相关函数
package demochain

import (
	"crypto/sha256"
	"encoding/hex"
	"time"
)

//区块结构体
type Block struct{
    Index int64 //区块编号
    Timestamp int64 //区块时间戳
    PrevBlockHash string //上一个区块的哈希值
    Hash string //当前区块哈希值

    Data string //区块数据
}

//计算hsah值
func calculateHash(b Block) string {
    //计算hash值包含除了当前区块哈希值的其他数据
    blockData:=string(b.Index)+string(b.Timestamp)+b.PrevBlockHash+b.Data
    hashInBytes:=sha256.Sum256([]byte(blockData))
    return hex.EncodeToString(hashInBytes[:])
}

//生成新区块
func GenerateNewBlock(preBlock Block,data string) Block {
    newBlock:=Block{}
    newBlock.Index=preBlock.Index+1
    newBlock.PrevBlockHash=preBlock.Hash
    newBlock.Timestamp=time.Now().Unix()
    newBlock.Data=data
    newBlock.Hash=calculateHash(newBlock)
    return newBlock
}

//创始区块
func GenerateGenesisBlock(){
    preBlock :=Block{}
    preBlock.Index=-1
    preBlock.Hash=""
    GenerateNewBlock(preBlock,"Genesis Block")
}

创建Blockchain

  • 创建Blockchain文件
  • 创建Blockchain结构体及相关方法
package demochain

import (
	"fmt"
	"log"
)

type Blockchain struct {
	Blocks []*Block
}

//创建新的区块链
func NewBlockchain() *Blockchain {
    //创始区块
	genesisBlock := GenerateGenesisBlock()
	blockchain := Blockchain{}
	blockchain.AppendBlock(&genesisBlock)
	return &blockchain
}

//在区块上增加数据
func (bc *Blockchain) SendData(data string) {
	preBlock := bc.Blocks[len(bc.Blocks)-1]
	newBlock := GenerateNewBlock(*preBlock, data)
	bc.AppendBlock(&newBlock)
}

//添加区块
func (bc *Blockchain) AppendBlock(newBlock *Block) {
	if len(bc.Blocks) == 0 {
		bc.Blocks = append(bc.Blocks, newBlock)
		return
	}
	if isValid(*newBlock, *bc.Blocks[len(bc.Blocks)-1]) {
		bc.Blocks = append(bc.Blocks, newBlock)
	} else {
		log.Fatal("invalid block")
	}
}

//打印区块链里面的数据
func (bc *Blockchain) Print() {
	for _, block := range bc.Blocks {
		fmt.Printf("Index: %d\n", block.Index)
		fmt.Printf("PrevHash: %s\n", block.PrevBlockHash)
		fmt.Printf("CurrHash: %s\n", block.Hash)
		fmt.Printf("Data: %s\n", block.Data)
		fmt.Printf("Timestamp: %d\n", block.Timestamp)
		fmt.Println()
	}
}

//添加区块前校验
func isValid(newBlock Block, oldBlock Block) bool {
	if newBlock.Index-1 != oldBlock.Index {
		return false
	}
	if newBlock.PrevBlockHash != oldBlock.Hash {
		return false
	}
	if calculateHash(newBlock) != newBlock.Hash {
		return false
	}
	return true
}

创建区块链

package main

import "go-blockchain/core"

func main() {
	bc := core.NewBlockchain()
	bc.SendData("Send 1 BTC to Alice")
	bc.SendData("Send 1 EOS to Bob")
	bc.Print()
}

结果

创建Http Server

步骤

  • 创建http server
  • 提供API访问接口
package main

import (
	"encoding/json"
	"go-blockchain/core"
	"io"
	"net/http"
)


//全局的blockchain变量
var blockchain *core.Blockchain

//提供http服务
func run() {
	http.HandleFunc("/blockchain/get", blockchainGetHandler)
	http.HandleFunc("/blockchain/write", blockchainWriteHandler)
	//监听端口
	http.ListenAndServe("localhost:8888", nil)
}

//get请求的方法
func blockchainGetHandler(w http.ResponseWriter, r *http.Request) {
  //把任意对象转换为json格式
	bytes, error := json.Marshal(blockchain)
	if error != nil {
		http.Error(w, error.Error(), http.StatusInternalServerError)
		return
	}
	//转换成string
	io.WriteString(w, string(bytes))
}
//write请求的方法
func blockchainWriteHandler(w http.ResponseWriter, r *http.Request) {
	blockData := r.URL.Query().Get("data")
	blockchain.SendData(blockData)
	blockchainGetHandler(w, r)
}

func main() {
	blockchain = core.NewBlockchain()
	run()
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/388477.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenCV入门(三)快速学会OpenCV2图像处理基础

OpenCV入门(三)快速学会OpenCV2图像处理基础 1.颜色变换cvtColor imgproc的模块名称是由image(图像)和process(处理)两个单词的缩写组合而成的,是重要的图像处理模块,主要包括图像…

VSCode问题记录

20230304 - 0. 引言 这几年的编程方式还真是各种变化,从一开始直接VIM,到后面使用jupyter进行机器学习相关,然后再过渡到vim的形式并加以tmux批量化,最后去年使用了vscode作为IDE。随着工具的变化,那么很多习惯也都随…

PyQGIS自定义应用程序打包

路径准备ps:打包时需要根据自己的安装路径进行相应修改QGIS3.22.16的安装路径:D:\QGIS3.22.16QGIS3.22.16中python-qgis.bat的路径:D:\QGIS3.22.16\bin\python-qgis-ltr.bat准备打包的工程所在目录:E:\Crater_DamageEstimation0303安装pyinst…

Python基础—文件操作

Python基础—文件操作 文件操作 文件是指为了重复使用或长期使用的目的,以文本或二进制形式存放于外部存储器(硬盘、U盘、光盘等)中的数据保存形式,文件是信息交换的重要途径,也是利用程序解决实际问题的重要媒介。 …

网络编程面试相关内容

1.什么是网络编程网络编程的本质是多台计算机之间的数据交换。数据传递本身没有多大的难度,不就是把一个设备中的数据发送给其他设备,然后接受另外一个设备反馈的数据。现在的网络编程基本上都是基于请求/响应方式的,也就是一个设备发送请求数…

RPC框架笔记

文章目录RPC概述一次RPC的完整过程RPC的优缺点分层设计编解码层——数据格式协议层——概念网络通信层——网络库RPC框架的关键指标稳定性易用性扩展性观测性高性能Kitex框架解读整体框架自研网络库——Netpoll扩展性设计性能优化——网络库优化性能优化——编解码优化合并部署…

【Flutter入门到进阶】Flutter基础篇---组件生命周期与状态

1 Android界面渲染流程UI树与FlutterUI树的设计思路对比 1.1 android渲染流程中的树的组织 1.1.1 XML加载与解析 1.1.2 ViewRootImpl组织树结构 1.1.3 编舞者掌控调用时机 1.1.4 View负责UI渲染 1.1.5 底层surfacefiling负责沟通硬件 1.2 flutter组件设计思路&#xff0c…

Canal实时监控案例

Canal实时监控案例 文章目录Canal实时监控案例0. 写在前面1. TCP 模式测试1.1 IDEA创建项目canal-module1.2 通用监视类——CanalClient1.2.1 Canal 封装的数据结构1.2.2 在 canal-module 模块下创建 cn.canal 包,并在该包下创建 CanalClient.java文件2. Kafka 模式…

前后端身份验证

1、web 开发模式 【】基于服务端渲染的传统 Web 开发模式 【】基于前后端分离的新型 Web 开发模式:依赖于 Ajax 技术的广泛应用。后端只负责提供 API 接口,前端使用 Ajax 调用接口的开发模式 2、身份认证 【】服务端渲染推荐使用 Session 认证机制 【】…

《堆的应用》TOP-K问题

TOP-K问题:即求数据中前k个最大的元素或者最小的元素,一般情况下,这些数据量是非常大的。 比如:专业前10名、世界500强、世界富豪榜、游戏中前100名等这些排名都是TOP-K问题。 来源于《财富》世界500强排行榜。 对于TOP-k问题,能想到的最简…

【XXL-JOB】XXL-JOB定时处理视频转码

【XXL-JOB】XXL-JOB定时处理视频转码 文章目录【XXL-JOB】XXL-JOB定时处理视频转码1. 准备工作1.1 高级配置1.2 分片广播2. 需求分析2.1 作业分片方案2.2 保证任务不重复执行2.2.1 保证幂等性3. 视频处理业务流程3.1 添加待处理任务3.2 查询待处理任务3.3 更新任务状态3.4 工具…

考研还是工作?两战失败老道有话说

老道入职第一周自我介绍谈谈考研谈谈工作新的启程自我介绍 大家好!在下是一枚考研失败两次的自认为聪明能干的有点小帅的实则超级垃圾的三非名校毕业的自动化渣男。大一下就加入实验室,在实验室焊板子、画板子、培训、打比赛外加摸鱼;参加过…

Swagger扩展 - 同一个接口生成多份Swagger API文档

为同一个ApiOperation生成多份不同Swagger API文档。 0. 目录1. 背景2. 效果展示3. 实现3.1 关键逻辑 - 让接口自解释3.2 关键逻辑 - 如何生成相应的ApiDescription3.3 关键逻辑 - 如何为生成的ApiDescription 赋值3.4 关键逻辑 - 如何动态生成Docket4. 继续优化5. 参考1. 背景…

【Spark分布式内存计算框架——Structured Streaming】3. Structured Streaming —— 入门案例:WordCount

1.3 入门案例:WordCount 入门案例与SparkStreaming的入门案例基本一致:实时从TCP Socket读取数据(采用nc)实时进行词频统计WordCount,并将结果输出到控制台Console。 文档:http://spark.apache.org/docs/2…

一个Bug让人类科技倒退几十年?

大家好,我是良许。 前几天在直播的时候,问了直播间的小伙伴有没人知道「千年虫」这种神奇的「生物」的,居然没有一人能够答得上来的。 所以,今天就跟大家科普一下这个人类历史上最大的 Bug 。 1. 全世界的恐慌 一个Bug会让人类…

Java中的自动类型提升与强制类型转换

一、自动类型提升 自动类型提升是指在程序运行时因为某种情况需要,JVM将较小的数据类型自动转换为较大的数据类型,以保证精度和正确性。在Java中,需要进行类型提升的情况有以下几种: 1. byte、short和char提升为int类型 当运算…

spark sql(五)sparksql支持查询哪些数据源,查询hive与查询mysql的区别

1、数据源介绍 sparksql默认查询的数据源是hive数据库,除此之外,它还支持其它类型的数据源查询,具体的到源码中看一下: 可以看到sparksql支持查询的数据源有CSV、parquet、json、orc、txt、jdbc。这些数据源中前面五个我还能理解&…

【Python】RPA批量生成word文件/重命名及批量删除

批量生成word文件 场景:需要新建多个类似文件名 比如:今天的事例是新建12个文件名为: ​ 保安员考试试卷1及答案.docx ​ 保安员考试试卷2及答案.docx ​ … ​ 保安员考试试卷12及答案.docx 痛点: ​ 手动操作重复性高&a…

目标检测中回归损失函数(L1Loss,L2Loss,Smooth L1Loss,IOU,GIOU,DIOU,CIOU,EIOU,αIOU ,SIOU)

文章目录L-norm Loss 系列L1 LossL2 LossSmooth L1 LossIOU系列IOU (2016)GIOU (2019)DIOU (2020)CIOU (2020)EIOU (2022)αIOU (2021)SIOU (2022…

【SpringCloud】SpringCloud详解之Eureka实战

目录前言SpringCloud Eureka 注册中心一.服务提供者和服务消费者二.需求三.搭建Eureka-Server四.搭建Eureka-Client(在服务提供者配置:用户订单)前言 微服务中多个服务,想要调用,怎么找到对应的服务呢? 这里有组件的讲解 → SpringCloud组件…