搭建自己的以太坊区块链

一、基本概念

以太坊简单来说就是区块链与智能合约的结合,是基于solidity语言实现的。在以太坊中,智能合约也有一个帐户地址。

1.1、 EVM

  以太坊虚拟机(EVM)是以太坊中智能合约的运行环境。它不仅被沙箱封装起来,事实上它被完全隔离,运行在EVM内部的代码不能接触到网络、文件系统或者其它进程。甚至智能合约之间也只有有限的调用。

  以太坊支持两种智能合约的编程语言:Solidity 和 Serpent。Serpent 语言面临一些安全问题,现在已经不推荐使用了。Solidity 语法类似 JavaScript,它编译器 solc 可以把智能合约源码编译成以太坊虚拟机 EVM 可以执行的二进制码。
现在以太坊提供更方便的在线 IDE —— Remix https://remix.ethereum.org 使用 Remix,免去了安装 solc 和编译过程,它可以直接提供部署合约所需的二进制码和 ABI。

1.2、 Accounts

  以太坊中有两类账户,它们共用同一个地址空间。外部账户,该类账户被公钥-私钥对控制。合约账户,该类账户被存储在账户中的代码控制。 外部账户的地址是由公钥决定的,合约账户的地址是在创建合约时确定的

  每个账户都有一个以太币余额(单位是“Wei”),该账户余额可以通过向它发送带有以太币的交易来改变。

1.3、 Transactions

  每一笔交易都是一条信息,可以通过交易,将余额从一个帐户发至另一个帐户。

1.4、 Gas

  每一笔交易需要支付一定的gas。gas price是由创建者设置的,调用合约的发送账户需要交易费用 = gas price * gas amount。

1.5、 以太坊客户端

  以太坊客户端用于接入以太坊网络,进行账户管理、交易、挖矿、智能合约相关的操作。目前有多种语言实现的客户端,常用的有 Go 语言实现的 go-ethereum 客户端 Geth,支持接入以太坊网络并成为一个完整节点,也可作为一个 HTTP-RPC 服务器对外提供 JSON-RPC 接口。
  

二、搭建go-ethereum

两种安装方式:

  • ppa安装
  • 源码编译

2.1、ppa安装

2.2、源码编译

编译安装时 make geth 过程中可能会报错,可以通过下面方案进行修复

三、安装 Solidity 编译器

Solidity 编译器也有多种方法安装,参照 http://solidity.readthedocs.io/en/latest/installing-solidity.html 这里介绍最简单快捷的安装方式:PPA 直接安装。

3.1、ppa安装

四、搭建以太坊

4.1、创世区块

要运行以太坊私有链,需要定义自己的创世区块,创世区块信息写在一个 JSON 格式的配置文件中。首先将下面的内容保存到一个 JSON 文件中,例如 genesis.json

配置简单说明:

chainId指定了独立的区块链网络 ID。网络 ID 在连接到其他节点的时候会用到,以太坊公网的网络 ID 是 1,为了不与公有链网络冲突,运行私有链节点的时候要指定自己的网络 ID。不同 ID 网络的节点无法相互连接。

difficulty挖矿难度。

gasLimit区块 Gas 消耗限制。

4.2、初始化创世区块

目录结构

其中 geth/chaindata 中存放的是区块数据,keystore 中存放的是账户数据。

4.3、 启动以太坊区块链,并进入控制台模式

上面命令的主体是 geth console,表示启动节点并进入交互式控制台。
各选项含义如下:

  • datadir:指定区块链数据的存储位置;
  • identity:指定节点 ID
  • rpc:表示开启 HTTP-RPC 服务;
  • rpcport:指定 HTTP-RPC 服务监听端口号(默认为 8545);
  • port:指定和其他节点连接所用的端口号(默认为 30303);
  • nodiscover:关闭节点发现机制,防止加入有同样初始配置的陌生节点。

geth console进入一个交互式的 JavaScript 执行环境,在这里面可以执行 JavaScript 代码,其中 > 是命令提示符。在这个环境里也内置了一些用来操作以太坊的 JavaScript 对象,可以直接使用这些对象。这些对象主要包括:

  • eth:包含一些跟操作区块链相关的方法;
  • net:包含一些查看p2p网络状态的方法;
  • admin:包含一些与管理节点相关的方法;
  • miner:包含启动&停止挖矿的一些方法;
  • personal:主要包含一些管理账户的方法;
  • txpool:包含一些查看交易内存池的方法;
  • web3:包含了以上对象,还包含一些单位换算的方法。
4.3.1、创建账户

1)直接输入密码创建账户

2)交互式创建账户

4.3.2、查看账户余额

4.3.3、挖矿

开始挖矿

其中 start 的参数表示挖矿使用的线程数。第一次启动挖矿会先生成挖矿所需的 DAG 文件,这个过程有点慢,等进度达到 100% 后,就会开始挖矿,此时屏幕会被挖矿信息刷屏。

停止挖矿

4.3.4、交易

第一个账户已经有余额了了。第二个账户没有币。

账户解锁,只有先对账户解锁才能转账。

进行交易

此时如果没有挖矿,用 txpool.status 命令可以看到本地交易池中有一个待确认的交易,可以使用 eth.getBlock("pending", true).transactions 查看当前待确认交易。

进行挖矿交易。

新区块挖出后,挖矿结束,查看账户 1 的余额,已经收到了账户 0 的以太币

4.3.5、 查看交易与区块

1) 查看总区块数

2) 查看交易

3)通过区块号查看区块:

五、以太坊区块链网络

我们通过单机的不同端口来模拟不同的网络。

首先需要使用相同的创世区块来初始化一个链出来。

然后在chian2中创建一个账户

使用2个终端分别打开着2个链

目前启动了三个节点,但都默认关闭了发现功能,需要手动添加peer节点。

在每个终端输入admin.nodeInfo.enode, 把输出记录下来到static-nodes.json文件,我这里情况如下:

两个终端退出后重启。输入admin.peers可以查看节点信息

开始挖矿

chain2 链启动后会出现警告同步数据失败,等待的一段时间后就可以了。

增加节点还是使用admin.addPeer来处理。

addPeer() 的参数就是节点二的 enode 信息,注意要把 enode 中的 [::] 替换成节点二的 IP 地址。连接成功后,节点二就会开始同步节点一的区块,同步完成后,任意一个节点开始挖矿,另一个节点会自动同步区块,向任意一个节点发送交易,另一个节点也会收到该笔交易。

通过 admin.peers 可以查看连接到的其他节点信息,通过 net.peerCount 可以查看已连接到的节点数量。

除了上面的方法,也可以在启动节点的时候指定 --bootnodes 选项连接到其他节点。

参考链接:

  • https://mshk.top/2017/11/go-ethereum-1-7-2/
  • https://g2ex.github.io/2017/09/12/ethereum-guidance/
  • https://github.com/xiaoping378/blog/blob/master/posts/%E4%BB%A5%E5%A4%AA%E5%9D%8A-%E7%A7%81%E6%9C%89%E9%93%BE%E6%90%AD%E5%BB%BA%E5%88%9D%E6%AD%A5%E5%AE%9E%E8%B7%B5.md