Home > 感悟 > 基于以太坊私有链搭建一个分布式应用【1】

基于以太坊私有链搭建一个分布式应用【1】0+

5,073 views / 2018.03.15 / 9:09 下午

这几天不分白昼的看各种英文文档和stackoverflow,终于把区块链这套基本的框架和流程搞通了,感觉十分不容易,故做个分享。不过,如果你时间充裕,请直接阅读英文官方文档:http://www.ethdocs.org/en/latest/,不要看我们这些囫囵吞枣的内容。如果阅读有困难,可以从本文先找找感觉。

名词解释

Ethereum–以太坊,是一个开源的有智能合约功能的公共区块链平台

公有链、私有链、联盟链–公有链不解释;私有链是指其写入权限由某个组织和机构控制的区块链,参与节点的资格会被严格限制;联盟链是指有若干个机构共同参与管理的区块链,每个机构都运行着一个或多个节点,其中的数据只允许系统内不同的机构进行读写和发送交易,并且共同来记录交易数据。

Geth–对应软件包ethereum,又名Go Ethereum,是以太坊协议的三种实现之一,由Go语言开发,完全开源的项目。Geth 可以被安装在很多操作系统上,包括Windows、Linux、Mac的OSX、Android或者IOS系统

Solidity–对应软件包solc,是一种语法类似JavaScript的高级语言。它被设计成以编译的方式生成以太坊虚拟机代码。

gas— cost = gasPrice * gasUsed, gaslimit是由发起者设置的,gasPrice是双方博弈的。

truffle:合约编译、测试、发布框架工具

以太坊中的数据单位

* ether

* finney

* szabo

* wei

* 1 ether = 1 * 10^18 wei;

* 1 ether = 1 * 10^6 szabo;

* 1 ehter = 1* 10^3 finney;

程序在处理交易的时候用的单位都是wei

 

系统准备

两台同网段的linux云虚机,内存必须>=2G

系统建议使用最新的ubuntu版本,可以省却很多编译的麻烦。如果是centos>7.0。

本问采用两台ubuntu系统:

10.120.113.245—简称node1服务器

10.120.113.246—简称node2服务器

 

node1服务器搭建

 

安装geth:

sudo apt-get install software-properties-common

sudo add-apt-repository -y ppa:ethereum/ethereum

sudo add-apt-repository -y ppa:ethereum/ethereum-dev

sudo apt-get update

sudo apt-get install ethereum

安装solc编译器

sudo apt-get install solc

 

先创建3个账号,作为创世大神用的。以下代码运行三次。

appadmin@ubuntu:~$ geth account new

INFO [03-06|17:39:52] Maximum peer count                       ETH=25 LES=0 total=25

Your new account is locked with a password. Please give a password. Do not forget this password.

Passphrase:

Repeat passphrase:

Address: {e2b44335459830c43aaede94a6c748b40f5bfb26}

 

开始创造世界,先编辑个genesis.json文件:

{

“nonce”: “0x0000000000000042”, //Number once

“difficulty”: “0x1”,//挖矿的难度

“alloc”: {//给三个创世大神初始化钱

“f4182f0dc92313f8e106fc033641c3351703911f”: {

“balance”: “20000009800000000000000000000”

},

“899a969874bec249e4ef439c75adb0c358913b95”: {

“balance”: “20000009800000000000000000000”

},

“6797c39109ec4676d3b5dbb4dc76f1143a0f633a”: {

“balance”: “20000009800000000000000000000”

}

},

“config”: {

“chainId”: 12,//1-8不能用,详情https://ethereum.stackexchange.com/questions/17051/how-to-select-a-network-id-or-is-there-a-list-of-network-ids

“homesteadBlock”: 0,

“eip155Block”: 0,

“eip158Block”: 0

},

“mixhash”: “0x0000000000000000000000000000000000000000000000000000000000000000”, “coinbase”: “0x0000000000000000000000000000000000000000”,

 

“timestamp”: “0x00”,

 

“parentHash”: “0x0000000000000000000000000000000000000000000000000000000000000000”,

 

“extraData”: “0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa”,//传啥都行,但必须符合这格式

 

“gasLimit”: “0xb2d05e00”

}

好,把上面这个json文件放到eth目录中,执行如下代码:

geth –datadir “/home/appadmin/.ethereum” init eth/genesis.json

 

创建成功后,编写个启动脚本start.sh:

#!/bin/sh

geth –ipcdisable –rpc –rpcaddr “10.120.113.245” –port 30303 –rpcport 8101 –rpccorsdomain “*” –unlock ‘0,1,2’ –password ~/eth/password –networkid 12 –datadir ‘~/.ethereum’  console 2>>log

rpc是对外通信用的, ipc是内部通信用的,如果ipcdisable会无法在新的会话中attach到这个节点中,保证安全性(相反,可以geth attach新开一个控制台)

命令中会用password密码文件解锁以上三个账号,下文会解释为何要解锁。

保存,chmod +x start.sh 让其可执行

然后运行./start.sh其中控制台,稍后片刻就进入了。

 

查看节点下的创世大神们都有谁:

> eth.accounts

[“0xe2b44335459830c43aaede94a6c748b40f5bfb26”, “0x83817fa106fee9cfe149c9548e3656bffda90987”, “0x58a87b6080a226750f1e9e6d0f999ddfbc1bf914”]

 

开始挖矿钱,先看看矿机在谁的控制下:

eth.coinbase

可以通过这个命令设置所有者:

miner.setEtherbase(eth.accounts[2])

 

开始挖矿

> miner.start()

null

 

查看账户有多少钱了,上面说过,单位都是wei

> eth.getBalance('0xe2b44335459830c43aaede94a6c748b40f5bfb26')

2.0000019635e+28

> eth.getBalance('0x83817fa106fee9cfe149c9548e3656bffda90987')

2.00000098e+28

> eth.getBalance('0xbcf5b841303bc08026ce2d3b8f83498ffe42c12f')

0

 

可以使用eth.blockNumber查看一下区块高度是否增加。

> eth.blockNumber

1982

> eth.blockNumber

1985

> miner.stop()

true

> eth.blockNumber

1991

> eth.blockNumber

1991

> eth.blockNumber

1991

 

再创建个新账号:

> personal.newAccount()

Passphrase:

Repeat passphrase:

“0xdc23fc95dc3d452a210652be55195f5f743167ed”

> eth.accounts

[“0xe2b44335459830c43aaede94a6c748b40f5bfb26”, “0x83817fa106fee9cfe149c9548e3656bffda90987”, “0x58a87b6080a226750f1e9e6d0f999ddfbc1bf914”, “0xdc23fc95dc3d452a210652be55195f5f743167ed”]

 

> eth.getBalance(‘0xdc23fc95dc3d452a210652be55195f5f743167ed’)

0

 

执行转账命令,看看好不好使,结果发现报错:

> eth.sendTransaction({from: eth.accounts[3], to: eth.accounts[0], value: 120000000000000000000})

Error: authentication needed: password or unlock

at web3.js:3143:20

at web3.js:6347:15

at web3.js:5081:36

at <anonymous>:1:1

 

这个是以太坊的一个保护机制,每隔一段时间账户就会自动锁定,这个时候任何以太币在账户之间的转换都会被拒绝,除非把该账户解锁.

这个时候我们就需要执行 personal.unlockAccount(eth.accounts[3]) 并输入密码来解锁eth.accounts[3]才可。

>  personal.unlockAccount(eth.accounts[3])

Unlock account 0xdc23fc95dc3d452a210652be55195f5f743167ed

Passphrase:

true

> eth.sendTransaction({from: eth.accounts[3], to: eth.accounts[0], value: 120000000000000000000})

Error: insufficient funds for gas * price + value

at web3.js:3143:20

at web3.js:6347:15

at web3.js:5081:36

at <anonymous>:1:1

>  eth.gasPrice

18000000000

> eth.estimateGas({from: eth.accounts[2], to: eth.accounts[0], value: 120000000000000000000})

21000

由 于cost = gas * gasPrice , ( 账户3减少的资产 – 账户0增加的资产)/ gasPrice = 消耗的gas

 

> personal.unlockAccount(eth.accounts[2])

Unlock account 0xdc23fc95dc3d452a210652be55195f5f743167ed

Passphrase:

true

> eth.sendTransaction({from: eth.accounts[2], to: eth.accounts[0], value: 110000000000000000000})

“0xc27f031a26c80db62e959a00fe17325bed32820d6497076eedfd50fd51e5330a”

 

这时候可以看到矿池里面有未打包的交易,需要等矿工打包完成。

> txpool.status

{

pending: 1,

queued: 0

}

通过getTransation查看交易详情。

> eth.getTransaction(‘0xc27f031a26c80db62e959a00fe17325bed32820d6497076eedfd50fd51e5330a’)

{

blockHash: “0x0000000000000000000000000000000000000000000000000000000000000000”,

blockNumber: null,

from: “0x58a87b6080a226750f1e9e6d0f999ddfbc1bf914”,

gas: 90000,

gasPrice: 18000000000,

hash: “0xc27f031a26c80db62e959a00fe17325bed32820d6497076eedfd50fd51e5330a”,

input: “0x”,

nonce: 0,

r: “0x37114e0086c08a33cca996ba3a0ac3b263bf974e539f7a4c2136a2dca0bfe67a”,

s: “0x2b88f2a5abc23e8a21759589e4a7565fbfe61768e5b00b4e0b0056d4824087ca”,

to: “0xe2b44335459830c43aaede94a6c748b40f5bfb26”,

transactionIndex: 0,

v: “0x3b”,

value: 110000000000000000000

}

至此,node1节点搭建完成。下一章我们来看怎么编写和执行一个合约。

本站内容受著作权法保护。个人 blog 转载时请遵循 “署名-非商业用途-保持一致” 的创作共用协议;商业网站或未授权媒体不得复制本站内容。
Categories: 感悟 Tags:

Comments (0) Trackbacks (0) 本篇共有 0 篇评论↓
  1. No comments yet.
  1. No trackbacks yet.