首页 > 其他分享 >基于Go语言跟我一起写DApp-转型区块链应用开发推荐课程GoSDK+Fisco-Bcos

基于Go语言跟我一起写DApp-转型区块链应用开发推荐课程GoSDK+Fisco-Bcos

时间:2023-10-21 09:45:34浏览次数:45  
标签:Bcos Blocks string DApp bc newBlock func GoSDK 区块

基于Go语言跟我一起写DApp-转型区块链应用开发推荐课程GoSDK+Fisco-Bcos

0 介绍

学习目标:1、理解什么是区块链;2、掌握区块链基本结构;3、构建区块链基本模型;

  • 理论部分:1、区块链七层架构模型;2、区块链链式结构;
  • 实践部分:1、创建区块;2、创建区块的“链”;3、访问区块链;

开发环境:GoLand (付费,学生可以申请免费,需要提供证明)
区块链的理论基础部分可以参考我写的其他博客,本文主要介绍实践。

开源代码:https://github.com/hexbo/go-blockchain-demo
如果有帮助欢迎star和分享~也欢迎提pr


1 区块链理论基础




数据层

hash

hash函数的特点:单向性、确定性、隐蔽性、抗篡改、抗碰撞;

区块链最基本的技术是hash,这里给出用go写的一个hash的demo:

package main

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

func calcHash(toBeHashed string) string {
	hashInBytes := sha256.Sum256([]byte(toBeHashed))
	hashInStr := hex.EncodeToString(hashInBytes[:])
	log.Printf("%s %s", toBeHashed, hashInStr)
	return hashInStr
}

func main() {
	calcHash("test1")
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

如果不熟悉Go,关于上述代码可能会有以下问题:

2 从0到1实现区块链模型

组成部分:1.实现区块和链式结构;2.实现一个简单的HTTP Server,对外暴露读写接口;

说明:Go语言函数名大小写:小写代表方法只能在当前包使用,是私有方法,大写代表公有方法。

区块 Block

package core

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

type Block struct {
	Index         int64  // 区块编号
	Timestamp     int64  // 区块时间戳
	PrevBlockHash string // 上一个区块哈希值
	Hash          string // 当前区块哈希
	Data          string // 区块数据
}

func calculateHash(b Block) string {
	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() Block {
	preBlock := Block{}
	preBlock.Index = -1
	preBlock.Hash = ""
	return GenerateNewBlock(preBlock, "Genesis Block")
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

链式结构

代码说明:参数名在函数前是结构函数的语法,类似C++的类成员函数,GO里都是绑定到结构体上的。

package core

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)
	}
}

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
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

【问题】如下代码: 这里的len函数在这里不会冗余吗?
C的strlen需要对char数组遍历一遍,因此相当于O(n)的复杂度,不是O(1),不清楚Go的len函数

if isValid(*newBlock, *bc.Blocks[len(bc.Blocks)-1]) {
 
  • 1

说明:参考上面给出的一个关于go string存储的问题,go在字符串指针开头存了字符串长度数据,而不是在末尾存’\0’,所以应该是可以O(1)查询。

CMD验证

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()
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

HTTP RPC读写

package main

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

var blockchain *core.Blockchain

func run() {
	http.HandleFunc("/blockchain/get", blockchainGetHandler)
	http.HandleFunc("/blockchain/write", blockchainWriteHandler)
	http.ListenAndServe("localhost:8888", nil)
}

func blockchainGetHandler(w http.ResponseWriter, r *http.Request) {
	bytes, error := json.Marshal(blockchain)
	if error != nil {
		http.Error(w, error.Error(), http.StatusInternalServerError)
		return
	}
	io.WriteString(w, string(bytes))
}

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()
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

运行后访问localhost:8888/blockchain/get可以查看当前区块数据,访问/write?data="xxxx"可以写数据

Reference

  1. video
 

标签:Bcos,Blocks,string,DApp,bc,newBlock,func,GoSDK,区块
From: https://www.cnblogs.com/add1188/p/17778474.html

相关文章

  • Web3.0-DApp开发热门技术项目实战课程+智能合约编写+交易所的实战项目
    web1.0~3.0,很多年前,互联网没有那么发达,刚出来的时候,仅仅只能在网上浏览观看信息,这就是1.0,后来出现了很多的软件,人们不仅可以浏览还可以发表自己的看法,手机app百花齐放,每个应用都有自己的数据库,存储数据,这就是2.0,现如今出现了3.0,去中心化的思想摆脱了数据库,即可实现不用数据库也......
  • FISCO-BCOS[WeBASEUtils工具类]
    packagepriv.pront.PetStore.utils;importcn.hutool.core.lang.Dict;importcn.hutool.http.Header;importcn.hutool.http.HttpRequest;importcn.hutool.http.HttpResponse;importcn.hutool.json.JSONArray;importcn.hutool.json.JSONObject;importcn.hutool.j......
  • 关于FISCO-BCOS如何进行节点扩容并添加到群组
    本节假设已经参照搭建第一个区块链网络搭建了一条n节点的联盟链,接下来的操作将生成一个新的节点,然后将节点加入群组1。......
  • 执行SQL语句&存储过程的真正【神器】,不用ORM的全选它,比dapper好
    支持.NetCore(2.0及以上)与.NetFramework(4.0及以上)(注意:升级了,可以覆盖到早期的.NetFramework4.0了,而且修复了数据库字段为Null时报错的问题,无敌了!!)此工具在IDataAccess接口中提供。 已被.Net圈内多家大厂采用!IDataAccess所在的命名空间是:DeveloperSharp.Framework.QueryE......
  • DApp智能合约去中心化软件
      DApp,全称DecentralizedApplication,经常使用的人都知道,它是基于去中心化的应用程序的方向,dapp是通过智能化的合约技术实现,是在上链上运行的,是去中心化的应用软件。  DApp智能合约去中心化软件功能的主要核心,就是无需提供去中心化的服务器,所有的数据都是存储在链上的,具有......
  • dapp链游系统开发搭建
      本文就指导你搭建一个基于上链接的链游系统软件,来看看这些步骤都有哪些吧。  1.先了解链游系统的技术开发功能,软件包括以太,Truffle技术,这个技术是基于构建以太的应用程序开发,帮助用户快速的实现搭建dapp,链游系统软件。  2.建立游戏项目,相关的代码管理,软件的控制,使......
  • HybridApp(混合应用)开发框架的优缺点分析
    写在前面HybridApp作为一种既能够在原生应用程序环境中运行,也能够在Web浏览器中运行的应用程序。它主要使用Web技术进行开发,如HTML、CSS和JavaScript,并使用一个中间层将其封装在原生应用程序中。当然技术的持续推进,HybridApp相关的前端框架也应运而生。准备比较......
  • dapp开发项目设计需求功能
      dapp项目的开发是结合了区块软件的技术,dapp的软件系统已经成为某个行业的赚钱焦点。dapp的项目基于去中心化的应用程序,让用户拥有一定的自主权和主动权,在交易时有一定的限制,具有很好的公平性,数据不受任何的机构限制。开发设计dapp项目,首先就是先考虑到软件的功能需求。 ......
  • 存储过程Select/Return/Output与Dapper对应关系
    存储过程:ALTERPROCEDURE[dbo].[usp_test]@testintoutputASBEGINselect@test=12;select11;END对应关系:1.参数out,output均可以,都对应Dapper:parameters.Add("@test",dbType:DbType.Int32,direction:ParameterDirection.Output);intm2=parameters.Get......
  • dapper mysql 批量新增修改
    dapper是C#程序员比较喜欢用的轻量级ORM,简单易学,只是没有批量新增以及修改(收费版有),写了如下扩展///<summary>///dapperMySQL批量新增修改扩展///</summary>publicstaticclassDapperExtensions{///<summary>///批量插入......