区块链技术与应用

Posted 仿生程序员会梦见电子羊吗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区块链技术与应用相关的知识,希望对你有一定的参考价值。

https://blog.csdn.net/lakersssss24/article/details/125762826?spm=1001.2014.3001.5501
https://blog.csdn.net/lakersssss24/article/details/126434147
https://blog.csdn.net/lakersssss24/article/details/126671408?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-3-126671408-blog-126434147.pc_relevant_3mothn_strategy_and_data_recovery&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-3-126671408-blog-126434147.pc_relevant_3mothn_strategy_and_data_recovery&utm_relevant_index=4

提前准备

sudo apt-get update  更新源 
sudo apt-get install ssh 安装远程客户端
sudo apt-get install curl 安装命令行工具
sudo apt-get install git 安装git
sudo apt-get install gcc 安装gcc
sudo apt-get install vim 安装vim文件编辑器
sudo apt-get install make 安装make
sudo apt-get install net-tools 安装网络工具
sudo apt-get install net-tools  安装mousepad 类似于windows的记事本
./bootstrap.sh

https://teach.imcn.me/y2020/1146.html

couchDB安装 https://blog.csdn.net/TU_Dresden/article/details/126864418

实验一

network

./network.sh up


./network.sh up createChannel -s couchdb

./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go


export PATH=$PWD/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP" 
export CORE_PEER_TLS_ROOTCERT_FILE=$PWD/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=$PWD/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$PWD/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles "$PWD/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "$PWD/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '"function":"InitLedger","Args":[""]'


restart

./network.sh up createChannel -ca -s couchdb


gin模板

package main
 
import (
	"fmt"
	"github.com/gin-gonic/gin"
)
 
type Stu struct 
	Name string `form:"name"`
	Id   string `form:"id"`
	Age  string `form:"age"`

 
func main() 
	r := gin.Default()
	var stu Stu
	r1 := r.Group("/fabric2.4")
	r1.POST("/setstu", func(c *gin.Context) 
		//var stu Stu
		c.ShouldBind(&stu)
		c.JSON(200, stu)
		fmt.Println("stu:", stu)
	)
	r1.POST("/ok1", func(c *gin.Context) 
		c.JSON(200, "ok1")
	)
	r.Run(":8080") // 监听并在 0.0.0.0:8080 上启动服务
 

链码的只要功能部分:

package chaincode
 
import (
	"encoding/json"
	"fmt"
 
	"github.com/hyperledger/fabric-contract-api-go/contractapi"
)
 
// SmartContract provides functions for managing an Asset
type SmartContract struct 
	contractapi.Contract

 
// Asset describes basic details of what makes up a simple asset
//Insert struct field in alphabetic order => to achieve determinism across languages
// golang keeps the order when marshal to json but doesn't order automatically
type Asset struct 
	AppraisedValue int    `json:"AppraisedValue"`
	Color          string `json:"Color"`
	ID             string `json:"ID"`
	Owner          string `json:"Owner"`
	Size           int    `json:"Size"`

 
// InitLedger adds a base set of assets to the ledger
func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface) error 
	assets := []Asset
		ID: "asset1", Color: "blue", Size: 5, Owner: "Tomoko", AppraisedValue: 300,
		ID: "asset2", Color: "red", Size: 5, Owner: "Brad", AppraisedValue: 400,
		ID: "asset3", Color: "green", Size: 10, Owner: "Jin Soo", AppraisedValue: 500,
		ID: "asset4", Color: "yellow", Size: 10, Owner: "Max", AppraisedValue: 600,
		ID: "asset5", Color: "black", Size: 15, Owner: "Adriana", AppraisedValue: 700,
		ID: "asset6", Color: "white", Size: 15, Owner: "Michel", AppraisedValue: 800,
	
 
	for _, asset := range assets 
		assetJSON, err := json.Marshal(asset)
		if err != nil 
			return err
		
 
		err = ctx.GetStub().PutState(asset.ID, assetJSON)
		if err != nil 
			return fmt.Errorf("failed to put to world state. %v", err)
		
	
 
	return nil

 
// CreateAsset issues a new asset to the world state with given details.
func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, id string, color string, size int, owner string, appraisedValue int) error 
	exists, err := s.AssetExists(ctx, id)
	if err != nil 
		return err
	
	if exists 
		return fmt.Errorf("the asset %s already exists", id)
	
 
	asset := Asset
		ID:             id,
		Color:          color,
		Size:           size,
		Owner:          owner,
		AppraisedValue: appraisedValue,
	
	assetJSON, err := json.Marshal(asset)
	if err != nil 
		return err
	
 
	return ctx.GetStub().PutState(id, assetJSON)

 
// ReadAsset returns the asset stored in the world state with given id.
func (s *SmartContract) ReadAsset(ctx contractapi.TransactionContextInterface, id string) (*Asset, error) 
	assetJSON, err := ctx.GetStub().GetState(id)
	if err != nil 
		return nil, fmt.Errorf("failed to read from world state: %v", err)
	
	if assetJSON == nil 
		return nil, fmt.Errorf("the asset %s does not exist", id)
	
 
	var asset Asset
	err = json.Unmarshal(assetJSON, &asset)
	if err != nil 
		return nil, err
	
 
	return &asset, nil

 
// UpdateAsset updates an existing asset in the world state with provided parameters.
func (s *SmartContract) UpdateAsset(ctx contractapi.TransactionContextInterface, id string, color string, size int, owner string, appraisedValue int) error 
	exists, err := s.AssetExists(ctx, id)
	if err != nil 
		return err
	
	if !exists 
		return fmt.Errorf("the asset %s does not exist", id)
	
 
	// overwriting original asset with new asset
	asset := Asset
		ID:             id,
		Color:          color,
		Size:           size,
		Owner:          owner,
		AppraisedValue: appraisedValue,
	
	assetJSON, err := json.Marshal(asset)
	if err != nil 
		return err
	
 
	return ctx.GetStub().PutState(id, assetJSON)

 
// DeleteAsset deletes an given asset from the world state.
func (s *SmartContract) DeleteAsset(ctx contractapi.TransactionContextInterface, id string) error 
	exists, err := s.AssetExists(ctx, id)
	if err != nil 
		return err
	
	if !exists 
		return fmt.Errorf("the asset %s does not exist", id)
	
 
	return ctx.GetStub().DelState(id)

 
// AssetExists returns true when asset with given ID exists in world state
func (s *SmartContract) AssetExists(ctx contractapi.TransactionContextInterface, id string) (bool, error) 
	assetJSON, err := ctx.GetStub().GetState(id)
	if err != nil 
		return false, fmt.Errorf("failed to read from world state: %v", err)
	
 
	return assetJSON != nil, nil

 
// TransferAsset updates the owner field of asset with given id in world state, and returns the old owner.
func (s *SmartContract) TransferAsset(ctx contractapi.TransactionContextInterface, id string, newOwner string) (string, error) 
	asset, err := s.ReadAsset(ctx, id)
	if err != nil 
		return "", err
	
 
	oldOwner := asset.Owner
	asset.Owner = newOwner
 
	assetJSON, err := json.Marshal(asset)
	if err != nil 
		return "", err
	
 
	err = ctx.GetStub().PutState(id, assetJSON)
	if err != nil 
		return "", err
	
 
	return oldOwner, nil

 
// GetAllAssets returns all assets found in world state
func (s *SmartContract) GetAllAssets(ctx contractapi.TransactionContextInterface) ([]*Asset, error) 
	// range query with empty string for startKey and endKey does an
	// open-ended query of all assets in the chaincode namespace.
	resultsIterator, err := ctx.GetStub().GetStateByRange("", "")
	if err != nil 
		return nil, err
	
	defer resultsIterator.Close()
 
	var assets []*Asset
	for resultsIterator.HasNext() 
		queryResponse, err := resultsIterator.Next()
		if err != nil 
			return nil, err
		
 
		var asset Asset
		err = json.Unmarshal(queryResponse.Value, &asset)
		if err != nil 
			return nil, err
		
		assets = append(assets, &asset)
	
 
	return assets, nil

查看虚拟机的IP和地址:

ifconfig

gin框架

package main
 
import (
	"bytes"
	"crypto/x509"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/hyperledger/fabric-gateway/pkg/client"
	"github.com/hyperledger/fabric-gateway/pkg/identity"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"io/ioutil"
	"path"
	"time"
)
 
const (
	mspID         = "Org1MSP"
	cryptoPath    = "./peerOrganizations/org1.example.com"
	certPath      = cryptoPath + "/users/User1@org1.example.com/msp/signcerts/cert.pem"
	keyPath       = cryptoPath + "/users/User1@org1.example.com/msp/keystore/"
	tlsCertPath   = cryptoPath + "/peers/peer0.org1.example.com/tls/ca.crt"
	peerEndpoint  = "192.168.136.130:7051"
	gatewayPeer   = "peer0.org1.example.com"
	channelName   = "mychannel"
	chaincodeName = "basic"
)
 
type Asset struct 
	AppraisedValue int    `form:"appraisedValue" json:"appraisedValue" `
	Color          string `form:"color" json:"color"`
	ID             string `form:"id" json:"id"`
	Owner          string `form:"owner" json:"owner"`
	Size           int    `form:"size" json:"size"`

 
func main() 
	// The gRPC client connection should be shared by all Gateway connections to this endpoint
	clientConnection := newGrpcConnection()
	defer clientConnection.Close()
 
	id := newIdentity()
	sign := newSign()
 
	// Create a Gateway connection for a specific client identity
	gateway, err := client.Connect(
		id,
		client.WithSign(sign),
		client.WithClientConnection(clientConnection),
		// Default timeouts for different gRPC calls
		client.WithEvaluateTimeout(5*time.Second),
		client.WithEndorseTimeout(15*time.Second),
		client.WithSubmitTimeout(5*time.Second),
		client.WithCommitStatusTimeout(1*time.Minute),
	)
	if err != nil 
		panic(err)
	
	defer gateway.Close()
	network := gateway.GetNetwork(channelName)
	contract := network.GetContract(chaincodeName)
 
	r := gin.Default()
	r1 := r.Group("/fabric2.4")
	r1.POST("/CreateAsset", func(c *gin.Context) 
		var asset Asset
		c.ShouldBind(&asset)
		c.JSON(200, asset)
		marshal, _ := json.Marshal(asset)
		fmt.Println(string(marshal))
		fmt.Println("asset:", asset)
	)
	r1.POST("/GetAllAssets", func(c *gin.Context) 
		result := getAllAssets(contract)
		c.JSON(200, result)
	)
	r.Run(":8080") // 监听并在 0.0.0.0:8080 上启动服务
 

 
// Evaluate a transaction to query ledger state.
func getAllAssets(contract *client.Contract) string 
	fmt.Println("Evaluate Transaction: GetAllAssets, function returns all the current assets on the ledger")
 
	evaluateResult, err := contract.EvaluateTransaction("GetAllAssets")
	if err != nil 
		panic(fmt.Errorf("failed to evaluate transaction: %w", err))
	
	result := formatJSON(evaluateResult)
 
	fmt.Printf("*** Result:%s\\n", result)
 
	return string(evaluateResult)

 
// newGrpcConnection creates a gRPC connection to the Gateway server.
func newGrpcConnection() *grpc.ClientConn 
	certificate, err := loadCertificate(tlsCertPath)
	if err != nil 
		panic(err)
	
 
	certPool := x509.NewCertPool()
	certPool.AddCert(certificate)
	transportCredentials := credentials.NewClientTLSFromCert(certPool, gatewayPeer)
 
	connection, err := grpc.Dial(peerEndpoint, grpc.WithTransportCredentials(transportCredentials))
	if err != nil 
		panic(fmt.Errorf("failed to create gRPC connection: %w", err))
	
 
	return connection

 
// newIdentity creates a client identity for this Gateway connection using an X.509 certificate.
func newIdentity() *identity.X509Identity 
	certificate, err := loadCertificate(certPath)
	if err != nil 
		panic(err)
	
 
	id, err := identity.NewX509Identity(mspID, certificate)
	if err != nil 
		panic(err)
	
 
	return id

 
func loadCertificate(filename string) (*x509.Certificate, error) 
	certificatePEM, err := ioutil.ReadFile(filename)
	if err != nil 
		return nil, fmt.Errorf("failed to read certificate file: %w"以上是关于区块链技术与应用的主要内容,如果未能解决你的问题,请参考以下文章

《区块链应用指南方法与实践》读书笔记

《区块链应用指南方法与实践》读书笔记

《区块链应用指南方法与实践》读书笔记

[技术发展-5]:《区块链与加快推动区块链技术和产业创新发展》

从《区块链技术原理与应用实践》看区块链技术如何激活新场景赋能价值传递

区块链技术应用与安全发展