准备工作
安装git
输入以下命令安装Git:
sudo apt-get install git
安装solc
输入以下命令安装solc:
sudo npm install -g solc
root@i-colbyo7v:/home/ubuntu# npm install -g solc
/usr/local/node-v8.1.2-linux-x64/bin/solcjs -> /usr/local/node-v8.1.2-linux-x64/lib/node_modules/solc/solcjs
+ solc@0.4.13
added 65 packages in 59.744s
我们就会发现在终端中输入solc命令返回一个出错信息。这是因为solc只是一个程序集,如果我们想要在终端中使用solc程序编译智能合约,则需要安装solc-cli,这是solc的命令行界面。
输入以下命令安装solc-cli:
sudo npm install -g solc-cli
root@i-colbyo7v:/home/ubuntu# npm install -g solc-cli
/usr/local/node-v8.1.2-linux-x64/bin/solc -> /usr/local/node-v8.1.2-linux-x64/lib/node_modules/solc-cli/dist/index.js
npm WARN solc-cli@0.3.0 requires a peer of solc@^0.3.5 but none was installed.
+ solc-cli@0.3.0
added 20 packages in 18.604s
输入以下命令可以一并安装solc和solc-cli7(推荐使用此命令安装):
sudo npm install -g solc solc-cli --save-dev
如果输入solcjs --help命令,有以下输出,则表明solc和solc-cli安装成功:
zcc@ubuntu:~$ solcjs --help
Usage: solcjs [options] [input_file...]
Options:
--version Show version number [boolean]
--optimize Enable bytecode optimizer. [boolean]
--bin Binary of the contracts in hex. [boolean]
--abi ABI of the contracts. [boolean]
--interface Solidity Interface of the contracts. [boolean]
--output-dir, -o Output directory for the contracts. [string]
--help Show help [boolean]
到了这里,如果想以后的智能合约编译工作不使用geth控制台来完成,那么solc编译器就算安装完了。但是,如果我们需要在geth控制台使用solc编译器,那么我们仍然需要安装solc二进制包。输入以下命令安装solc二进制包8:
sudo add-apt-repository ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install solc
安装Geth客户端
有多种以太坊客户端,安装Go-ethereum输入以下命令13:
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum
ubuntu@i-5tthrr8u:~$ geth --help
NAME:
geth - the go-ethereum command line interface
Copyright 2013-2017 The go-ethereum Authors
USAGE:
geth [options] command [command options] [arguments...]
VERSION:
1.6.6-stable-10a45cb5
COMMANDS:
init Bootstrap and initialize a new genesis block
import Import a blockchain file
export Export blockchain into file
removedb Remove blockchain and state databases
dump Dump a specific block from storage
monitor Monitor and visualize node metrics
account Manage accounts
wallet Manage Ethereum presale wallets
console Start an interactive JavaScript environment
attach Start an interactive JavaScript environment (connect to node)
js Execute the specified JavaScript files
makedag Generate ethash DAG (for testing)
version Print version numbers
bug opens a window to report a bug on the geth repo
license Display license information
dumpconfig Show configuration values
help, h Shows a list of commands or help for one command
下面开始建立私有以太坊网络:
mkdir private-geth
cd private-geth
建立创世纪区块文件,是一个json格式的文件:
vim genesis.json
在创世纪区块的json文件中填入以下内容, 并保存.
{
"config": {
"chainId": 12345,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"coinbase" : "0x0000000000000000000000000000000000000000",
"difficulty" : "0x400",
"extraData" : "0x123456",
"gasLimit" : "0xffffffff",
"nonce" : "0x0000000000000042",
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00",
"alloc": { }
}
mixhash:与nonce配合用于挖矿,由上一个区块的一部分生成的hash。注意他和nonce的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。.
nonce: nonce就是一个64位随机数,用于挖矿,注意他和mixhash的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。
difficulty: 设置当前区块的难度,如果难度过大,cpu挖矿就很难,这里设置较小难度
alloc: 用来预置账号以及账号的以太币数量,因为私有链挖矿比较容易,所以我们不需要预置有币的账号,需要的时候自己创建即可以。
coinbase: 矿工的账号,随便填
timestamp: 设置创世块的时间戳
parentHash: 上一个区块的hash值,因为是创世块,所以这个值是0
extraData: 附加信息,随便填,可以填你的个性信息,必须为十六进制的偶位字符串
gasLimit: 该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总和,因为我们是私有链,所以填最大。
进入geth平台
root@i-5tthrr8u:/home/ubuntu/private-geth# geth --datadir ./data/00 init genesis.json
WARN [07-02|17:02:11] No etherbase set and no accounts found as default
INFO [07-02|17:02:11] Allocated cache and file handles database=/home/ubuntu/private-geth/data/00/geth/chaindata cache=16 handles=16
INFO [07-02|17:02:11] Writing custom genesis block
INFO [07-02|17:02:11] Successfully wrote genesis state database=chaindata hash=a0e580鈥5e82e
INFO [07-02|17:02:11] Allocated cache and file handles database=/home/ubuntu/private-geth/data/00/geth/lightchaindata cache=16 handles=16
INFO [07-02|17:02:11] Writing custom genesis block
INFO [07-02|17:02:11] Successfully wrote genesis state database=lightchaindata hash=a0e580鈥5e82e
root@i-5tthrr8u:/home/ubuntu/private-geth# geth --datadir ./data/00 --networkid 15 console
WARN [07-02|17:02:37] No etherbase set and no accounts found as default
INFO [07-02|17:02:37] Starting peer-to-peer node instance=Geth/v1.6.6-stable-10a45cb5/linux-amd64/go1.8.1
INFO [07-02|17:02:37] Allocated cache and file handles database=/home/ubuntu/private-geth/data/00/geth/chaindata cache=128 handles=1024
WARN [07-02|17:02:37] Upgrading chain database to use sequential keys
INFO [07-02|17:02:37] Initialised chain configuration config="{ChainID: 15 Homestead: 0 DAO: DAOSupport: false EIP150: EIP155: 0 EIP158: 0 Metropolis: Engine: unknown}"
INFO [07-02|17:02:37] Disk storage enabled for ethash caches dir=/home/ubuntu/private-geth/data/00/geth/ethash count=3
INFO [07-02|17:02:37] Disk storage enabled for ethash DAGs dir=/root/.ethash count=2
WARN [07-02|17:02:37] Upgrading db log bloom bins
INFO [07-02|17:02:37] Bloom-bin upgrade completed elapsed=185.399碌s
INFO [07-02|17:02:37] Initialising Ethereum protocol versions="[63 62]" network=15
INFO [07-02|17:02:37] Database conversion successful
INFO [07-02|17:02:37] Loaded most recent local header number=0 hash=a0e580鈥5e82e td=262144
INFO [07-02|17:02:37] Loaded most recent local full block number=0 hash=a0e580鈥5e82e td=262144
INFO [07-02|17:02:37] Loaded most recent local fast block number=0 hash=a0e580鈥5e82e td=262144
INFO [07-02|17:02:37] Starting P2P networking
INFO [07-02|17:02:39] UDP listener up self=enode://96f7a95a8c5e7a1f911142d87ce53ae882568be0435016e4803a6d410a9ecc7a69322cee8efbe8499ec7c737c377793182cab8869a076389c6b47626df00450b@[::]:30303
INFO [07-02|17:02:39] RLPx listener up self=enode://96f7a95a8c5e7a1f911142d87ce53ae882568be0435016e4803a6d410a9ecc7a69322cee8efbe8499ec7c737c377793182cab8869a076389c6b47626df00450b@[::]:30303
INFO [07-02|17:02:39] IPC endpoint opened: /home/ubuntu/private-geth/data/00/geth.ipc
**Welcome to the Geth JavaScript console!**
instance: Geth/v1.6.6-stable-10a45cb5/linux-amd64/go1.8.1
modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
geth --identity "haha" --datadir ./data/00 --networkid 12345 --rpcapi "db,eth,net,web3" --port 61910 --rpcport 8200 console
各参数说明如下:
identity :区块链的标示,随便填写,用于标示目前网络的名字
init :指定创世块文件的位置,并创建初始块
datadir :设置当前区块链网络数据存放的位置
port:网络监听端口,默认是8080
rpc:启动rpc通信,可以进行智能合约的部署和调试。它在geth中通常被默认激活。
rpcapi: 设置允许连接的rpc的客户端,一般为db,eth,net,web3
networkid: 设置当前区块链的网络ID,用于区分不同的网络,是一个数字
console:启动命令行模式,可以在Geth中执行命令
此外,还可以使用如下参数:
nodiscover : 使用这个命令可以确保你的节点不会被非手动添加你的人发现。否则,你的节点可能被陌生人的区块链无意添加,如果他和你有相同的初始文件和网络ID。
maxpeers : 如果你不希望其他人连接到你的测试链,可以使用maxpeers 0。反之,如果你确切知道希望多少人连接到你的节点,你也可以通过调整数字来实现。
rpcapi : 这个命令可以决定允许什么API通过RPC进入。在默认情况下,geth可以在RPC激活web3界面。请注意在RPC/IPC界面提供API,会使每个可以进入这个界面(例如dapp’s)的人都有权限访问这个API。注意你激活的是哪个API。Geth会默认激活IPC界面上所有的API,以及RPC界面上的db,eth,net和web3 API。
rpccorsdomain : 这个可以指示什么URL能连接到你的节点来执行RPC定制端任务。务必谨慎,输入一个特定的URL而不是wildcard ( * ),后者会使所有的URL都能连接到你的RPC实例。
创建新账户
> personal.newAccount()
Passphrase:
Repeat passphrase:
"0x28b769b3b9109afd1e9e50a9312c5a3bfae8a699"
> INFO [07-02|17:02:57] New wallet appeared url=keystore:///home/ubuntu/private鈥[32mstatus=Locked
开始挖矿,他会先自动更新一下
> miner.start()
INFO [07-02|17:03:22] Updated mining threads threads=0
INFO [07-02|17:03:22] Transaction pool price threshold updated price=18000000000
null
> INFO [07-02|17:03:22] Starting mining operation
INFO [07-02|17:03:22] Commit new mining work number=1 txs=0 uncles=0 elapsed=190.145碌s
INFO [07-02|17:03:27] Generating DAG in progress epoch=0 percentage=0 elapsed=3.072s
INFO [07-02|17:03:29] Generating DAG in progress epoch=0 percentage=1 elapsed=5.604s
INFO [07-02|17:03:32] Generating DAG in progress epoch=0 percentage=2 elapsed=8.263s
INFO [07-02|17:03:34] Generating DAG in progress epoch=0 percentage=3 elapsed=10.788s
INFO [07-02|17:03:37] Generating DAG in progress epoch=0 percentage=4 elapsed=13.659s
INFO [07-02|17:03:40] Generating DAG in progress ep
解锁
> personal.unlockAccount(eth.accounts[0])
Unlock account 0x28b769b3b9109afd1e9e50a9312c5a3bfae8a699
Passphrase:
true
发送交易,记住第一个账户的密码是123,第二个账户是123
>eth.sendTransaction({from:
"0x8260b02ac49855f9c00ff4275dc5291300517e30", to: "0xf7f54ba52d6226c1f3d4417cc0d700616474681d", gas:31000, 'gasPrice': web3.toWei(300, 'gwei'), "value": "1"})
INFO [07-02|17:12:56] Submitted transaction fullhash=0x7ce0faae69bc502936dbd0b27de5e1eae4b9cb40f9812f0571b6e970bce933a6 recipient=0xb4e2e2514eae3684157bf34a0cee2c07c431cf92
"0x7ce0faae69bc502936dbd0b27de5e1eae4b9cb40f9812f0571b6e970bce933a6"
矿池里面有未打包的交易
> txpool.status
{
pending: 1,
queued: 0
}
查看区块,它里面有打包的交易
> eth.getBlock(7)
{
difficulty: 239008,
extraData: "0xd783010606846765746887676f312e382e31856c696e7578",
gasLimit: 4265693055,
gasUsed: 21000,
hash: "0x14be6ad6bc92187b106bbb6b9b867f9b422895186052483623ea972b22849eaa",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x28b769b3b9109afd1e9e50a9312c5a3bfae8a699",
mixHash: "0x85df2a283fde403380b168f6dd985ea5a308c651c772fe2cf9e2a1276a59c03f",
nonce: "0x6ba641d5bc943a3c",
number: 7,
parentHash: "0x391702b4c862252af99f58b09001c8dae8de209678f2d57247fe1610ee5132d5",
receiptsRoot: "0xc570ba38565fc473b816fb9a3a1c4736b2b4155dea47ca35ee932c45d5922886",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 641,
stateRoot: "0xc488d58864a62b6711f19824cbb94af4ca1582da2909e235e3f269c4ca34d275",
timestamp: 1498987154,
totalDifficulty: 1984304,
transactions: ["0x7ce0faae69bc502936dbd0b27de5e1eae4b9cb40f9812f0571b6e970bce933a6"],
transactionsRoot: "0x3cecf9cf166ff0cdadedfc145f6d1e45b108d15a07dd85650eb38236e4662c23",
uncles: []
}
查看交易
> eth.getTransaction("0x7ce0faae69bc502936dbd0b27de5e1eae4b9cb40f9812f0571b6e970bce933a6")
{
blockHash: "0x14be6ad6bc92187b106bbb6b9b867f9b422895186052483623ea972b22849eaa",
blockNumber: 7,
from: "0x28b769b3b9109afd1e9e50a9312c5a3bfae8a699",
gas: 31000,
gasPrice: 300000000000,
hash: "0x7ce0faae69bc502936dbd0b27de5e1eae4b9cb40f9812f0571b6e970bce933a6",
input: "0x",
nonce: 0,
r: "0x5e30add8d6726e4b5f542d5e77b78f7d111abda861c432b09304dc6422f27663",
s: "0x10ef4e85481a9d507c8c07f4a8990f6b02abedab1c23dd838679f739b2b97ed4",
to: "0xb4e2e2514eae3684157bf34a0cee2c07c431cf92",
transactionIndex: 0,
v: "0x41",
value: 1
}
现在查看未打包的交易为0
> txpool.status
{
pending: 0,
queued: 0
}
let source = “pragma solidity ^0.4.0;contract Calc{ /区块链存储/ uint count; /执行会写入数据,所以需要transaction
的方式执行。/ function add(uint a, uint b) returns(uint){ count++; return a + b; } /执行不会写入数据,所以允许call
的方式执行。/ function getCount() returns (uint){ return count; }}”;