Hyperledger Fabric 入门笔记(四)Fabric V2.4 测试网络基础

2023-10-27

文章目录


前言

本篇主要参考官方技术文档,介绍了如何测试网络的准备工作、使用脚本搭建测试网络的细节以及示例应用的运行。


一、准备测试网络

1.1. 概述

Fabric官方提供了一个基础示例项目fabric-samples,项目仓库为hyperledger/fabric-samples。该项目可以部署一个测试网络,专用于引导用户学习Fabric区块链网络的基本特性和操作。

部署这个测试网络需要预先准备三部分内容:

  • 示例,即fabric-samples仓库。
    注1:包括示例链码等,正常开发不需要这部分内容。
  • 平台特定的Hyperledger Fabric CLI工具二进制文件和配置文件(platform-specific Hyperledger Fabric CLI tool binaries and config files)。
    注2:详见后文。
  • Fabric Docker镜像。
    注3:Fabric的节点以Docker容器的形式运行。而镜像(Image)和容器(Container)的关系就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。因此需要先获取所需的镜像。

官方提供了两个脚本bootstrap.sh和install-fabric.sh用于获取上述内容。两个脚本的源代码都位于GitHub上的hyperledger/fabric项目的scripts文件夹中,使用方法和运行效果也相同,但是install-fabric.sh脚本的语法较bootstrap.sh脚本有所改进。

具体来讲,脚本的作用如下:

  1. 如果当前目录中没有hyperledger/fabric-samples,则从GitHub克隆hyperledger/fabric-samples项目仓库并签出(checkout)指定的版本标签。
  2. 将指定版本的平台特定的Hyperledger Fabric CLI工具二进制文件和配置文件分别放到本地fabric-samples仓库的根目录下的/bin和/config目录中。
  3. 从Docker Hub上下载指定版本的Hyperledger Fabric Docker镜像文件到本地Docker注册表中,并将下载的镜像文件标记为"latest"。

1.2. 完成准备工作

1.2.1. 运行install-fabric.sh脚本

为了方便后期管理,在当前登录用户的HOME目录下创建一个空目录并进入该目录:

mkdir hyfa && cd hyfa

在当前目录下新建一个名为install-fabric.sh的文件:

vim install-fabric.sh

打开浏览器,在网址栏输入install-fabric.sh脚本源代码的URL(https://github.com/hyperledger/fabric/blob/main/scripts/install-fabric.sh),将其中的代码复制过来,保存后退出。

赋予install-fabric.sh脚本文件可执行权限:

chmod +x install-fabric.sh

执行install-fabric.sh:

./install-fabric.sh

注1:不建议在执行该脚本时使用root权限,即,不要执行sudo ./install-fabric.sh

注2:下载可能需要几分钟,也可能需要十几分钟,取决于当前的网络环境。如果下载太慢,可以换个时间段,无需其它操作。

注3:使用该脚本时如遇到任何错误,再次执行即可。

注4:可以执行./install-fabric.sh -h打印帮助文档查看如何有选择地安装特定版本或者特定组件。

1.2.2. 文件夹去锁(可选)

执行install-fabric.sh脚本时,如果使用了root权限,脚本运行后,在GUI中会发现fabric-samples文件夹是带锁的,无法移动文件到该文件夹。同时fabric-samples文件夹以及其中的全部文件的属主都是root,当前用户在运行文件夹中的脚本时会因为权限不够而报错。

如果使用chmod指令解锁文件夹,虽然可以去锁,但是会使里面的全部文件夹带锁;如果递归解锁,则文件在终端中都会绿色高亮(因为所有用户都有读/写/执行的权限,Linux系统默认认为这些文件是高风险文件),如此一来不美观。另外这也没有解决运行脚本时可能的权限不足问题。

最好的解决方法是把fabric-samples文件夹的属主更改为当前用户:

sudo chown -R $USER fabric-samples

1.3. install-fabric.sh脚本运行结果

默认情况下,运行install-fabric.sh的结果如下:

  1. 克隆hyperledger/fabric-samples到当前目录并签出。之后在该文件夹下可以用git branch命令查看当前的分支。
    在这里插入图片描述
  2. 拉取Hyperledger Fabric二进制文件:实际上是下载了hyperledger-fabric-linux-amd64-x.x.x.tar.gz和hyperledger-fabric-ca-linux-amd64-x.x.x.tar.gz这两个压缩文件,然后解压到指定目录,然后删除压缩文件。
    在这里插入图片描述
  3. 拉取Hyperledger Fabric Docker镜像文件:具体来讲是拉取fabric-peer、fabric-orderer、fabric-ccenv、fabric-tools、fabric-baseos和fabric-ca这6个镜像文件。

1.4. 什么是二进制文件?

如前一节所示,拉取二进制文件其实是先下载了两个.tar.gz格式的压缩文件。

.tar.gz格式的压缩文件是源代码的安装包,解压时会编译一些所谓的二进制文件,即可执行文件(可以理解成一个工具)。将该格式的压缩文件放到Windows的系统中,用压缩软件打开,可以看到最终的可执行文件都有哪些。

如图所示,fabric-samples/bin目录里的即为二进制文件,而fabric-samples/config目录里的则是配置文件。查看GitHub上的fabric-samples仓库,可以发现没有这两个目录及其中的内容,证明这是额外实现的。

在这里插入图片描述

hyperledger-fabric-ca-linux-amd64-x.x.x.tar.gz解压后是bin文件夹下的fabric-ca-client和fabric-ca-server这两个二进制文件。

hyperledger-fabric-linux-amd64-x.x.x.tar.gz解压后则是config文件夹下的.yaml配置文件和bin文件夹下的其他二进制文件。

1.5. 备用的准备方法(可选)

参考运行结果,也可以手动实现脚本完成的工作。

  1. 克隆fabric-samples仓库并签出:
git clone https://gitee.com/hyperledger/fabric-samples.git
cd fabric-samples
git checkout -q v2.4.7
  1. 下载压缩文件并解压:
wget https://github.com/hyperledger/fabric/releases/download/v2.4.7/hyperledger-fabric-linux-amd64-2.4.7.tar.gz
tar -zxvf hyperledger-fabric-linux-amd64-2.4.7.tar.gz
wget https://github.com/hyperledger/fabric-ca/releases/download/v1.5.5/hyperledger-fabric-ca-linux-amd64-1.5.5.tar.gz
tar -zxvf hyperledger-fabric-ca-linux-amd64-1.5.5.tar.gz

注:如果无法在虚机上下载,则直接从https://github.com/hyperledger/fabric/tags上下载对应版本的压缩文件,再复制到虚机的fabric-samples文件夹下即可。
3. 使用docker pull命令从Docker Hub拉取指定的Docker镜像文件并将已下载的镜像标记为最新:

docker pull hyperledger/fabric-peer:2.4.7 \ 
&& docker pull hyperledger/fabric-orderer:2.4.7 \ 
&& docker pull hyperledger/fabric-ca:1.5.5 \ 
&& docker pull hyperledger/fabric-tools:2.4.7 \ 
&& docker pull hyperledger/fabric-ccenv:2.4.7 \ 
&& docker pull hyperledger/fabric-baseos:2.4.7
docker tag hyperledger/fabric-peer:2.4.7 hyperledger/fabric-peer \ 
&& docker tag hyperledger/fabric-orderer:2.4.7 hyperledger/fabric-orderer \ 
&& docker tag hyperledger/fabric-ca:1.5.5 hyperledger/fabric-ca \ 
&& docker tag hyperledger/fabric-tools:2.4.7 hyperledger/fabric-tools \ 
&& docker tag hyperledger/fabric-ccenv:2.4.7 hyperledger/fabric-ccenv \ 
&& docker tag hyperledger/fabric-baseos:2.4.7 hyperledger/fabric-baseos

二、使用测试网络

2.1. 概述

Fabric官方提供了提供了一个脚本network.sh用于启动测试网络。进入测试网络的目录,可以找到该脚本:

cd ~/hyfa/fabric-samples/test-network

2.2. 基本用法

2.2.1. 启动网络

启动一个默认名称为“fabric_test”的网络:

./network.sh up

启动网络后可以docker ps查看容器。

2.2.2. 创建通道

创建一个默认名称为“mychannel”的通道:

./network.sh createChannel

2.2.3. 在通道部署链码

部署Go版本的asset-transfer-basic链码:

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

在这里插入图片描述

链码部署后可以再次查看容器,将会看到多出了两个实例。

2.2.4. 关停网络

./network.sh down

该命令将停止并删除节点和链码容器,删除组织加密材料,并从Docker Registry移除链码镜像。该命令还删除之前运行的通道项目和docker卷。

注:如果未正常关停网络,下次启动测试网络时,应先执行该命令。

2.3. 报错

2.3.1. 跟文件权限相关的报错

错误描述:permission denied

在这里插入图片描述

报错原因:当前用户对fabric-samples文件夹的权限不够。

解决方法:更改fabric-samples文件夹的权限(见1.2.2节);或者在运行脚本前先获得root shell权限(sudo bash)。

2.3.2. 跟Docker相关的报错

错误1

错误描述:Got permission denied while trying to connect to the Docker daemon socket

在这里插入图片描述

报错原因:docker守护进程启动的时候,会默认赋予名字为docker的用户组读写Unix socket的权限,如果在安装docker时没有将当前用户添加到docker组,则会出现如下问题。

解决方法:创建docker用户组,并将当前用户加入到docker用户组中,那么当前用户就有权限访问Unix socket,进而也就可以执行docker相关命令。

sudo groupadd docker
sudo gpasswd -a $USER docker
newgrp docker
错误2

错误描述:Version in “./compose/compose-test-net.yaml” is unsupported

在这里插入图片描述

报错原因:docker-compose在使用.yaml文件时,文件里的版本号与docker和docker-compose的版本有要求,则需要更新的版本。

解决方法:更新docker和docker-compose,或者修改.yaml文件里的版本号。

错误3

错误描述:UnixHTTPConnectionPool(host=‘localhost’, port=None): Read timed out. (read timeout=60)

在这里插入图片描述

报错原因:docker-compose启动容器花费的时间超过默认设定的60S,见于性能特别差劲的系统。

解决方法:修改超时默认设置。

vim /etc/profile
export DOCKER_CLIENT_TIMEOUT=500
export COMPOSE_HTTP_TIMEOUT=500
source /etc/profile

2.3.3. 跟Golang相关的报错

错误1

错误描述:go: 未找到命令

在这里插入图片描述

报错原因:没有正确配置配置Golang环境。

解决方法:正确配置Golang。

错误2

错误描述:Error: failed to normalize chaincode path: ‘go list‘ failed …

报错原因:下载依赖的连接被拒绝。

解决方法:更换Golang代理。

2.4. 脚本使用语法

network.sh脚本的语法是:network.sh <mode> [flag]

其中,<…>代表必选项,[…]代表可选项。

mode有5种,说明如下。

  • up:启动Fabric网络,但是不创建通道。
  • createChannel:在网络启动后创建一个通道。
  • up createChannel:启动Fabric网络并创建通道。
  • deployCC:部署链码到通道。
  • down:关闭Fabric网络。

flag根据mode的选择有不同,并且可以多选。

当mode为up或createChannel时,说明如下。

  • -ca:使用CA生成网络加密材料。
  • -c:定义要创建的通道的名称(默认为“mychannel”)。
  • -s:选择Peer节点的状态数据库的类型,LevelDB(默认)或CouchDB。
  • -r:客户端最大重试请求次数(默认为5次)。
  • -d:客户端最大请求时延(默认为3秒)。
  • -verbose:Verbose模式,用于输出详细的日志信息。

注:在Verbose模式下,脚本会在特定的地方使用env命令和grep命令在终端中列出相关的环境变量及其赋值,可以参见test-netork/scripts目录下的envVar.sh脚本。

当mode为deployCC时,部分说明如下。

  • -c:部署链码的通道名。
  • -ccn:链码名。
  • -ccp:链码的文件路径。
  • -ccl:链码的编程语言。

2.5. network.sh脚本代码详解

2.5.1. 脚本的功能说明

network.sh脚本会根据启动脚本时输入的子命令和参数运行对应的函数。

在这里插入图片描述

2.5.2. 脚本启动网络详解

2.5.2.1. 总体说明

如果使用up子命令,network.sh脚本会运行networkUp()函数。

在这里插入图片描述

该函数的作用如下:

  1. 调用checkPrereqs()函数。该函数会进行一些检查,包括二进制文件和配置文件是否存在、二进制文件跟镜像的版本是否匹配,等等。

  2. 调用createOrgs()函数。该函数为Peer节点和排序服务创建所有部署和操作网络所需要的加密材料并调用organisations文件夹中的ccp-generate.sh脚本为Org1和Org2生成CCP文件。

  3. 使用docker-compose启动节点的容器。

2.5.2.2. 加密材料的生成
Option 1:使用cryptogen工具

默认情况下,createOrgs()函数使用bin文件夹中的cryptogen工具的generate命令分别为Org1、Org2和Orderer Org创建证书和密钥,配置文件在organizations/cryptogen文件夹中。

在这里插入图片描述

Option 2:使用Fabric CA组件

如果带了CA标志,createOrgs()函数使用docker-compose和配置文件compose/compose-ca.yaml及compose/docker/docker-compose-ca.yaml来启动三个Fabric CA服务器的容器。

容器的镜像为fabric-ca,配置文件位于organizations/fabric-ca文件夹中。

在这里插入图片描述

这些容器在启动时会执行命令fabric-ca-server start -b admin:adminpw -d并使用各自的配置文件生成CA证书、秘钥和数据库等内容,并和配置文件存放在一起。

createOrgs()函数继续调用位于organizations/fabric-ca文件夹的registerEnroll.sh脚本中的函数,使用Fabric CA客户端和刚刚生成的内容为Org1、Org2和Orderer Org创建证书和密钥。

2.5.2.3. docker-compose启动容器
Option 1:使用LevelDB

默认情况下,docker-compose使用配置文件compose/compose-test-net.yaml以及compose/docker/docker-compose-test-net.yaml启动容器peer0.org1.example.com、peer0.org2.example.com、orderer.example.com及cli。其中,peer0.org1.example.com和peer0.org2.example.com分别是Org1和Org2的peer节点,orderer.example.com是排序节点,cli是测试网络的维护节点。

Option 2:使用CouchDB

如果在启动网络时,数据库选用couchdb,docker-compose还会使用配置文件compose/compose-couch.yaml以及compose/docker/docker-compose-couch.yaml启动容器couchdb0和couchdb1分别作为Org1和Org2的的peer节点的数据库。

2.5.3. 脚本创建通道详解

如果使用createChannel子命令,network.sh脚本会运行createChannel()函数。该函数又会根据提供的通道名称调用scripts/createChannel.sh脚本。

在这里插入图片描述

createChannel.sh脚本首先运行creatChannelGenesisBlock()函数,使用configtxgen工具基于配置文件configtx/configtx.yaml中的TwoOrgsApplicationGenesis配置创建通道创世块。

在这里插入图片描述

createChannel.sh脚本然后运行createChannel()函数,使用osnadmin工具创建通道。

在这里插入图片描述

createChannel.sh脚本接着运行joinChannel()函数,使用Peer工具将Peer节点peer0.org1.example.com和peer0.org2.example.com连接到通道。

在这里插入图片描述

createChannel.sh脚本最后运行setAnchorPeer()函数,该函数直接调用scripts文件夹中的setAnchorPeer.sh脚本使这两个Peer节点设为锚节点。

在这里插入图片描述

2.5.4. 脚本部署链码详解

如果使用deployCC子命令,network.sh脚本会运行deployCC()函数。

在这里插入图片描述

该函数直接调用Scripts文件夹下的deployCC.sh脚本部署链码。

deployCC.sh脚本首先会安装链码依赖:

在这里插入图片描述

然后调用packageChaincode()方法,该方法使用peer lifecycle chaincode package命令创建链码包:

在这里插入图片描述

接着调用installChaincode()方法分别在组织1和组织2的peer节点上安装链码包,调用queryInstalled()方法查询安装结果。

接着调用approveForMyOrg()方法为组织1批准链码定义,并调用checkCommitReadiness()方法检查链码定义是否可以提交,期望结果是组织1已经批准而组织2还没有;再一次调用approveForMyOrg()方法为组织2批准链码定义,此时再调用checkCommitReadiness()方法检查链码定义是否可以提交,期望结果变为组织1和组织2都已经批准。

最后调用commitChaincodeDefinition()方法提交链码定义到通道,并调用querCommitted()方法查询提交是否成功。

可选的,可以额外调用chaincodeInvokeInit()方法初始化账本,但这要求链码中实现了InitLedger()方法。

上述这些方法的定义见Scripts文件夹下的ccutils.sh脚本。

在这里插入图片描述

2.6. 脚本运行结果说明

2.6.1. 加密材料

使用up子命令时,network.sh脚本运行networkUp()函数。networkUp()函数则会调用createOrgs()函数使用cryptogen工具或者Fabric CA组件为Peer节点和排序服务创建加密材料。

两种方式均会在organisations文件夹内创建如下两个子文件夹:

ordererOrganizations:保存负责管理排序节点的组织的相关资源。

peerOrganizations:保存负责管理Peer节点的组织的相关资源。

两个子文件夹下会以组织的域名创建文件夹,保存该组织的资源。管理排序节点的组织的域名下包含如下文件夹:

  • ca:保存负责管理排序节点的CA证书和私钥。
  • tlsca:保存排序节点通信时用到的证书和私钥。
  • user:保存排序节点管理员用户的证书和私钥。
  • msp:保存上面各种类型的所有证书和私钥,因为在一些配置文件中存在直接引用MSP文件夹的情况。
  • orderers:保存各个排序节点的CA证书和私钥。

管理Peer节点的组织的域名下类似。

2.6.2. CCP文件

createOrgs()函数还会调用ccp-generate.sh脚本,该脚本使用同目录下的两个模板文件ccp-template.json和ccp-template.yaml,分别为Org1和Org2生成CCP文件,即organisations/peerOrganisations/org1.example.com下的connection-org1.json和connection-org1.yaml,以及organisations/peerOrganisations/org2.example.com下的connection-org2.json和connection-org2.yaml。

这些CCP文件供APP使用,使得APP能够连接到测试网络中的Peer节点。注释掉这一部分内容不会对测试网络的启动、创建通道和部署链码产生影响。

举例来说,可以在项目fabric-samples/asset-transfer-basic/application-java的App.java文件中找到对connection-org1.yaml的使用。

在这里插入图片描述

注:部分APP(例如fabric-samples/asset-transfer-basic/application-gateway-java项目)同样无需这些CCP文件。

2.7. 使用peer CLI测试链码

在测试网络部署链码后,可以使用peer CLI从Fabric网络内部来测试已部署的智能合约。peer CLI是网络启动时加入网络的一个容器,作为网络的维护节点。

首先设置环境变量:

export PATH=$PATH:${PWD}/../bin
export FABRIC_CFG_PATH=${PWD}/../config/

作为Org1操作peer CLI:

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":[]}'

查询账本:

peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'

修改账本:

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":"TransferAsset","Args":["asset6","Christopher"]}'

设置环境变量,作为Org2操作peer CLI:

export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051

查询账本:

peer chaincode query -C mychannel -n basic -c '{"Args":["ReadAsset","asset6"]}'

三、运行示例应用

说明:示例应用演示了如何使用Fabric提供的API来从外部调用已部署的智能合约。尽管名为应用,但是它并不是一个严格意义上能够提供外部接入和人机交互的客户端。如果要开发一个完整的APP,还需要引入其它技术栈,比如SpringBoot。

asset-transfer-basic示例的Java版本应用demo的使用方法如下。

打开第一个终端,在test-network文件夹中启动网络,建立通道,部署asset-transfer-basic示例的链码:

./network.sh up -ca
./network.sh createChannel
./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-java -ccl java

完成后,打开第二个终端,进入asset-transfer-basic/application-gateway-java文件夹中,运行项目中的启动脚本:

./gradlew run

之后应用demo就会运行,并在当前终端中输出一些内容。
当想要结束时,在test-network文件夹下关闭网络即可:

./network.sh down

注意,这里启动网络时要使用CA标志,这是因为cryptogen工具和Fabric CA为测试网络生成的加密材料并不完全一样,而示例应用中使用的路径是基于Fabric CA的。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hyperledger Fabric 入门笔记(四)Fabric V2.4 测试网络基础 的相关文章

  • 【C++】_4.内存分布

    目录 1 C C 内存分布 2 C语言的动态内存管理方式 3 C 内存管理方式 3 1 new delete 操作内置类型 3 2 new delete 操作自定义类型 4 operator new 与operator delete函数 5
  • RuntimeError: cuda runtime error (30)解决

    程序出错如上 而且总是伴随着黑屏 一开始以为是cuda跑出问题 而且该问题必须重启才能解决 但是一直很好奇我的电脑Ubuntu18 04设置了黑白屏从不 还是出现该错误 最后为了复现该错误就强制锁屏 果然错误复现 找到原因之后就可以比较好解
  • vue前端使用Docker部署

    在上一篇文章中 我们介绍了如果在CentOS上安装docker环境 本文则是介绍docker的具体项目实践 主要介绍如果通过docker容器来部署vue前端项目 本文需要基于vue项目已经开发完成 并且docker环境已经准备好 思路是Do

随机推荐

  • SQL基础(1)

    1 Where条件语句 使用Were语句指定搜索条件过滤返回的数据 用于提取满足指定条件 语法 select b Sid b Sname a score from sc a join Student b on a Sid b Sid whe
  • ChatGPT和智能化能源:如何应用于能源领域的智能化生产和能源管理?

    Chatgpt Chat Gpt 小智Ai Chat小智 Gpt小智 ChatGPT小智Ai GPT小智 GPT小智Ai Chat小智Ai 丨 随着社会的发展和工业化的进程 能源需求不断增加 如何实现能源的高效 低碳 安全 可持续发展成为了
  • python数据分析绘图

    ROC AUC曲线 分类模型 混淆矩阵 混淆矩阵中所包含的信息 True negative TN 称为真阴率 表明实际是负样本预测成负样本的样本数 预测是负样本 预测对了 False positive FP 称为假阳率 表明实际是负样本预测
  • Qt:Drag-Drop操作在QGraphicsView及Model/View框架下的实现

    最近使用到Qt的Drag Drop功能 结合自己的例子写下来给大家分享一下 实现从QTreeView拖动Node到QGraphicsView上 以及QGraphicsView上item之间的拖动 先来说Model View中的实现 1 Mo
  • WPF的TChart控件使用---添加直线---标题勾选---提示

    TChart1 Aspect View3D false 控件3D效果 Steema TeeChart WPF Styles Line line1 new Steema TeeChart WPF Styles Line 直线 line1 Ti
  • 微信公众号 Jssdk调用错误码:63002, 获取access_token错误代码 errcode 40164的解决方法,如何解决,微信公众号的坑。

    今晚在开发公众号 需要调用到 Jssdk 结果配置好了 一运行就提示 Errmsg config fail Error 系统错误 错误码 63002 invalid signature 20200108 00 04 41 我的心突然就好慌
  • HTTPS理论基础

    目录 HTTPS原理 密码学基础 HTTPS通信过程 数字证书 本文链接 https blog csdn net iispring article details 51615631 HTTPS原理 我们知道 HTTP请求都是明文传输的 所谓
  • POSTGIS教程

    一 什么是PostgreSQL和PostGIS 1 1 什么是PostgreSQL 说起数据库 大家耳熟能详的商业数据库产品当推Oracle 微软的SqlServer和IBM的 DB2等 而开源数据库中则有两大产品MySQL和Postgre
  • 数据结构PTA 案例6-1.4 地下迷宫探索

    案例6 1 4 地下迷宫探索 题目 解法 题目 假设有一个地下通道迷宫 它的通道都是直的 而通道所有交叉点 包括通道的端点 上都有一盏灯和一个开关 请问你如何从某个起点开始在迷宫中点亮所有的灯并回到起点 输入格式 输入第一行给出三个正整数
  • Linux内核中断系统结构——软中断

    在 Linux异常 中断 处理体系结构 这篇文章 我们详细描写了内核如何进行中断 异常 向量表的初始化 如何初始化硬件中断 IRQ 的操作 在这篇文章中 我们将重心放在软件中断上 也就是 CPU 本身的中断 这篇文章包括五个内容 软中断 t
  • 当电桥为恒流源时惠斯通电桥电压的计算方法

    http wenku baidu com link url S55C CbY IQBl7oqgICODIz765KasqscVU2ACb6xV1OJB1zhLWwvryumayUWtB7V0b3 uHiclyhZtHHMfejUVFuYfd
  • 大数据毕设 - 校园卡数据分析与可视化(python 大数据)

    文章目录 0 前言 1 课题介绍 2 数据预处理 2 1 数据清洗 2 2 数据规约 3 模型建立和分析 3 1 不同专业 性别的学生与消费能力的关系 3 2 消费时间的特征分析 4 Web系统效果展示 5 最后 0 前言 Hi 大家好 这
  • python和opencv利用摄像头进行视频捕获

    python容易上手 利用opencv进行视频录制及后期的人脸识别 都是比较简单易上手的方案 工具 python3 10 opencv4 54 平台 win10 vscode 摄像头捕获程序 import cv2 as cv cap cv
  • Arduino从零开始(2)——控制舵机与步进电机

    0 前言 本文主要介绍通过Arduino控制舵机 步进电机以及循环的使用 目录 0 前言 1 介绍 2 Arduino控制舵机 2 1方法一 2 2方法二 3 Arduino控制步进电机 1 介绍 对于Arduino控制舵机的方法是通过其输
  • 做方差分析需要正态性检验吗_方差分析(SPSS版)

    方差分析 SPSS版 原创 Gently spss学习乐园 2019 10 15 文章同步于 微信公众号 SPSS学习乐园 方差分析 SPSS版 方差分析的基本思想 R A Fisher提出的统计理论基础 将总变异分解为由研究因素所产生的变
  • 计算机系统结构:流水线技术总结

    文章目录 什么是流水线 流水线的分类 流水线的性能指标 流水线设计中的若干问题 非线性流水线的调度 单功能非线性流水线的最优调度 多功能非线性流水线的调度 一条经典的5段流水线 相关与流水线冲突 结构冲突 因硬件资源满足不了指令重叠执行的要
  • 基于Pytorch实现LSTM(多层LSTM,双向LSTM)进行文本分类

    LSTM原理请看这 点击进入 LSTM nn LSTM input size hidden size num layers 1 nonlinearity tanh bias True batch first False dropout 0
  • Cesium加载Supermap的wmts服务

    最近使用cesium 加载supermap的wmts 服务 多次遇到加载异常与白页面问题 纠结好久最后才搞定 特此记录 1 首先找到方法加载wmts 的api 文档 官方提示使用WebMapTileServiceImageryProvide
  • nginx配置防止域名恶意解析

    前几发生一件事情 就是通过nginx日志发现有一个域名恶意指向到了我的服务器 大家可以去查查域名恶意解析可能会造成的危害 由于我是用的nginx配置了一个反向代理 所以直接配置nginx就可以实现域名恶意解析的问题了 首先打开我们的ngin
  • Hyperledger Fabric 入门笔记(四)Fabric V2.4 测试网络基础

    文章目录 前言 一 准备测试网络 1 1 概述 1 2 完成准备工作 1 2 1 运行install fabric sh脚本 1 2 2 文件夹去锁 可选 1 3 install fabric sh脚本运行结果 1 4 什么是二进制文件 1