区块链研究(一):Windows下搭建以太坊私有链,部署智能合约实现数据上链功能(完整跑通版!好累!)

先说一下,之前学习部署以太坊私有链,看了好多博文,发现节点之前总是无法连接识别,踩了好多坑,,,今天我把自己完整跑通的实验流程给大家展示出来,希望有所帮助!

摘要:本文主要介绍区块链网络构建的方式,区块链网络仅用于实验,主要搭建以太坊私有链,在实验阶段,由于在公链做实验需消耗货币,因此本节仅在本地搭建多节点的私有链进行实验。由于智能合约是在以太坊虚拟机上运行的,因此后期可以根据业务需求很方便的转移到公有链或者其他联盟链等。

 开发工具如下:

Remix

智能合约代码开发的集成环境

Geth

以太坊客户端

web3j SDK

以太坊java开发包

Node.js

JavaScript运行环境

(1)部署geth客户端

为了方便在本地主机实验,本文基于windows系统安装软件和部署实验环境。下载geth-windows-amd64-1.8.3-329ac18e.exe进行安装geth客户端。图5-1为geth安装进度。

图5-1 Geth安装进度

输入geth version查看geth版本信息,如果控制台打印信息如图5-2所示,则表示Geth客户端安装成功。

图5-2查看Geth版本信息

(2)搭建以太坊私有链

安装完成Geth之后,接下来需要基于Geth搭建多节点的以太坊私有链,以及生成创世区块。首先需要定义区块链的创世状态,以太坊允许开发者可以自己定义创世区块。具体的定义数据存在文件中,创建一个名为genesis.json的文件,其文件内容如下所示:

{

    "config": {

        "chainId": 1995,

        "homesteadBlock": 0,

        "eip155Block": 0,

        "eip158Block": 0

    },

    "alloc": { },

    "nonce": "0x74657374",

    "difficulty": "0x020000",

    "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",

    "coinbase": "0x0000000000000000000000000000000000000000",

    "timestamp": "0x00",

    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",

    "extraData": "0x51AC67A34EA754C16EAF6E906D4B8BD5",

    "gasLimit": "0xffffff"

}

其中,chainId是一个用来区分不同 EVM 链的一个标识,以此来保持区块链网络的独立性,不同chainId的以太坊节点是无法链接的。alloc表示可以用于预置账户以及以太币的数量,difficulty表示挖矿难度,coinbase表示挖矿的矿工账号,gasLimit用于对gas的消耗总量的限制,在本文以太坊私有链中可以将gasLimit定义为最大值。

定义创世块的文件准备完毕,通过genesis.json来进行区块链初始化。本文搭建的以太坊私有链网络包含3个节点,以下均简称节点A、节点B和节点C,每个节点需要有自己专门的数据区,分别建立data_init001、data_init002、data_init003三个节点的文件夹。在私有链搭建中,要求生成创世区块时采用统一的配置文件。分别对三个节点执行初始化命令。在genesis.json文件路径下执行以下命令。其他节点修改datadir的路径即可。

geth --datadir "D://winterJujubeBlockchain/data_init001/" init genesis.json

节点在初始化完成之后,会在各自的文件夹下生成geth和keystore两个文件夹,其中geth主要存放区块链数据以及节点的日志,keystore主要存储加密过的私钥文件。如图5-3所示的执行结果即表示以太坊节点初始化成功。

节点在初始化完成之后,会在各自的文件夹下生成geth和keystore两个文件夹,其中geth主要存放区块链数据以及节点的日志,keystore主要存储加密过的私钥文件。如图5-3所示的执行结果即表示以太坊节点初始化成功。

图5-3以太坊节点初始化成功

各节点初始化完成之后,需要启动三个以太坊节点。需要注意的是,启动节点需分别在三个独立的终端对三个节点执行启动命令。以下为节点A的启动命令,其他节点启动命令类似,仅需修改各自节点的port、rpcport和identity即可。

geth --datadir "D://winterJujubeBlockchain/data_init001/" --networkid 1995 --identity "node001" --port 30303 --rpc --rpcport 8545 --rpcapi "db,eth,eth,net,web3,admin" --rpcaddr "0.0.0.0" --rpccorsdomain "*" --nodiscover  --ipcdisable --verbosity 3 console

其中networkid表示当前区块链网络ID,要求必须与chainId一致,且三个节点的启动networkid要保持一致。identity为节点标识,port表示节点端口,默认设置为30303,rpcport表示rpc 服务端口,默认设置为8545。nodiscover属性表示可以使得geth不去寻找其他节点,可以严格控制以太坊私有链接入的节点。verbosity参数此处设置为3,表示终端的日志级别为info。rpcapi指定需要调用的HTTP-RPC API接口。rpccorsdomain指定一个可以接收请求来源的,且以逗号间隔的域名列表。以太坊节点A启动成功如图5-4所示。

图5-4以太坊节点A启动成功

构建多节点的以太坊私有链,需要将每个节点连接起来组成分布式区块链网络。使用admin.nodeInfo命令来查看各节点信息,图5-5为节点A的信息,其中属性enode为节点A的独有的标识信息。在进行节点连接之前应检查每个节点的RPC端口是否开放、网络是否畅通等情况。在各节点的终端输入admin.peers查看各自的结果为空,说明各节点都没有发现其他节点。在网络环境良好的情况下,首先将节点A和节点C的enode信息查出,在节点B的终端输入admin.addPeer(节点A的enode)和admin.addPeer(节点C的enode),结果返回true。输入admin.peers查看节点B的连接情况,如图5-6所示,节点A和节点C分别与节点B连通。

图5-5以太坊节点A的节点信息

图5-6节点A和节点C分别与节点B连通

接下来在节点A的终端命令行输入admin.addPeer(节点C的enode),结果返回true。输入admin.peers查看节点A的连接情况,如图5-7所示,此时节点A与和节点B、C互相链接成功。此时3个节点互相连接组成了以太坊区块链网络,至此包含3个节点的私有链搭建完成。

图5-7节点A与和节点B、C互相链接成功

(3)准备以太坊账户

私有链搭建完毕之后需要准备以太坊账户,在节点A的终端输入personal.newAccount("密码"),创建一个以太坊账户,返回一个账户地址“0x71b2fa08a3515b979e57aadd492f37fb693fd573”。执行personal.unlockAccount("账户地址")来解锁账户。将该账户设定为区块链矿工,输入miner.start(挖矿线程数量)启动挖矿,私有链挖矿速度较快可以迅速积累以太币,后续基于此账户进行智能合约部署以及合约函数调用等活动。图5-8为节点A开启挖矿功能。

图5-8节点A开启挖矿功能

区块链网络互通之后,其他节点会同步节点A所产生的区块,在每个节点的命令行输入eth.blockNumber命令查看,发现3个节点的区块数量一致,说明区块同步状态良好。

图5-9 3个节点的区块数量检查

 (4)部署智能合约

如图5-10所示,可以查看编译详情,内容包括智能合约名称、Bytecode和ABI等信息。Bytecode是Solidity 是合约代码被翻译以后的信息,它包括了二进制的计算机指令。Bytecode 通常是将数字、常量和其他信息以一种编码方式写在一起,每一个指令都是一个被称为opcode 的操作,这些 opcode 的大小都是 1 比特(8 位)。在以太坊平台中,被部署在区块链上的合约就是 Bytecode,它在用户与智能合约交互的时候会被执行。ABI定义了智能合约中可以进行交互的方法和变量。因为智能合约在部署到区块链之前被转变为 Bytecode,因此合约使用者需要了解有哪些可以使用的操作。ABI作为一个标准来展示方法接口,这样可以使得别的编程语言也可以与智能合约交互。

图5-10智能合约编译详情

智能合约编译成功之后,接下来对合约进行部署到搭建的以太坊私有链。首先启动所有以太坊节点,指定以太坊账户进行挖矿,确保区块链网络运行良好。如图5-11所示,在remix中的部署环境选择External Http Provider进行连接。输入http://127.0.0.1:8545连接到本地私有链环境。

图5-11 Remix采用External Http Provider进行私有链连接。

在account中列出了已经存在私有链中的账户,选择上一小节提前创建好的以太坊账户“0x71b2fa08a3515b979e57aadd492f37fb693fd573”,设置GAS LIMIT的值,选择要部署的智能合约。点击部署按钮,等待区块链网络的响应结果。如图5-12所示,JujubeTrace合约部署成功。可以看到私有链返回已创建的合约账户地址为"0x95D8f67A31DfA098d5e3d1115D0E5343223102Ba",返回的信息还包括交易hash、交易所消耗的gas等。此时,我们查看区块链的控制台日志,如图5-13所示,智能合约的部署交易已经被节点A的矿工成功挖到并生成区块保存在私有链。

图5-12智能合约部署成功

图5-13 智能合约部署的交易成功

好了,到这里整个私有链以及智能合约被部署了,我这里给出一个简单的智能合约demo,感兴趣的同学可以尝试一下部署,按照上面的步骤。

下面是一个智能合约demo:

pragma solidity ^0.4.24;

contract JujubeTrace{

    string imageEncryptionDigest; 

    string winterJujubeTraceabilityInformation; 

function JujubeTrace()payable {}

function saveInformation(string imgParameter,string jujubeParameter) public{

        require(

         bytes(imgParameter).length > 0,

         "The image encryption summary information is empty."

        );

        require(

         bytes(jujubeParameter).length > 0,

         "The traceability information of winter jujube is empty."

        );

        imageEncryptionDigest = imgParameter;

        winterJujubeTraceabilityInformation = jujubeParameter;

}

    function queryInformation() public constant returns(string,string){

        return (imageEncryptionDigest, winterJujubeTraceabilityInformation);

    }

}

好了,每天学一点,快乐一点点。。。。。

如果有问题可以私信我,欢迎同学们交流!!!

猜你喜欢

转载自blog.csdn.net/myTomorrow_better/article/details/137157572