FISCO BCOS开发第一个区块链应用--小白实战

2023-11-01

官方链接

简单的步骤直接跳过了,主要是记录下整个过程中出现问题最多的地方

4. 创建区块链应用项目

第一步. 安装环境

首先,我们需要安装JDK以及集成开发环境

首先,在官网上下载JDK14(JDK1.8 至JDK 14都支持)并安装

然后,修改环境变量

视频讲解

文字步骤

# 确认您当前的java版本
$ java -version
# 确认您的java路径
$ ls /Library/Java/JavaVirtualMachines
# 返回
# jdk-14.0.2.jdk

# 如果使用的是bash
$ vim .bash_profile 
# 在文件中加入JAVA_HOME的路径
# export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-14.0.2.jdk/Contents/Home 
$ source .bash_profile

# 如果使用的是zash
$ vim .zashrc
# 在文件中加入JAVA_HOME的路径
# export JAVA_HOME = Library/Java/JavaVirtualMachines/jdk-14.0.2.jdk/Contents/Home 
$ source .zashrc

# 确认您的java版本
$ java -version
# 返回
# java version "14.0.2" 2020-07-14
# Java(TM) SE Runtime Environment (build 14.0.2+12-46)
# Java HotSpot(TM) 64-Bit Server VM (build 14.0.2+12-46, mixed mode, sharing)

进入IntelliJ IDE官网,下载并安装社区版IntelliJ IDE

(我把idea装ubantu里面了,虽然一开始有点卡,扩了2g内存就可以了。还是觉得这样比较方便简单一点。。毕竟师兄给我讲了一遍,我没听懂)

安装链接

安装完后要创建一个快捷方式,这样就不需要每次启动的时候去目录下执行

创建快捷方式链接

第二步. 创建一个Java工程

在IntelliJ IDE中创建一个gradle项目,勾选GradleJava,并输入工程名

 

 第三步. 引入FISCO BCOS Java SDK

 在build.gradle文件中的 dependencies下加入对FISCO BCOS Java SDK的引用。

repositories {
    mavenCentral()
    maven {
        allowInsecureProtocol = true
        url "http://maven.aliyun.com/nexus/content/groups/public/"
    }
    maven {
        allowInsecureProtocol = true
        url "https://oss.sonatype.org/content/repositories/snapshots" 
    }
}

引入Java SDK jar包

testImplementation group: 'junit', name: 'junit', version: '4.12'
implementation ('org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:2.9.0')

第四步. 配置SDK证书

修改build.gradle文件,引入Spring框架,

def spring_version = "4.3.27.RELEASE"
List spring = [
        "org.springframework:spring-core:$spring_version",
        "org.springframework:spring-beans:$spring_version",
        "org.springframework:spring-context:$spring_version",
        "org.springframework:spring-tx:$spring_version",
]

dependencies {
    testImplementation group: 'junit', name: 'junit', version: '4.12'
    implementation ("org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:2.9.0")
    implementation spring
}

 asset-app/test/resources目录下创建配置文件 applicationContext.xml,写入配置内容。

(官方图)

applicationContext.xml的内容如下:

<?xml version="1.0" encoding="UTF-8" ?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
    <bean id="defaultConfigProperty" class="org.fisco.bcos.sdk.config.model.ConfigProperty">
        <property name="cryptoMaterial">
            <map>
                <entry key="certPath" value="conf" />
            </map>
        </property>
        <property name="network">
            <map>
                <entry key="peers">
                    <list>
                        <value>127.0.0.1:20200</value>
                        <value>127.0.0.1:20201</value>
                    </list>
                </entry>
            </map>
        </property>
        <property name="account">
            <map>
                <entry key="keyStoreDir" value="account" />
                <entry key="accountAddress" value="" />
                <entry key="accountFileFormat" value="pem" />
                <entry key="password" value="" />
                <entry key="accountFilePath" value="" />
            </map>
        </property>
        <property name="threadPool">
            <map>
                <entry key="channelProcessorThreadSize" value="16" />
                <entry key="receiptProcessorThreadSize" value="16" />
                <entry key="maxBlockingQueueSize" value="102400" />
            </map>
        </property>
    </bean>

    <bean id="defaultConfigOption" class="org.fisco.bcos.sdk.config.ConfigOption">
        <constructor-arg name="configProperty">
            <ref bean="defaultConfigProperty"/>
        </constructor-arg>
    </bean>

    <bean id="bcosSDK" class="org.fisco.bcos.sdk.BcosSDK">
        <constructor-arg name="configOption">
            <ref bean="defaultConfigOption"/>
        </constructor-arg>
    </bean>
</beans>

 在以上配置文件中,我们指定了证书存放的位certPath的值为conf。接下来我们需要把SDK用于连接节点的证书放到指定的conf目录下。

# 假设我们将asset-app放在~/fisco目录下 进入~/fisco目录
$ cd ~/fisco
# 创建放置证书的文件夹
$ mkdir -p asset-app/src/test/resources/conf
# 拷贝节点证书到项目的资源目录
$ cp -r nodes/127.0.0.1/sdk/* asset-app/src/test/resources/conf
# 若在IDE直接运行,拷贝证书到resources路径
$ mkdir -p asset-app/src/main/resources/conf
$ cp -r nodes/127.0.0.1/sdk/* asset-app/src/main/resources/conf

这里注意!!!假设我们将 asset-app 放在~fisco目录下

一开始的默认地址并不是 fisco !!! 

5. 业务逻辑开发 

上面我们已经介绍了如何在自己的项目中引入以及配置Java SDK,本节介绍如何通过Java程序调用合约,同样以示例的资产管理说明。

第一步.将3编译好的Java合约引入项目中

cd ~/fisco  
# 将编译好的合约Java类引入项目中。
cp console/contracts/sdk/java/org/fisco/bcos/asset/contract/Asset.java asset-app/src/main/java/org/fisco/bcos/asset/contract/Asset.java

(官方图) 

 第二步.开发业务逻辑

在路径/src/main/java/org/fisco/bcos/asset/client目录下,创建AssetClient.java类,通过调用Asset.java实现对合约的部署与调用

 这里出现了一个小问题:client 是我自己新建的,但是当要创建AssetClient.java类的时候,提示 client是只读文件,使用了网上的方法也不管用,后面我想到这也是ubuntu里的文件呀,就去终端看了下,发现文件夹确实是带着小锁的。解决方法

AssetClient.java 代码如下:

package org.fisco.bcos.asset.client;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.List;
import java.util.Properties;
import org.fisco.bcos.asset.contract.Asset;
import org.fisco.bcos.sdk.BcosSDK;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple2;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

public class AssetClient {
    static Logger logger = LoggerFactory.getLogger(AssetClient.class);

    private BcosSDK bcosSDK;
    private Client client;
    private CryptoKeyPair cryptoKeyPair;

    public void initialize() throws Exception {
        @SuppressWarnings("resource")
        ApplicationContext context =
                new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        bcosSDK = context.getBean(BcosSDK.class);
        client = bcosSDK.getClient(1);
        cryptoKeyPair = client.getCryptoSuite().createKeyPair();
        client.getCryptoSuite().setCryptoKeyPair(cryptoKeyPair);
        logger.debug("create client for group1, account address is " + cryptoKeyPair.getAddress());
    }

    public void deployAssetAndRecordAddr() {

        try {
            Asset asset = Asset.deploy(client, cryptoKeyPair);
            System.out.println(
                    " deploy Asset success, contract address is " + asset.getContractAddress());

            recordAssetAddr(asset.getContractAddress());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            // e.printStackTrace();
            System.out.println(" deploy Asset contract failed, error message is  " + e.getMessage());
        }
    }

    public void recordAssetAddr(String address) throws FileNotFoundException, IOException {
        Properties prop = new Properties();
        prop.setProperty("address", address);
        final Resource contractResource = new ClassPathResource("contract.properties");
        FileOutputStream fileOutputStream = new FileOutputStream(contractResource.getFile());
        prop.store(fileOutputStream, "contract address");
    }

    public String loadAssetAddr() throws Exception {
        // load Asset contact address from contract.properties
        Properties prop = new Properties();
        final Resource contractResource = new ClassPathResource("contract.properties");
        prop.load(contractResource.getInputStream());

        String contractAddress = prop.getProperty("address");
        if (contractAddress == null || contractAddress.trim().equals("")) {
            throw new Exception(" load Asset contract address failed, please deploy it first. ");
        }
        logger.info(" load Asset address from contract.properties, address is {}", contractAddress);
        return contractAddress;
    }

    public void queryAssetAmount(String assetAccount) {
        try {
            String contractAddress = loadAssetAddr();
            Asset asset = Asset.load(contractAddress, client, cryptoKeyPair);
            Tuple2<BigInteger, BigInteger> result = asset.select(assetAccount);
            if (result.getValue1().compareTo(new BigInteger("0")) == 0) {
                System.out.printf(" asset account %s, value %s \n", assetAccount, result.getValue2());
            } else {
                System.out.printf(" %s asset account is not exist \n", assetAccount);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            // e.printStackTrace();
            logger.error(" queryAssetAmount exception, error message is {}", e.getMessage());

            System.out.printf(" query asset account failed, error message is %s\n", e.getMessage());
        }
    }

    public void registerAssetAccount(String assetAccount, BigInteger amount) {
        try {
            String contractAddress = loadAssetAddr();

            Asset asset = Asset.load(contractAddress, client, cryptoKeyPair);
            TransactionReceipt receipt = asset.register(assetAccount, amount);
            List<Asset.RegisterEventEventResponse> response = asset.getRegisterEventEvents(receipt);
            if (!response.isEmpty()) {
                if (response.get(0).ret.compareTo(new BigInteger("0")) == 0) {
                    System.out.printf(
                            " register asset account success => asset: %s, value: %s \n", assetAccount, amount);
                } else {
                    System.out.printf(
                            " register asset account failed, ret code is %s \n", response.get(0).ret.toString());
                }
            } else {
                System.out.println(" event log not found, maybe transaction not exec. ");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            // e.printStackTrace();

            logger.error(" registerAssetAccount exception, error message is {}", e.getMessage());
            System.out.printf(" register asset account failed, error message is %s\n", e.getMessage());
        }
    }

    public void transferAsset(String fromAssetAccount, String toAssetAccount, BigInteger amount) {
        try {
            String contractAddress = loadAssetAddr();
            Asset asset = Asset.load(contractAddress, client, cryptoKeyPair);
            TransactionReceipt receipt = asset.transfer(fromAssetAccount, toAssetAccount, amount);
            List<Asset.TransferEventEventResponse> response = asset.getTransferEventEvents(receipt);
            if (!response.isEmpty()) {
                if (response.get(0).ret.compareTo(new BigInteger("0")) == 0) {
                    System.out.printf(
                            " transfer success => from_asset: %s, to_asset: %s, amount: %s \n",
                            fromAssetAccount, toAssetAccount, amount);
                } else {
                    System.out.printf(
                            " transfer asset account failed, ret code is %s \n", response.get(0).ret.toString());
                }
            } else {
                System.out.println(" event log not found, maybe transaction not exec. ");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            // e.printStackTrace();

            logger.error(" registerAssetAccount exception, error message is {}", e.getMessage());
            System.out.printf(" register asset account failed, error message is %s\n", e.getMessage());
        }
    }

    public static void Usage() {
        System.out.println(" Usage:");
        System.out.println(
                "\t java -cp conf/:lib/*:apps/* org.fisco.bcos.asset.client.AssetClient deploy");
        System.out.println(
                "\t java -cp conf/:lib/*:apps/* org.fisco.bcos.asset.client.AssetClient query account");
        System.out.println(
                "\t java -cp conf/:lib/*:apps/* org.fisco.bcos.asset.client.AssetClient register account value");
        System.out.println(
                "\t java -cp conf/:lib/*:apps/* org.fisco.bcos.asset.client.AssetClient transfer from_account to_account amount");
        System.exit(0);
    }

    public static void main(String[] args) throws Exception {
        if (args.length < 1) {
            Usage();
        }

        AssetClient client = new AssetClient();
        client.initialize();

        switch (args[0]) {
            case "deploy":
                client.deployAssetAndRecordAddr();
                break;
            case "query":
                if (args.length < 2) {
                    Usage();
                }
                client.queryAssetAmount(args[1]);
                break;
            case "register":
                if (args.length < 3) {
                    Usage();
                }
                client.registerAssetAccount(args[1], new BigInteger(args[2]));
                break;
            case "transfer":
                if (args.length < 4) {
                    Usage();
                }
                client.transferAsset(args[1], args[2], new BigInteger(args[3]));
                break;
            default:
            {
                Usage();
            }
        }
        System.exit(0);
    }

}

在 asset-app/tool目录下添加一个调用AssetClient的脚本 asset_run.sh

#!/bin/bash 

function usage() 
{
    echo " Usage : "
    echo "   bash asset_run.sh deploy"
    echo "   bash asset_run.sh query    asset_account "
    echo "   bash asset_run.sh register asset_account asset_amount "
    echo "   bash asset_run.sh transfer from_asset_account to_asset_account amount "
    echo " "
    echo " "
    echo "examples : "
    echo "   bash asset_run.sh deploy "
    echo "   bash asset_run.sh register  Asset0  10000000 "
    echo "   bash asset_run.sh register  Asset1  10000000 "
    echo "   bash asset_run.sh transfer  Asset0  Asset1 11111 "
    echo "   bash asset_run.sh query Asset0"
    echo "   bash asset_run.sh query Asset1"
    exit 0
}

    case $1 in
    deploy)
            [ $# -lt 1 ] && { usage; }
            ;;
    register)
            [ $# -lt 3 ] && { usage; }
            ;;
    transfer)
            [ $# -lt 4 ] && { usage; }
            ;;
    query)
            [ $# -lt 2 ] && { usage; }
            ;;
    *)
        usage
            ;;
    esac

    java -Djdk.tls.namedGroups="secp256k1" -cp 'apps/*:conf/:lib/*' org.fisco.bcos.asset.client.AssetClient $@

接着,配置好 log。在asset-app/src/test/resources目录下创建log4j.properties

### set log levels ###
log4j.rootLogger=DEBUG, file

### output the log information to the file ###
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.DatePattern='_'yyyyMMddHH'.log'
log4j.appender.file.File=./log/sdk.log
log4j.appender.file.Append=true
log4j.appender.file.filter.traceFilter=org.apache.log4j.varia.LevelRangeFilter
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C{1}.%M(%L) | %m%n

###output the log information to the console ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C{1}.%M(%L) | %m%n

 接着,通过配置gradle中的Jar命令,指定复制和编译任务。并引入日志库,在asset-app/src/test/resources目录下,创建一个空的contract.properties文件,用于应用在运行时存放合约地址。

(官方图片)

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    compile ("org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:2.9.0")
    compile spring
    compile ('org.slf4j:slf4j-log4j12:1.7.25')
    runtime ('org.slf4j:slf4j-log4j12:1.7.25')
}
jar {
    destinationDir file('dist/apps')
    archiveName project.name + '.jar'
    exclude '**/*.xml'
    exclude '**/*.properties'
    exclude '**/*.crt'
    exclude '**/*.key'

    doLast {
        copy {
            from configurations.runtime
            into 'dist/lib'
        }
        copy {
            from file('src/test/resources/')
            into 'dist/conf'
        }
        copy {
            from file('tool/')
            into 'dist/'
        }
        copy {
            from file('src/test/resources/contract')
            into 'dist/contract'
        }
    }
}

 至此,我们已经完成了这个应用的开发。

6. 运行应用

至此我们已经介绍使用区块链开发资产管理应用的所有流程并实现了功能,接下来可以运行项目,测试功能是否正常。

1.编译

# 切换到项目目录
$ cd ~/fisco/asset-app
# 编译项目
$ ./gradlew build

注意上面的 切换到项目目录,自己的 asset-app 在哪 ,就切到哪

 编译成功之后,将在项目根目录下生成 dist目录。dist目录下有一个asset_run.sh脚本,简化项目运行。现在开始一一验证本文开始定下的需求。

2.部署Asset.sol合约

# 进入dist目录
$ cd dist
$ bash asset_run.sh deploy

这里我出现了一些警告,我看有人说是jdk版本过高,无伤大雅,以后再看吧

 3.注册资产

给张三注册资产10万元 

$ bash asset_run.sh register zhangsan 100000

 注册成功,张三拥有资产10万元

 同上,也给张五注册资产10万元

$ bash asset_run.sh register Bob 100000
Register account successfully => account: Bob, value: 100000

4.查询资产

查询张三的资产有多少

$ bash asset_run.sh query zhangsan

张三拥有10万资产

 张五同上。

5.资产转移

张三转给张五 5万 块

$ bash asset_run.sh transfer zhangsan zhangwu  50000

转移成功 

 检查张三还剩多少钱

$ bash asset_run.sh query zhangsan

张三还剩 5 万。 

 检查张五还有多少钱

$ bash asset_run.sh query zhangwu

张五有 15 万 

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

FISCO BCOS开发第一个区块链应用--小白实战 的相关文章

随机推荐

  • 【八组输入输出你都了解多少】

    目录 前言 一 总览 一 只能从标准流 std 中输入和输出数据 二 可以从所以流中读取和写入数据 三 只能从字符串中读取和写入数据 二 详细描述 一 scanf fscanf sscanf 1 scanf 2 fscanf 3 sscan
  • 震惊,docker操作竟如此简单

    Docker概述 1 什么是Docker Docker 是一个开源的应用容器引擎 让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中 然后发布到任何流行的Linux和Windows操作系统的机器上 也可以实现虚拟化 容器是完全使用沙箱
  • c#—OpenFileDialog(打开文件对话框)

    OpenFileDialog是什么 OpenFileDialog是一个类 实例化此类可以设置弹出一个文件对话框 比如 我们发邮件时需要上传附件的时候 就会弹出一个让我们选择文件的对话框 我们可以根据自己的需求 自行设置一些对话框的属性 那么
  • ASP.NET WebAPI 连接数据库

    ASP NET Web API 是一种框架 用于轻松构建可以访问多种客户端 包括浏览器和移动设备 的 HTTP 服务 ASP NET Web API 是一种用于在 NET Framework 上构建 RESTful 应用程序的理想平台 本文
  • window11中Jdk1.8下载,安装和环境配置(超详细)

    一 下载安装包 这里为了方便大家 提供百度网盘下载 链接 https pan baidu com s 1 Qz7pO226To7yy6ytdPR Q https pan baidu com s 1 Qz7pO226To7yy6ytdPR Q
  • Windows——进程间通信

    进程间通信 进程间通信的概念 Mailslots 关于Mailslots 命名规则 使用 创建 Mailslot 写入 Mailslot 读取Mailslot 管道 关于管道 匿名管道 匿名管道创建 命名管道 命名规则 访问模式 相关操作
  • Spring Boot 多数据源及事务解决方案

    一个主库和N个应用库的数据源 并且会同时操作主库和应用库的数据 需要解决以下两个问题 如何动态管理多个数据源以及切换 如何保证多数据源场景下的数据一致性 事务 本文主要探讨这两个问题的解决方案 希望能对读者有一定的启发 1 数据源切换原理
  • 关于Springboot 无法捕获异常(@Transactional注解导致)

    在工作中发现了一个非常奇怪的事情 就是我突然间捕获不了异常 异常捕获 关于为什么会出现这样的问题呢 经过研究发现 原来是在这个类上 被加上了事务的注解 Transactional 这个事务的注解 就把我的异常给处理掉了 所以在这个被事务注解
  • 使用IntelliJ IDEA创建基于Gradle的kotlin项目

    一 首先打开Idea 选择Create New Project 二 选择Gradle项目并勾选 三 填写项目信息 四 然后一路默认下去就可以了 五 最终创建好的项目如下 六 写个HelloWorld
  • STM32F103ZET6【标准库函数开发】------按键扫描和外部中断的优先级对比

    1 打开正点原子的库函数源码可以看到关于按键的程序有两个 一个是按键输入实验 一个是外部中断实验 从最后体现的效果来看 这两个似乎是一样的 那么如果按键输入和外部中断冲突了 那么哪个优先级比较高呢 今天就来试试 2 首先还是简单介绍 硬件用
  • 什么是数据流图 Data Flow Diagram (DFD)

    什么是数据流图 DFD 如何绘制DFD 一张图片胜过千言万语 数据流图 DFD 是系统内信息流的传统视觉表示 一个整齐而清晰的DFD可以用图形描绘出大量的系统需求 它可以是手动的 自动的或两者的组合 它显示了信息如何进入和离开系统 什么改变
  • Windows Server --- RDP远程桌面服务器激活和RD授权

    RDP远程桌面服务器激活和RD授权 一 激活服务器 二 设置RD授权 系统 Window server 2008 R2 服务 远程桌面服务 注 该方法适合该远程桌面服务器没网络状态下 离线 激活服务器 一 激活服务器 1 打开远程桌面授权管
  • 链表的运用:多项式加法

    通过链表来实现两个多项式的加法 1 创建节点类型 用链表储存多项式则链表的一个节点就代表多项式的某一项 所以一个节点应该包含多项式的系数 多项式的指数以及指向下个节点的指针 2 打印多项式 传入一个指向多项式链表的指针 遍历该链表 依次打印
  • 线性代数的本质——几何角度理解

    B站网课来自 3Blue1Brown的翻译版 看完醍醐灌顶 强烈推荐 线性代数的本质 本课程从几何的角度翻译了线代中各种核心的概念及性质 对做题和练习效果有实质性的提高 下面博主来总结一下自己的理解 1 向量的本质 在物理中的理解是一个有起
  • Qt下实现支持多线程的单例模式

    1 代码介绍 实现单例模式的代码很多 本文的单例模式实现代码是本人一直在工程项目中使用的 现拿出和大家交流分享 本文实现的单例模式 支持多线程 采用双重校验检索的方式 集成析构类 杜绝内存泄漏 稳定性好 使用C Qt的朋友们可以了解一下 不
  • 一、深入理解-Java集合初篇

    导读 本篇文章开始我们将要开始讲解Java集合 包括List Set Map等 也会对HashMap做深入的讲解 通过JDK1 7和JDK1 8两个版本的源码分析一步一步引导大家理解编程思想 同时还会就JDK1 7 JDK1 8两个版本的哈
  • [CentOS Python系列] 四.阿里云服务器CentOS连接远程MySQL数据库及pymsql

    从2014年开始 作者主要写了三个Python系列文章 分别是基础知识 网络爬虫和数据分析 Python基础知识系列 Pythonj基础知识学习与提升 Python网络爬虫系列 Python爬虫之Selenium Phantomjs Cas
  • Xgboost安装,常见错误解决办法

    Xgboost安装 本人在安装Xgboost时 查看了太多的教程 但因为太多的教程已经过时了 最后结合多个教程 overflow上的问题 对这些问题进行解决 此处为了感谢 特地贴出网址 另 本机环境 python3 64位 步骤 1 为了获
  • Spring Boot 日志组件logback实现日志分级打印

    准备工作 环境 1 windows 2 jdk 8 3 maven 3 0 4 IDEA 构建工程
  • FISCO BCOS开发第一个区块链应用--小白实战

    官方链接 简单的步骤直接跳过了 主要是记录下整个过程中出现问题最多的地方 4 创建区块链应用项目 第一步 安装环境 首先 我们需要安装JDK以及集成开发环境 首先 在官网上下载JDK14 JDK1 8 至JDK 14都支持 并安装 然后 修