区块链的相关知识后补,先从实际的上手,从实例中学习
知识点
分布式数据库并且只能插入和查找
任何人都可以成为节点,保存整个数据库,且数据同步
工作量产生价值,成为币
软件安装
brew tap ethereum/ethereum brew install ethereum
执行时间较长,需要耐心等待或者梯子
也可以编译安装,请自行百度
https://github.com/ethereum/go-ethereum
检查是否安装成功
geth -h
搭建私有链
需要给一个数据存储的文件夹,我们使用
cd ~ mkdir ethereum cd ethereum
初始化一个创世区块,新建文件
vi genesis.json
{ "nonce": "0x0000000000000042", "difficulty": "0x020000", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x0000000000000000000000000000000000000000", "timestamp": "0x00", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", "gasLimit": "0x4c4b40", "config": { "chainId": 15, "homesteadBlock": 0, "eip155Block": 0, "eip158Block": 0 }, "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 --datadir data init genesis.json
运行上面的命令,会读取genesis.json文件,根据其中的内容,将创世区块写入到区块链中。如果看到log信息中含有Successfully wrote genesis state字样,说明初始化成功。其中的数据信息等会保存在我们设置的data目录中。
启动私有链
初始化完成后,就可以通过输入以下命令启动私有链,并打开console了
geth –-datadir data console 2>> geth.log
指定数据目录是data,启动console,并且把console的输出重定向到geth.log文件
这样你可以另外启动一个控制台,使用命令查看console的输出
启动了区块链节点并进入了Javascript Console
这是一个交互式的Javascript执行环境,在这里面可以执行Javascript代码,其中>是命令提示符。在这个环境里也内置了一些用来操作以太坊的Javascript对象,可以直接使用这些对象。这些对象主要包括:
eth:包含一些跟操作区块链相关的方法 net:包含以下查看p2p网络状态的方法 admin:包含一些与管理节点相关的方法 miner:包含启动&停止挖矿的一些方法 personal:主要包含一些管理账户的方法 txpool:包含一些查看交易内存池的方法 web3:包含了以上对象,还包含一些单位换算的方法
基本玩法
查看&创建账户
>eth.accounts [ ]
目前还没有账户,下面开始创建,参数即是密钥
>personal.newAccount('password') "0x2b661b5b692de27578e6fb199b4ae2714ff24047"
查询余额
>eth.getBalance(eth.accounts[0]) 0
注意在console里也是可以用tab键自动补全的
启动&停止挖矿
miner.start(10)
其中参数表示挖矿使用的线程数。
第一次启动挖矿会先生成挖矿所需的DAG文件,这个过程有点慢,等进度达到100%后,就会开始挖矿,此时屏幕会被挖矿信息刷屏。
如果想停止挖矿,并且进度已经达到100%之后,可以在js console中输入
miner.stop()
挖到的区块会奖励币,是按wei的单位,wei是以太币的最小单位,1个以太币=10的18次方个wei。要查看有多少个以太币,可以用web3.fromWei()将返回值换算成以太币
>eth.getBalance(eth.accounts[0])
2.31e+21
>web3.fromWei(eth.getBalance(eth.accounts[0]),'ether')
2310
可以设置矿工的账户
>miner.setEtherbase(eth.accounts[1]) true >eth.coinbase
返回矿工的账户
转账
#为账户设置别名,方便命令输入 user1=eth.accounts[0] user2=eth.accounts[1]
#查看区块高度,现在为0 eth.blockNumber
#转账测试,首先解锁账号user1 #命令运行后要求输入解锁密码,直接回车,默认账号锁定密码为空 也就是调用newAccount时候传的参数 返回true成功 personal.unlockAccount(user1)
#从user1向user2转账3个以太币 #命令运行后,提交交易立马回出发挖矿 eth.sendTransaction({from:user1,to:user2,value:web3.toWei(3,"ether")})
发现还没转过去,此时交易已经提交到区块链,但还未被处理,这可以通过查看txpool来验证:
>txpool.status
{
pending: 1,
queued: 0
}
#挖矿测试
#geth启动后,自动启动挖矿,这时运行miner.start(),返回为null 无交易的时候#不挖矿,当有交易时自动会触发挖矿流程
#我们可以先停止挖矿
miner.stop()
然后发现交易已经完成
查看交易和区块
可以通过区块号查看区块
> eth.getBlock(66) { difficulty: 135266, extraData: "0xd783010802846765746886676f312e31308664617277696e", gasLimit: 3350537, gasUsed: 0, hash: "0x265dfcc0649bf6240812256b2b9b4e3ae48d51fd8e43e25329ac111556eacdc8", logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", miner: "0x4a3b0216e1644c1bbabda527a6da7fc5d178b58f", mixHash: "0xaf755722f62cac9b483d3437dbc795f2d3a02e28ec03d39d8ecbb6012906263c", nonce: "0x3cd80f6ec5c2f3e9", number: 66, parentHash: "0x099776a52223b892d13266bb3aec3cc04c455dc797185f0b3300d39f9fc0a8ec", receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", size: 535, stateRoot: "0x0c9feec5a201c8c98618331aecbfd2d4d93da1c6064abd0c41ae649fc08d8d06", timestamp: 1520391527, totalDifficulty: 8919666, transactions: [], transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", uncles: [] }
或者通过交易hash查看交易,交易hash就是在sendTransaction的时候,会返回的一串
> amount = web3.toWei(10,'ether') "10000000000000000000" > eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:amount}) INFO [03-07|11:13:11] Submitted transaction fullhash=0x1b21bba16dd79b659c83594b0c41de42debb2738b447f6b24e133d51149ae2a6 recipient=0x46B24d04105551498587e3C6CE2c3341d5988938 "0x1b21bba16dd79b659c83594b0c41de42debb2738b447f6b24e133d51149ae2a6"
>eth.getTransaction("0x1b21bba16dd79b659c83594b0c41de42debb2738b447f6b24e133d51149ae2a6") { blockHash: "0x1cb368a27cc23c786ff5cdf7cd4351d48f4c8e8aea2e084a5e9d7c480449c79a", blockNumber: 463, from: "0x4a3b0216e1644c1bbabda527a6da7fc5d178b58f", gas: 90000, gasPrice: 18000000000, hash: "0x1b21bba16dd79b659c83594b0c41de42debb2738b447f6b24e133d51149ae2a6", input: "0x", nonce: 0, r: "0x31d22686e0d408a16497becf6d47fbfdffe6692d91727e5b7ed3d73ede9e66ea", s: "0x7ff7c14a20991e2dfdb813c2237b08a5611c8c8cb3c2dcb03a55ed282ce4d9c3", to: "0x46b24d04105551498587e3c6ce2c3341d5988938", transactionIndex: 0, v: "0x38", value: 10000000000000000000 }