【适合小白】搭建区块链网络

本文详细介绍了如何在Linux环境中搭建一条4节点的FISCOBCOS联盟链,包括检查系统依赖、使用build_chain.sh脚本、启动节点、检查进程和日志,以及配置和使用控制台来部署和调用智能合约。整个过程涵盖了从硬件和系统要求到区块链网络的基本运维和合约交互的步骤。
摘要由CSDN通过智能技术生成

一 搭建单群组FISCO BCOS联盟链

在进行以下所有操作前,请先检查自己虚拟机的硬件和系统要求。

硬性要求

  • FISCO BCOS支持x86_64和aarch64(ARM)架构的CPU

  • 由于节点多群组共享网络带宽、CPU和内存资源,因此为了保证服务的稳定性,一台机器上不推荐配置过多节点。

下表是单群组单节点推荐的配置,节点耗费资源与群组个数呈线性关系,您可根据实际的业务需求和机器资源,合理地配置节点数目。

我们可以使用开发部署工具 build_chain.sh去搭链,这个脚本依赖于openssl、curl

openssl 和 curl 都是常用的命令行工具,它们都可以用于加密、解密、传输数据等操作,但它们的作用和使用场景略有不同。 openssl 是一个强大的命令行工具,提供了丰富的加密和解密功能,可以用于生成密钥、加密数据、签名、验证签名、解密数据等操作。

openssl 可以用于生成 RSA、DSA、ECDSA 等多种密钥,并且支持多种加密算法和哈希算法。此外,openssl 还可以用于生成 X.509 证书、PKCS#12 证书等。使用 openssl 需要了解相关的加密知识和算法,否则不太容易上手。

curl 的作用是发送 HTTP 请求和接收 HTTP 响应,它也可以用于加密和解密数据,但它的加密功能比较简单,通常只用于基本的 HTTP 身份验证和 SSL/TLS 加密。curl 支持多种 HTTP 方法和协议,如 HTTP/1.0、HTTP/1.1、HTTP/2 等。此外,curl 还支持 FTP、FTPS、SMB、SMBS 等多种协议。使用 curl 可以方便地测试和调试 HTTP 请求和响应,也可以用于自动化脚本中。

总的来说,openssl 更适合加密和解密数据操作,需要更多的加密知识和算法知识,而 curl 更适合发送 HTTP 请求和接收 HTTP 响应操作,适合测试和调试 HTTP 请求和响应。

首先我们需要指定一个根目录,这里我指定的是fisco

检查是否安装openssl、java

fisco$ openssl version

若输出以下内容则表示openssl依赖存在
OpenSSL 1.1.1n  15 Mar 2022


若没有这个依赖则需要自己手动去下载

centos系统
sudo yum install -y openssl openssl-devel

  • sudo 表示以管理员权限运行命令(需要输入管理员密码);
  • yum 是 YUM 软件包管理器;
  • install 是安装命令;
  • -y 表示在安装时自动确认,即不要求用户输入确认;

ubuntu系统
sudo apt install -y openssl curl

  • sudo 表示以管理员权限运行命令(需要输入管理员密码);
  • apt 是 APT 软件包管理器;
  • install 是安装命令;
  • -y 表示在安装时自动确认,即不要求用户输入确认;

fisco$ java -version

若输出以下内容则表示jdk存在
java version "1.8.0_291"
Java(TM) SE Runtime Environment (build 1.8.0_291-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.291-b10, mixed mode)

搭建一条4节点的FISCO BCOS链

执行下面命令前,请确保build_chain.sh脚本在当前目录下、机器的30300~30303,20200~20203,8545~8548端口没有被占用。

fisco$ bash build_chain.sh -l 127.0.0.1:4 -p 30300,20200,8545

执行成功后会输出以下内容
Checking fisco-bcos binary...
Binary check passed.
==============================================================
Generating CA key...
==============================================================
Generating keys ...
Processing IP:127.0.0.1 Total:4 Agency:agency Groups:1
==============================================================
Generating configurations...
Processing IP:127.0.0.1 Total:4 Agency:agency Groups:1
==============================================================
[INFO] Execute the download_console.sh script in directory named by IP to get FISCO-BCOS console.
e.g.  bash /home/ubuntu/fisco/nodes/127.0.0.1/download_console.sh
==============================================================
[INFO] FISCO-BCOS Path   : bin/fisco-bcos
[INFO] Start Port        : 30300 20200 8545
[INFO] Server IP         : 127.0.0.1:4
[INFO] Output Dir        : /home/ubuntu/fisco/nodes
[INFO] CA Key Path       : /home/ubuntu/fisco/nodes/cert/ca.key
==============================================================
[INFO] All completed. Files in /home/ubuntu/fisco/nodes

如果没有build_chian.sh脚本则需要自己手动去下载

## 下载脚本
fisoc$ curl -#LO https://github.com/FISCO-BCOS/FISCO-BCOS/releases/download/v2.9.1/build_chain.sh && chmod u+x build_chain.sh

Bash:Shell解释器。build_chain.sh是一个Bash脚本,所以我们需要用到这个Shell去解释执行这个脚本

build_chain.sh: 是一个用于快速搭建 FISCO BCOS 联盟链的开发部署工具。使用该工具可以帮助用户快速生成一条链中节点的配置文件。

-l:指定IP地址(这里指定的是127.0.0.1)

“:4”:表示搭建四个节点

-p 30300,20200,8545:表示区块链节点的监听端口号,多个端口号之间用逗号分隔。在本例中,它指定了三个端口号,分别是 30300(链的监听端口号)、20200 (数据库的连接端口号)和 8545(WebSocket的监听端口号)。这些端口号是用于区块链节点之间的通信和交互的。在实际使用中,需要根据实际情况修改这些端口号。

节点搭完之后,会在当前的目录下生成一个nodes文件,我们需要进入到nodes/127.0.0.1/目录下输入下面命令去启动所有节点

fisco/nodes/127.0.0.1$ bash start_all.sh

启动成功会输出类似下面的内容
try to start node0
try to start node1
try to start node2
try to start node3
 node1 start successfully
 node2 start successfully
 node0 start successfully
 node3 start successfully

start_all.sh:启动所有节点的Bash脚本,它会遍历并启动同时有config.ini和start的脚本文件

检查进程是否启动

fisco/nodes/127.0.0.1$ ps -ef | grep -v grep | grep fisco-bcos

执行成功后会输出以下内容
fisco       5453     1  1 17:11 pts/0    00:00:02 /home/ubuntu/fisco/nodes/127.0.0.1/node0/../fisco-bcos -c config.ini
fisco       5459     1  1 17:11 pts/0    00:00:02 /home/ubuntu/fisco/nodes/127.0.0.1/node1/../fisco-bcos -c config.ini
fisco       5464     1  1 17:11 pts/0    00:00:02 /home/ubuntu/fisco/nodes/127.0.0.1/node2/../fisco-bcos -c config.ini
fisco       5476     1  1 17:11 pts/0    00:00:02 /home/ubuntu/fisco/nodes/127.0.0.1/node3/../fisco-bcos -c config.ini

ps -ef 是 Linux 系统中用于列出当前运行进程信息的命令。

| 是管道符,用于将前一个命令的输出作为后一个命令的输入。

grep -v grep 是过滤命令,用于去除包含 "grep" 关键字的行。

grep fisco-bcos 是关键字搜索命令,用于查找包含 "fisco-bcos" 关键字的行。

因此,整个命令 ps -ef | grep -v grep | grep fisco-bcos 将列出所有当前运行进程的信息,并去除包含 "grep" 关键字的行,然后仅显示包含 "fisco-bcos" 关键字的行。

检查日志输出

fisco/nodes/127.0.0.1$ tail -f nodes/127.0.0.1/node0/log/log* | grep connected

正常情况会不停地输出连接信息,从输出可以看出node0与另外3个节点有连接
info|2019-01-21 17:30:58.316769| [P2P][Service] heartBeat,connected count=3
info|2019-01-21 17:31:08.316922| [P2P][Service] heartBeat,connected count=3
info|2019-01-21 17:31:18.317105| [P2P][Service] heartBeat,connected count=3

tail -f:tail命令的选项,表示追踪文件并实时输出文件末尾的内容。

nodes/127.0.0.1/node0/log/log*:指定要追踪的文件路径和文件名,表示追踪该目录下以“log”结尾的所有文件。

|:管道符,用于将前一个命令的输出作为后一个命令的输入。

grep connected:表示过滤出包含“connected”字符串的行。

检查是否存在共识

fisco/nodes/127.0.0.1$ tail -f nodes/127.0.0.1/node0/log/log* | grep +++

正常情况会不停输出++++Generating seal,表示共识正常
info|2020-12-22 17:24:43.729402|[g:1][CONSENSUS][SEALER]++++++++++++++++ Generating seal on,blkNum=1,tx=0,nodeIdx=1,hash=2e133146...
info|2020-12-22 17:24:47.740603|[g:1][CONSENSUS][SEALER]++++++++++++++++ Generating seal on,blkNum=1,tx=0,nodeIdx=1,hash=eb199760...

在 FISCO BCOS 中,共识进程会不断地输出 "+++", 这表示进程正在运行并且能够与其他节点通信。因此,如果这个符号不停地输出,就表示共识进程正在正常运转并且能够与其他节点通信。这个符号通常被用来检查共识进程是否正常工作,以及是否能够与其他节点通信。需要注意的是,如果这个符号没有输出,可能表示共识进程没有正常工作,需要进一步排查问题。

二 配置及使用控制台

准备依赖

# ubuntu系统安装java
sudo apt install -y default-jdk

#centos系统安装java
sudo yum install -y java java-devel

获取控制台

fisco$ curl -LO https://github.com/FISCO-BCOS/console/releases/download/v2.9.2/download_console.sh && bash download_console.sh

下载完成后就可以对控制台压缩包进行解压
fisco$ tar -zxvf console.tar.gz

如果因为网络问题导致长时间无法下载,请尝试 curl -#LO https://gitee.com/FISCO-BCOS/console/raw/master-2.0/tools/download_console.sh && bash download_console.sh

拷贝控制台配置文件、证书

拷贝配置文件
fisco$ cp -n console/conf/config-example.toml console/conf/config.toml

拷贝sdk证书
fisoc$ cp -r nodes/127.0.0.1/sdk/* console/conf/

在Linux中,cp是一个命令行工具,用于复制文件和目录。而-n是一个选项,用于表示“不覆盖”。

具体地说,当使用cp命令复制文件时,如果目标文件已经存在,那么覆盖目标文件将是一个潜在的问题。通过使用-n选项,可以防止覆盖已经存在的目标文件,而是仅仅打印出一个错误消息,并提示用户是否需要覆盖。

-rcp命令的一个选项,用于递归地复制整个目录树。这意味着,它将复制指定的目录及其所有子目录和文件,包括所有文件和目录的权限、所有权、时间戳等。当使用cp -r选项时,它会自动处理目录和文件的复制,并且不会询问是否要覆盖已存在的文件。

启动控制台

fisco/console$ bash start.sh

输出下述信息表明启动成功 否则请检查conf/config.toml中节点端口配置是否正确

用控制台获取信息

# 获取客户端版本
[group:1]> getNodeVersion
ClientVersion{
    version='2.6.0',
    supportedVersion='2.6.0',
    chainId='1',
    buildTime='20200819 15:47:59',
    buildType='Darwin/appleclang/RelWithDebInfo',
    gitBranch='HEAD',
    gitCommitHash='e4a5ef2ef64d1943fccc4ebc61467a91779fb1c0'
}
# 获取节点信息
[group:1]> getPeers
[
    PeerInfo{
        nodeID='c1bd77e188cd0783256ee06838020f24a697f9af785438403d3620967a4a3612e3abc4bbe986d1e9dddf62d4236bff0b7d19a935a3cd44889f681409d5bf8692',
        ipAndPort='127.0.0.1:30302',
        agency='agency',
        topic=[

        ],
        node='node2'
    },
    PeerInfo{
        nodeID='7f27f5d67f104eacf689790f09313e4343e7887a1a7b79c31cd151be33c7c8dd57c895a66086c3c8e0b54d2fa493407e0d9646b2bd9fc29a94fd3663a5332e6a',
        ipAndPort='127.0.0.1:57266',
        agency='agency',
        topic=[
            _block_notify_1
        ],
        node='node1'
    },
    PeerInfo{
        nodeID='862f26d9681ed4c12681bf81a50d0b8c66dd5b6ee7b0b42a4af12bb37b1ad2442f7dcfe8dac4e737ce9fa46aa94d904e8c474659eabf575d6715995553245be5',
        ipAndPort='127.0.0.1:30303',
        agency='agency',
        topic=[

        ],
        node='node3'
    }
]
[group:1]>

部署及调用合约

为了方便用户快速体验,控制台console中给内置了一些简单的合约示例,我的根目录是fisco,所以我这里的路径是:fisco/console/contracts/solidity,我们把这里面的HelloWorld.sol作为本章的示例

HelloWorld的合约内容如下:

pragma solidity>=0.4.24 <0.6.11;

contract HelloWorld {
    string name;

    constructor() public {
        name = "Hello, World!";
    }

    function get() public view returns (string memory) {
        return name;
    }

    function set(string memory n) public {
        name = n;
    }
}

部署合约

# 在控制台输入以下指令 部署成功则返回合约地址
[group:1]> deploy HelloWorld
transaction hash: 0xd0305411e36d2ca9c1a4df93e761c820f0a464367b8feb9e3fa40b0f68eb23fa
contract address:0xb3c223fc0bf6646959f254ac4e4a7e355b50a344

调用合约

# 查看当前块高
[group:1]> getBlockNumber
1

# 调用get接口获取name变量 此处的合约地址是deploy指令返回的地址
[group:1]> call HelloWorld 0xb3c223fc0bf6646959f254ac4e4a7e355b50a344 get
---------------------------------------------------------------------------------------------
Return code: 0
description: transaction executed successfully
Return message: Success
---------------------------------------------------------------------------------------------
Return values:
[
    "Hello,World!"
]
---------------------------------------------------------------------------------------------

# 查看当前块高,块高不变,因为get接口不更改账本状态
[group:1]> getBlockNumber
1

# 调用set设置name
[group:1]> call HelloWorld 0xb3c223fc0bf6646959f254ac4e4a7e355b50a344 set "Hello, FISCO BCOS"
transaction hash: 0x7e742c44091e0d6e4e1df666d957d123116622ab90b718699ce50f54ed791f6e
---------------------------------------------------------------------------------------------
transaction status: 0x0
description: transaction executed successfully
---------------------------------------------------------------------------------------------
Output
Receipt message: Success
Return message: Success
---------------------------------------------------------------------------------------------
Event logs
Event: {}

# 再次查看当前块高,块高增加表示已出块,账本状态已更改
[group:1]> getBlockNumber
2

# 调用get接口获取name变量,检查设置是否生效
[group:1]> call HelloWorld 0xb3c223fc0bf6646959f254ac4e4a7e355b50a344 get
---------------------------------------------------------------------------------------------
Return code: 0
description: transaction executed successfully
Return message: Success
---------------------------------------------------------------------------------------------
Return values:
[
    "Hello,FISCO BCOS"
]
---------------------------------------------------------------------------------------------

# 退出控制台
[group:1]> quit
当然可以!下面是一个简单的Java程序示例,演示了如何实现基于DPoS共识算法的区块链搭建: ```java import java.util.ArrayList; import java.util.List; class Block { private int index; private long timestamp; private String previousHash; private String hash; private List<Transaction> transactions; public Block(int index, long timestamp, String previousHash, String hash, List<Transaction> transactions) { this.index = index; this.timestamp = timestamp; this.previousHash = previousHash; this.hash = hash; this.transactions = transactions; } // getters and setters @Override public String toString() { return "Block{" + "index=" + index + ", timestamp=" + timestamp + ", previousHash='" + previousHash + '\'' + ", hash='" + hash + '\'' + ", transactions=" + transactions + '}'; } } class Transaction { private String fromAddress; private String toAddress; private double amount; public Transaction(String fromAddress, String toAddress, double amount) { this.fromAddress = fromAddress; this.toAddress = toAddress; this.amount = amount; } // getters and setters @Override public String toString() { return "Transaction{" + "fromAddress='" + fromAddress + '\'' + ", toAddress='" + toAddress + '\'' + ", amount=" + amount + '}'; } } class Blockchain { private List<Block> chain; private List<Transaction> pendingTransactions; public Blockchain() { this.chain = new ArrayList<>(); this.pendingTransactions = new ArrayList<>(); // Genesis block createBlock("0"); } public void createBlock(String previousHash) { int index = chain.size(); long timestamp = System.currentTimeMillis(); String hash = calculateHash(index, timestamp, previousHash, pendingTransactions); Block block = new Block(index, timestamp, previousHash, hash, new ArrayList<>(pendingTransactions)); chain.add(block); pendingTransactions.clear(); } public void createTransaction(String fromAddress, String toAddress, double amount) { Transaction transaction = new Transaction(fromAddress, toAddress, amount); pendingTransactions.add(transaction); } private String calculateHash(int index, long timestamp, String previousHash, List<Transaction> transactions) { // 实现具体的哈希计算逻辑,例如使用SHA-256算法 // 在此省略实现细节,仅作示例 return "hash"; } // 更多的区块链验证和共识算法逻辑可以在这里实现 @Override public String toString() { return "Blockchain{" + "chain=" + chain + ", pendingTransactions=" + pendingTransactions + '}'; } } public class Main { public static void main(String[] args) { Blockchain blockchain = new Blockchain(); // 创建一些交易 blockchain.createTransaction("Alice", "Bob", 10.0); blockchain.createTransaction("Bob", "Charlie", 5.0); // 挖矿产生新的区块 blockchain.createBlock(blockchain.getChain().get(blockchain.getChain().size() - 1).getHash()); System.out.println(blockchain); } } ``` 这是一个简单的区块链实现示例,仅用于演示基本概念和数据结构。在实际的生产环境中,还需要考虑更多的安全性和性能优化方面的问题。希望这个示例可以帮助你入门区块链开发!如果有任何问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值