Ubuntu安装以太坊开发环境

Ubuntu安装以太坊开发环境

  • 摘要
  • 版本说明
  • 介绍
  • 开发环境的搭建
    • 搭建以太坊
    • 安装Nodejs
    • 安装Solidity
    • 安装Truffle
  • 示例程序的运行
    • 以太坊运行
    • Truffle框架的使用
      • Truffle命令使用
      • 测试Demo搭建
    • 又发现一个很好用的快速搭建私有区块链群的方法
  • 搭建一个私有链

摘要

以太坊已经发展了很多年了,和以太坊配套的开发环境版本很多,初次学习很容易出现版本不兼容的问题,很不适合新手,本文的主要内容就是介绍如何搭建一套完整的以太坊开发环境,节省开发者宝贵时间。

版本说明

Ubuntu版本:20.04
Ethereum版本:1.9.23
Nodejs版本:v10.19.0
Solidity版本:0.7.4
Truffle版本:v5.1.52

介绍

众所周知,以太坊(Ethereum)是一个分布式账本,在以太坊上记账的内容具备分布式、不可篡改、追溯等特性,这也是区块链之所以流行的主要原因。
以太坊构建了一个虚拟机EVM,在虚拟机中可以部署图灵完备的智能合约(Smart Contract),所谓图灵完备,就是在合约中可以执行加减乘除等逻辑运算,可以实现现有计算机编程语言的所有逻辑,智能合约执行的每一步骤都被记录在以太坊中,可以被追溯,所以智能合约的研究也非常火热。目前比较流行的智能合约编程语言叫做Solidity,编译器也叫Solidity,Solidity编译器将用户编写好的智能合约编译成二进制(类似于汇编语言),以太坊提供将二进制部署到虚拟机的接口,用户可以手动将编译后的二进制部署到以太坊上进行执行。
由于编译、部署、调用Solidity的工作比较重复,需要一种成熟的框架来帮助开发者节省时间,Truffle应运而生,官方介绍Truffle是一个世界级的开发环境,测试框架,以太坊的资源管理通道,致力于让以太坊上的开发变得简单。
那么接下来的内容就介绍如何快速搭建以上环境,从而快速进入开发阶段。Let’s Rock!

开发环境的搭建

接下来介绍以太坊、Solidity编译器、Truffle等开发环境的搭建方法。

搭建以太坊

sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum

使用如下命令查看Solidity版本

geth version

如下图所示,本实验的以太坊版本为1.9.23
Ubuntu安装以太坊开发环境_第1张图片

安装Nodejs

安装Nodejs命令如下:

sudo apt-get install -y nodejs

查看Nodejs版本命令如下:

nodejs -v

如下图所示,本实验的Nodejs版本为v10.19.0
在这里插入图片描述

安装Solidity

安装命令如下:

sudo apt-get install npm
sudo npm install solc

运行截图如下:
Ubuntu安装以太坊开发环境_第2张图片
查看Solidity版本命令如下:

solc --version

如下图所示,本实验的Solidity版本为0.7.4
在这里插入图片描述

安装Truffle

安装命令如下所示:

npm install -g truffle

Ubuntu安装以太坊开发环境_第3张图片
使用如下命令查看truffle版本:

truffle version

如下图所示,本实验的truffle 版本为v5.1.52
Ubuntu安装以太坊开发环境_第4张图片

示例程序的运行

以上开发环境搭建完成后,就可以编写代码进行开发了。下面的内容就介绍程序开发的步骤。

以太坊运行

  1. 搭建ethe私有链

创建私链需要定义创世块文件,这个文件用来创建区块链的创世区块。新建blockchain/consortium_blockchain文件夹
在文件夹下新建genesis.json文件

mkdir blockchain
cd blockchain
mkdir consortium_blockchain
cd consortium_blockchain
vim genesis.json

写入如下内容:

{
  "config": {
    "chainId": 8434,
    "homesteadBlock": 1,
    "eip150Block": 2,
    "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "eip155Block": 3,
    "eip158Block": 3,
    "byzantiumBlock": 4,
    "alien": {
      "period": 2,
      "epoch": 300,
      "maxSignersCount": 5,
      "minVoterBalance": 100000000000000000000,
      "genesisTimestamp": 1536136198,
      "signers": [
            "0x393faea80893ba357db03c03ee73ad3e31257469",
            "0x30d342865deef24ac6b3ec2f3f8dba5109351571",
            "0xd410f95ede1d2da66b1870ac671cc18b66a97778"
      ]
    }
  },
  "nonce": "0x0",
  "timestamp": "0x5b8f92c2",
  "extraData": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "gasLimit": "0x47b760",
  "difficulty": "0x1",
  "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "alloc": {
    "cbfc29c31a31c869f9eb59a084d9019965978a7e": {
      "balance": "0x31d450f18af132720000000"
    },
    "393faea80893ba357db03c03ee73ad3e31257469": {
      "balance": "0xd3c21bcecceda1000000"
    },
    "30d342865deef24ac6b3ec2f3f8dba5109351571": {
      "balance": "0xd3c21bcecceda1000000"
    },
    "d410f95ede1d2da66b1870ac671cc18b66a97778": {
      "balance": "0xd3c21bcecceda1000000"
    },
    "a25dc63609ea7ea999033e062f2ace42231c0b69": {
      "balance": "0xd3c21bcecceda1000000"
    }

  },
  "number": "0x0",
  "gasUsed": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
  1. 创建创世块

执行下面命令初始化创世块

geth --datadir "./myblockchain" init genesis.json 

执行结果如下:
Ubuntu安装以太坊开发环境_第5张图片
初始化结束后,当前目录会新建目录myblockchain,myblockchain目录下多了geth和keystore两个文件夹:
1) geth保存的该链上的区块数据
2)keystore保存该链上的用户信息
执行如下命令查看目录结构:

sudo apt  install tree
tree myblockchain

目录结构如下:
Ubuntu安装以太坊开发环境_第6张图片

  1. 启动私有链
    启动私链:
geth --identity "myethereum" --rpc --rpcaddr "127.0.0.1" --port 30304 --rpcport "7545" --rpccorsdomain "*" --datadir ./myblockchain --rpcapi "db,eth,net,web3,admin,personal" --networkid 5777 console --allow-insecure-unlock

这里先介绍一下一些参数:

参数名 描述
identity 区块链的标识,用于标识目前网络的名字
init 指定创世块文件的位置,并创建创世块
datadir 当前区块链数据存放的位置
port 网络监听端口,默认30303
rpc 启动rpc通信
rpcapi 设置允许rpc的客户端,一般为db,eth,net,web3
rpccorsdomain 指定什么url能连接到你的节点执行rpc定制端任务,如果输入是“*”,则任何url都可以连接到你的rpc实例。
rpcaddr 连接rpc的地址,默认为localhost,为了方便访问建议使用本机IP地址
rpcport 连接rpc的端口,默认为8545
networkid 设置当前区块链的网络ID,用于区分不同的网络,是一个数字,公链为1;这个和创世块文件的chainid没有直接关联
console 启动命令行模式,可以再geth中执行命令

屏幕输出:

Ubuntu安装以太坊开发环境_第7张图片
4. 连接第二个geth终端
为了方便使用,经常要打开多个终端连接到同一个私链节点,可以采用如下命令,其中ipc就是启动私链是输出的“ipc endpoint opened”

cd blockchain/consortium_blockchain/myblockchain
geth attach geth.ipc

运行效果图如下所示:
Ubuntu安装以太坊开发环境_第8张图片
5. geth创建账号、启动挖矿、停止挖矿
在geth终端就可以执行启动挖矿、创建账户等操作,初始化后系统无账号,需要创建新账号,才能启动挖矿:

eth.accounts

Ubuntu安装以太坊开发环境_第9张图片
由于我事先新建了两个账户,所以上图显示两个账户的地址

新建账户:

personal.newAccount("12345678");

在这里插入图片描述
获取第一个账户的余额:

eth.getBalance(eth.accounts[0])

在这里插入图片描述
开始挖矿:

miner.start()

停止挖矿:

miner.stop()
  1. geth常用操作
    解锁账户
personal.unlockAccount(eth.accounts[0])

交易池状态:

txpool.status

区块总数:

eth.blockNumber

获取交易:

eth.getTransaction("0x5cff7cd36fe841a7eb35ba30f99c8851a4e57715e4b648aeb341c3c2619879cd");

获取第421个区块的信息:

eth.getBlock(421);

连接到其他节点:

admin.addPeer();

设置挖矿账户:

miner.setEtherbase(eth.coinbase)

转账交易,要先解锁账户:

eth.sendTransaction({
     from:"0xe76c73baf75a67dd9637ad2da33d13288d73ee16",to:"0x62232534fda9ffe0c5f32cf6d48568a861065fea",value:web3.toWei(100,"ether")})

Truffle框架的使用

Truffle命令使用

  1. 初始化项目
truffle init

初始化一个空项目,会生成三个文件夹 contracts(包含Migrations.sol,之后得将要部署的合约放在里面)、migrations(包含1_initial_migration.js,truffle migrate会执行该js)、test(空文件夹),以及两个js配置文件(一个win,一个mac/linux,与truffle部署网络相关)

  1. 开启truffle自带的一个以太坊环境
truffle develop

开启truffle自带的一个以太坊环境并创建10个账户,带有余额,console里面调用web3接口。web3.js是以太坊去中心化应用DApp必备的JavaScript库,提供了与Geth通信的JavaScript API(https://github.com/ethereum/wiki/wiki/javascript-API),使用JSON-RPC协议与Geth通信。以太坊只提供了JSON-RPC接口,而web.js是一个封装了JSON-RPC的API库(https://github.com/ethereum/wiki/wiki/json-rpc 直接调用不方便)
3. 编译合约

truffle compile
  1. 部署合约
truffle migrate

重复部署需要执行

truffle migrate --reset

测试Demo搭建

  1. 新建truffletest文件夹
mkdir truffletest
cd truffletest
  1. 项目初始化
truffle init

Ubuntu安装以太坊开发环境_第10张图片
该目录下自动生成下述文件:

Ubuntu安装以太坊开发环境_第11张图片

contracts/: 智能合约存放的目录,默认情况下已经帮你创建 Migrations.sol合约。
migrations/: 存放部署脚本
test/: 存放测试脚本
truffle-config.js: truffle的配置文件
3. 合约编译
demo的合约代码存储在contracts目录下,编译该合约代码的指令

truffle compile

编译成功的结果如下图:
Ubuntu安装以太坊开发环境_第12张图片
如合约改动,truffle compile仅对改动的合约进行编译,如需强制编译整体合约,可使用 truffle compile --compile-all
4. 测试代码编写
在contract目录下新建Greeter.sol合约文件,如下所示:

pragma solidity >=0.4.16 <0.8.0;

contract Greeter
{
     
    function helloWorld() public  returns (string memory) {
     
        return "111111Hello, World!";
    }

	function myhelloWorld() public  returns (string memory) {
     
                return "Hello, World!ss";
    }
}

修改migrations/1_initial_migration.js文件,如下所示:

const Migrations = artifacts.require("Migrations");
const Greeter = artifacts.require("Greeter");#新增代码

module.exports = function (deployer) {
     
  deployer.deploy(Migrations);
  deployer.deploy(Greeter);#新增代码
};

重新编译合约,如下所示:
Ubuntu安装以太坊开发环境_第13张图片
5. 部署合约
执行如下命令进行合约部署:

truffle migrate

如下图所示:
Ubuntu安装以太坊开发环境_第14张图片
需要解锁账户

personal.unlockAccount(eth.accounts[0])

再次部署,如下图:
Ubuntu安装以太坊开发环境_第15张图片
合约部署成功,在以太坊命令行可以看到一个合约正在队列中:
Ubuntu安装以太坊开发环境_第16张图片

miner.start()开始挖矿。
合约部署成功图如下所示:
Ubuntu安装以太坊开发环境_第17张图片
也有可能gas耗费完了,如下图:
Ubuntu安装以太坊开发环境_第18张图片
这是因为账户的以太坊不够,需要持续挖矿一段时间。

  1. 合约执行
    进入truffle命令行
truffle console

如下图:
在这里插入图片描述
执行如下命令:

> var contract;
undefined
> Greeter.deployed().then(function(instance){
     contract= instance;});
undefined
> contract.helloWorld()

Ubuntu安装以太坊开发环境_第19张图片
注意:如果虚拟机性能偏低,很容易出现gas消耗完毕,合约部署不成功的问题,解决方法是使用ganache-cli工具,具体方法如下:

  1. 命令行安装
    执行命令安装ganache-cli
sudo npm install -g ganache-cli

安装成功如下图:
Ubuntu安装以太坊开发环境_第20张图片
2. 运行ganache-cli
命令行执行

ganache-cli

如下图:
Ubuntu安装以太坊开发环境_第21张图片
Ubuntu安装以太坊开发环境_第22张图片
可以看到开了一个端口监听,端口号是8545.

  1. 修改truffletest工程配合文件,端口改为8545
    Ubuntu安装以太坊开发环境_第23张图片
  2. 运行命令部署合约
    执行命令
truffle migrate

Ubuntu安装以太坊开发环境_第24张图片
Ubuntu安装以太坊开发环境_第25张图片
5. 调用合约

ss@ubuntu:~/blockchain/truffletest$ truffle console
> var contract;
undefined
>  Greeter.deployed().then(function(instance){
     contract= instance;});
undefined
> contract.helloWorld()
> contract.helloWorld.call()

Ubuntu安装以太坊开发环境_第26张图片
成功!

注意:
当使用truffle test测试合约的时候,需要使用web3通信,需要安装web3,安装方法如下:

sudo npm install web3@^0.20.0

又发现一个很好用的快速搭建私有区块链群的方法

  1. 下载ganache软件
    官网地址是:https://www.trufflesuite.com/ganache
    软件下载地址是:https://github.com/trufflesuite/ganache/releases
    下载ganache-2.5.4-linux-x86_64.AppImage

双击打开
Ubuntu安装以太坊开发环境_第27张图片
点击quickstart或者new workspace
设置端口port和networkid,如下图:
Ubuntu安装以太坊开发环境_第28张图片
点击save workspace,如图:
Ubuntu安装以太坊开发环境_第29张图片
然后执行truffle工程里面的truffle-config.js文件,修改端口为对应的端口,例子中是9545.
就可以执行truffle migrate或者truffle console命令了,如下图:
Ubuntu安装以太坊开发环境_第30张图片
Ubuntu安装以太坊开发环境_第31张图片

也可以使用geth attach这个区块链,命令如下:

geth attach http://127.0.0.1:9545

如下图:

Ubuntu安装以太坊开发环境_第32张图片

搭建一个私有链

以上的以太坊只开了一个节点,还无法模拟多个节点的协作的目的,下面就介绍怎么搭建一个多节点的私有链。要在私有网络中建立多个node组成的集群,并互相发现,产生交易。
为了在本地网络运行多个以太坊节点的实例,必须确保一下几点:

  1. 每个实例都有独立的数据目录(–datadir)

  2. 每个实例运行都有独立的端口.(eth和rpc两者都是)(–port 和 --rpcprot)

  3. 在集群的情况下, 实例之间都必须要知道彼此.

  4. 唯一的ipc通信端点,或者禁用ipc.

  5. 启动第一个节点(指定端口),运行命令和结果如下:

admin.nodeInfo.enode

如下所示:
在这里插入图片描述
上面的命令以命令行的(console)的方式启动了节点, 所以我们可以通过继续输入下面的命令获取节点实例的enode url。
2. 新建另一个节点
再打开一个终端,初始化第二个节点:

geth --datadir "./myblockchain1" init genesis.json

如下:
Ubuntu安装以太坊开发环境_第33张图片
3. 启动第二个节点
执行如下命令:

geth --rpcaddr "127.0.0.1" --datadir ./myblockchain1 --rpcapi "db,eth,net,web3,admin,personal" --networkid 5777 --port 61911 --rpcport "7546" --bootnodes "enode://88017819fba64041dbff876e16c3dc4df96ef42ba194e2a7c127999501994da08db824a2a9200eca7d38d713a3a15ecc70ef9c3c30384b47688a42d943af14ac@127.0.0.1:30303?discport=52408" console

Ubuntu安装以太坊开发环境_第34张图片
上面的命令中,–bootndoes 是设置当前节点启动后,直接通过设置–bootndoes 的值来链接第一个节点, --bootnoedes 的值可以通过在第一个节的命令行中,输入:admin.nodeInfo.enode命令打印出来.
也可以不设置 --bootnodes, 直接启动,启动后进入命令行, 通过命令admin.addPeer(enodeUrlOfFirst Instance)把它作为一个peer添加进来.
为了确认链接成功,第二个节点输入:

admin.nodeInfo

如下:
Ubuntu安装以太坊开发环境_第35张图片
也可以输入如下命令连接另一个节点:

admin.addPeer("enode:公有链地址@IP地址:30303")

第一个节点输入:

net.peerCount
admin.peers

Ubuntu安装以太坊开发环境_第36张图片
从得到的结果可以看出,第一个节点有1个peer链接, 链接的node id为:
“88017819fba64041dbff876e16c3dc4df96ef42ba194e2a7c127999501994da08db824a2a9200eca7d38d713a3a15ecc70ef9c3c30384b47688a42d943af14ac”
这个id,正好就是第二个节点的id.
按照这样的方式继续扩展,可以非常容易就可以建立本地节点集群.这些工作都可以写成脚本代码来完成, 里面还可以包含创建账户,挖矿等…
请参考:https://github.com/ethersphere/eth-utils下的gethcluster.sh脚本,以及README中的使用方法和示例.
链接成功后,使用我们在上一篇文章中挖矿的账户,向第二个节点发送 “ether”(以太币的货币单位,还有一种叫"Wei",基本上这些货币单位都是用一些牛逼的人的名字来命名的).
首先查看第二个节点的Wei数量和整个网络的区块号,还有接收货币的账号id:

> eth.getBalance(eth.accounts[0])
138000000000000000000
> eth.blockNumber
44
>  eth.accounts[0]
"0xde6dbf1967bf7a848f22862f1343a720647fc3fa"
> 

在第一个节点命令行中,执行下面的操作:

> personal.unlockAccount(eth.accounts[0], "password")
true
> eth.sendTransaction({
     from: "0xde6dbf1967bf7a848f22862f1343a720647fc3fa", to: "0x3d9c81058d17ba699568241649912c60d7083f9d", value: web3.toWei(1, "ether")})
"0x7222e34a5d7ff6fe4f932a5703b66fa42d34b3b4825d0d16993dfe8bc3eef220"
> 

eth.sendTransaction就是执行发送以太币的操作, 参数from, to分别是发送账户和接收账户, web3.toWei(1, “ether”)是将1单位"ether"转换为相应的"Wei"数量.
然后执行挖矿(这里我也不理解,为什么发送货币以后,要通过挖矿才能让交易生效)。

你可能感兴趣的:(区块链)