修訂日期 | 姓名 | 郵箱 |
---|---|---|
2018-09-23 | brucefeng | brucefeng@brucefeng.com |
這半個月都在處理其餘的事情,沒來得及更新博客,今天看了下最近的博客訪問量增長很多,說明51CTO的小夥伴們對區塊鏈的興趣程度仍是極大的,可是考慮到前面的幾篇文章更多的都是關注於開發層面,而做爲運維出身的筆者很清楚51CTO上面的大部分讀者仍是運維同窗,因此在中秋節到來之際,寫一篇運維同窗比較感興趣也比較有興趣去學習的文章。html
說實話,最近這大半年,區塊鏈的圈子一直很是火(我指的是技術圈子,跟業務無關),不只僅是區塊鏈開發方向,區塊鏈運維也是蠻緊俏的,由於除了須要掌握傳統的DevOps技術以外(此處的傳統並非老技術,特指運維必備技能統稱),更要熟悉區塊鏈層面的相關軟件或者平臺,好比以太坊與超級帳本的私有化搭建與部署,固然如今最火爆的仍是對以太坊的研究。node
本文的操做環境是在虛擬機上完成,共計三臺虛擬機(配置儘可能高上去,以下這個配置挖礦太耗時)linux
主機名 | IP地址 | 操做系統 | 內存/GB | CPU/核 |
---|---|---|---|---|
nodeA.brucefeng.com | 172.16.222.189 | Ubuntu18.04 LTS | 2 | 2 |
nodeB.brucefeng.com | 172.16.222.190 | Ubuntu18.04 LTS | 2 | 2 |
nodeC.brucefeng.com | 172.16.222.191 | Ubuntu18.04 LTS | 2 | 2 |
以nodeA爲例進行相關配置,其餘節點配置操做相同git
根據本身須要選擇是否須要更換軟件源,此處用的是原生的便可。github
$ sudo apt-get update
sudo apt-get install vim openssh-server ntp ntpdate make gcc net-tools -y
$ sudo hostname nodeA.brucefeng.com
$ vim /etc/hosts 127.0.0.1 localhost 172.16.222.189 nodeA.brucefeng.com 172.16.222.190 nodeB.brucefeng.com 172.16.222.191 nodeC.brucefeng.com
hostname --fqdn驗證web
$ hostname -f nodeA.brucefeng.com
$ sudo timedatectl set-timezone "Asia/Shanghai"
$ sudo ntpdate time1.aliyun.com
$ sudo hwclock -w # 系統時間同步至硬件
手動設置完畢後,再經過以下方式進行ntp服務的配置,能夠選擇現有或者自建的時間服務器json
$ ntpdate -q time1.aliyun.com server 203.107.6.88, stratum 2, offset 0.050751, delay 0.06232 22 Sep 21:04:36 ntpdate[8082]: adjust time server 203.107.6.88 offset 0.050751 sec
$ sudo cp /etc/ntp.conf /etc/ntp.conf_brucefeng_201809231208 #備份配置文件 $ sudo vim /etc/ntp.conf //修改配置文件
修改信息以下ubuntu
# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board # on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for # more information. #pool 0.ubuntu.pool.ntp.org iburst #pool 1.ubuntu.pool.ntp.org iburst #pool 2.ubuntu.pool.ntp.org iburst #pool 3.ubuntu.pool.ntp.org iburst server time1.aliyun.com server time2.aliyun.com server time3.aliyun.com server time4.aliyun.com server time5.aliyun.com server time6.aliyun.com server time7.aliyun.com
$ sudo systemctl restart ntp #啓動ntp服務
以下操做在三臺機器上均須要執行完畢vim
$ mkdir ethereum ;cd ethereum $ wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
$ sudo tar zxvf go1.11.linux-amd64.tar.gz -C /usr/local/
$ mkdir -p ~/workspace/{src,pkg,bin} $ sudo cp /etc/profile /etc/profile_brucefeng_201809231354 $ sudo vim /etc/profile
添加以下配置api
#Setting For Golang export GOROOT="/usr/local/go" export GOPATH="/home/ubuntu/workspace" export GOBIN=$GOPATH/bin export PATH=$PATH:$GOROOT/bin
$ source /etc/profile $ go env
出現以下信息表示安裝完畢
GOARCH="amd64" GOBIN="/home/ubuntu/workspace/bin" GOCACHE="/home/ubuntu/.cache/go-build" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOOS="linux" GOPATH="/home/ubuntu/workspace" GOPROXY="" ......
以太坊的源碼文件網址以下
https://github.com/ethereum/go-ethereum
能夠選擇經過git clone
或者下載zip
包的方式進行源代碼的獲取,爲了方便起見,本文直接下載zip包上傳至三臺節點進行解壓部署。
(1) 下載源碼包
$ cd /home/ubuntu/ethereum $ wget https://github.com/ethereum/go-ethereum/archive/master.zip
(2) 解壓源碼包
$ unzip master.zip $ mkdir ~/workspace/github.com/ $ mv go-ethereum-master/ ~/workspace/github.com/go-ethereum $ cd ~/workspace/github.com/go-ethereum ; make geth #編譯安裝
(3) 添加環境變量
$ sudo vim /etc/profile
添加並修改以下信息
export GETH="$GOPATH/github.com/go-ethereum/build" export PATH=$PATH:$GOROOT/bin:$GETH/bin
(4) 測試生效
$ source /etc/profile $ geth --help
(1) 建立數據存儲目錄
$ mkdir -p /home/ubuntu/nodeA/data0 $ cd /home/ubuntu/nodeA
(2) 創世區塊配置文件genesis.json
{ "config": { "chainId": 66, "homesteadBlock": 0, "eip155Block": 0, "eip158Block": 0 }, "alloc" : {}, "coinbase" : "0x0000000000000000000000000000000000000000", "difficulty" : "0x20000", "extraData" : "", "gasLimit" : "0x2fefd8", "nonce" : "0x0000000000000042", "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", "parentHash" :"0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp" : "0x00" }
(3) 初始化創世區塊
$ geth --datadir data0/ init genesis.json
$ geth --datadir data0/ --networkid 66 --nodiscover console
Welcome to the Geth JavaScript console! 顯示啓動成功
> admin.peers []
目前爲空狀態,代表未於其餘節點進行通訊。
> admin.nodeInfo.enode
分別在三個節點的console上執行命令,顯示以下:
NodeA
"enode://d0d6a32cacb349c8f8c92372dc3a1e118384720636519a46c14067a3b62f6cfa8549a8766ade0f91790ebdadfb44341e03c50a171b714070527be96ed037707e@[::]:30303?discport=0"
NodeB
"enode://d9fc148c9808fbfee7954bd3324bfdff42777de7d2545ac3c2357f05939dbd8ee153cd32320a05f4dbf18138007f743f3a2097b62e71c3c47bb3cf1559dd1328@[::]:30303?discport=0"
NodeC
"enode://246782d2429f4697e18009505989ed82c2c0a664aab96ed80b96e28be42b6d9e2d11b27806ea43e46fddfcb3e9a41e9df4889636f51e3dadc0c937b0735d0bdc@[::]:30303?discport=0"
在NodeA節點上執行以下命令
>admin.addPeer("enode://d9fc148c9808fbfee7954bd3324bfdff42777de7d2545ac3c2357f05939dbd8ee153cd32320a05f4dbf18138007f743f3a2097b62e71c3c47bb3cf1559dd1328@172.16.222.190:30303")
返回true
表示加入成功
注意點
> admin.peers
在NodeA節點上執行以下命令
經過查看localAddress跟remoteAddress查看節點關聯信息。
在NodeB節點上執行以下命令
在NodeC節點上執行以下命令
> admin.peers []
在NodeA節點上執行以下命令
>admin.addPeer("enode://246782d2429f4697e18009505989ed82c2c0a664aab96ed80b96e28be42b6d9e2d11b27806ea43e46fddfcb3e9a41e9df4889636f51e3dadc0c937b0735d0bdc@172.16.222.191:30303")
在NodeB節點上執行以下命令
>admin.addPeer("enode://246782d2429f4697e18009505989ed82c2c0a664aab96ed80b96e28be42b6d9e2d11b27806ea43e46fddfcb3e9a41e9df4889636f51e3dadc0c937b0735d0bdc@172.16.222.191:30303")
在NodeA節點上執行以下命令
在NodeB節點上執行以下命令
在NodeC節點上執行以下命令
注意: 節點關機後,會自動被刪除,節點從新啓動後,會自動加入節點集羣,可是若是全部節點所有斷掉,則須要從新添加。
> personal.listAccounts
或者
> eth.accounts
> personal.newAccount("brucefeng1991") "0xcd3d95c64394452313b539a1f2de54eab2b80eed" > personal.newAccount("brucefeng1992") "0xc4f132a71da05257a71ae5872beabd12c50dbb81"
> personal.listAccounts ["0xcd3d95c64394452313b539a1f2de54eab2b80eed", "0xc4f132a71da05257a71ae5872beabd12c50dbb81"]
查看帳戶地址
> personal.listWallets
> eth.coinbase INFO [09-23|18:17:20.246] Etherbase automatically configured address=0xcD3d95c64394452313b539a1f2dE54Eab2B80eEd "0xcd3d95c64394452313b539a1f2de54eab2b80eed"
默認狀況下,平臺會選擇建立的第一個帳戶做爲挖礦帳戶(coinbase),能夠經過miner.setEthbase()進行coinbase帳戶的設置。
注意:在執行挖礦命令以前,務必在節點上面設置挖礦帳戶(coinbase),不然會報錯
Error: etherbase missing: etherbase must be explicitly specified
NodeA
["0xcd3d95c64394452313b539a1f2de54eab2b80eed", "0xc4f132a71da05257a71ae5872beabd12c50dbb81"]
NodeB
["0x22160d844b4016ed8f45ce63c405de72b1946696", "0x23e80b2f1f74fc6da4bcb015d17ed642bcc98c06"]
NodeC
["0xa37539c0f41fea23c81f65b196df825202bc3bb5", "0x3c9cdb2f29606a0b35ae95b51521a41bb5b48e27"]
> miner.start()
INFO [09-23|18:57:41.223] Updated mining threads threads=6 INFO [09-23|18:57:41.223] Transaction pool price threshold updated price=1000000000 null > INFO [09-23|18:57:41.225] Commit new mining work number=1 sealhash=b16ebe…9b0094 uncles=0 txs=0 gas=0 fees=0 elapsed=794.985µs > INFO [09-23|18:57:52.671] Successfully sealed new block number=1 sealhash=b16ebe…9b0094 hash=082473…eb94b6 elapsed=11.446s INFO [09-23|18:57:52.671] ined potential block number=1 hash=082473…eb94b6 INFO [09-23|18:57:52.672] Commit new mining work number=2 sealhash=7a67a7…3c98aa uncles=0 txs=0 gas=0 fees=0 elapsed=1.062ms INFO [09-23|18:57:55.115] Successfully sealed new block number=2 sealhash=7a67a7…3c98aa hash=c5cd53…c3e66b elapsed=2.443s INFO [09-23|18:57:55.115] ined potential block number=2 hash=c5cd53…c3e66b INFO [09-23|18:57:55.116] Commit new mining work number=3 sealhash=cc1414…f36ad7 uncles=0 txs=0 gas=0 fees=0 elapsed=343.53µs INFO [09-23|18:57:55.166] Successfully sealed new block number=3 sealhash=cc1414…f36ad7 hash=765d41…03ce17 elapsed=50.270ms INFO [09-23|18:57:55.166] ined potential block number=3 hash=765d41…03ce17 INFO [09-23|18:57:55.167] Commit new mining work number=4 sealhash=cb5122…e36b2c uncles=0 txs=0 gas=0 fees=0 elapsed=718.996µs INFO [09-23|18:57:58.048] Successfully sealed new block number=4 sealhash=cb5122…e36b2c hash=ab1e6d…03b40b elapsed=2.881s INFO [09-23|18:57:58.048] ined potential block number=4 hash=ab1e6d…03b40b INFO [09-23|18:57:58.049] Commit new mining work number=5 sealhash=0dd5ab…5d47d9 uncles=0 txs=0 gas=0 fees=0 elapsed=159.
注意:儘可能將虛擬機的配置調高一點,不然會出現如下這些信息,耗時很是久。
INFO [09-23|18:48:45.223] Updated mining threads threads=2 INFO [09-23|18:48:45.229] Transaction pool price threshold updated price=1000000000 INFO [09-23|18:48:45.230] Etherbase automatically configured address=0x22160D844B4016eD8f45cE63C405DE72B1946696 null > INFO [09-23|18:48:45.236] Commit new mining work number=1 sealhash=88e805…da6df6 uncles=0 txs=0 gas=0 fees=0 elapsed=4.290ms INFO [09-23|18:48:48.930] Generating DAG in progress epoch=0 percentage=0 elapsed=2.961s INFO [09-23|18:48:51.895] Generating DAG in progress epoch=0 percentage=1 elapsed=5.926s INFO [09-23|18:48:54.739] Generating DAG in progress epoch=0 percentage=2 elapsed=8.770s ..........無盡的等待......... INFO [09-23|18:53:50.638] Generated ethash verification cache epoch=0 elapsed=5m4.669s INFO [09-23|18:54:08.357] Generating DAG in progress epoch=1 percentage=0 elapsed=15.480s INFO [09-23|18:54:19.874] Generating DAG in progress epoch=1 percentage=1 elapsed=26.997s INFO [09-23|18:54:29.911] Generating DAG in progress epoch=1 percentage=2 elapsed=37.034s ..........無盡的等待......... WARN [09-23|18:57:57.836] Discarded bad propagated block number=1 hash=082473…eb94b6 INFO [09-23|18:57:58.398] Block synchronisation started INFO [09-23|18:57:58.404] Mining aborted due to sync INFO [09-23|18:57:58.611] Imported new state entries count=1 elapsed=1.352ms processed=1 pending=0 retry=0 duplicate=0 unexpected=0 INFO [09-23|18:57:58.870] Imported new block headers count=4 elapsed=95.436ms number=4 hash=ab1e6d…03b40b INFO [09-23|18:57:58.889] Imported new chain segment blocks=4 txs=0 mgas=0.000 elapsed=16.862ms mgasps=0.000 number=4 hash=ab1e6d…03b40b cache=849.00B INFO [09-23|18:57:58.892] Imported new block headers count=1 elapsed=20.452ms number=5 hash=75e595…4e4cc2 INFO [09-23|18:57:58.893] Imported new chain segment blocks=1 txs=0 mgas=0.000 elapsed=316.348µs mgasps=0.000 number=5 hash=7 ..........無盡的等待......... INFO [09-23|19:07:35.250] Generated ethash verification cache epoch=1 elapsed=13m42.368s INFO [09-23|19:09:28.613] Successfully sealed new block number=37 sealhash=95e0e0…ad356d hash=7506d6…015be8 elapsed=10m54.093s INFO [09-23|19:09:28.614] ined potential block number=37 hash=7506d6…015be8 INFO [09-23|19:09:28.619] Commit new mining work number=38 sealhash=96b6b0…b3d462 uncles=0 txs=0 gas=0 fees=0 elapsed=662.942µs INFO [09-23|19:12:33.104] Successfully sealed new block number=38 sealhash=96b6b0…b3d462 hash=a91e1b…a15902 elapsed=3m4.484s INFO [09-23|19:12:33.105] ined potential block number=38 hash=a91e1b…a15902 INFO [09-23|19:12:33.107] Commit new mining work number=39 sealhash=6bf2a3…0d8be3 uncles=0 txs=0 gas=0 fees=0 elapsed=2.170ms
> miner.stop()
NodeA
coinbase帳戶: 0xcd3d95c64394452313b539a1f2de54eab2b80eed
> eth.getBalance(eth.coinbase) 180000000000000000000
或者
> eth.getBalance(eth.accounts[0]) 180000000000000000000
或者對結果進行單位轉換
> web3.fromWei(eth.getBalance(eth.accounts[0]),'ether') 180
NodeB查詢NodeA的coinbase帳戶
> eth.getBalance("0xcd3d95c64394452313b539a1f2de54eab2b80eed") 180000000000000000000
NodeC查詢NodeA的coinbase帳戶
> eth.getBalance("0xcd3d95c64394452313b539a1f2de54eab2b80eed") 180000000000000000000
一樣,在NodeA和NodeC上面一樣能夠查詢NodeB上面帳號地址的餘額。
場景: NodeA(原有額度:180)的挖礦地址向NodeB(原有額度:10)的挖礦地址轉入2 ETH
在進行交易轉帳以前,咱們須要對交易轉出方的帳戶進行解鎖操做。
NodeA上執行命令
> personal.unlockAccount("0xcd3d95c64394452313b539a1f2de54eab2b80eed") Unlock account 0xcd3d95c64394452313b539a1f2de54eab2b80eed Passphrase: true
將ETH轉成Wei進行交易
> transferAmount= web3.toWei(2,'ether') "2000000000000000000"
>eth.sendTransaction({from:"0xcd3d95c64394452313b539a1f2de54eab2b80eed",to:"0x22160d844b4016ed8f45ce63c405de72b1946696",value:transferAmount})
返回結果
INFO [09-23|20:13:20.968] Setting new local account address=0xcD3d95c64394452313b539a1f2dE54Eab2B80eEd INFO [09-23|20:13:20.968] Submitted transaction fullhash=0xd115c9ccfb1bfcc92faaf3ef6fae34ba670ef68cb03807d82d943141851985ce recipient=0x22160D844B4016eD8f45cE63C405DE72B1946696 "0xd115c9ccfb1bfcc92faaf3ef6fae34ba670ef68cb03807d82d943141851985ce"
> txpool.status { pending: 1, queued: 0 }
指定只挖一個區塊
> miner.start() ; admin.sleepBlocks(1),miner.stop()
> txpool.status { pending: 0, queued: 0 }
NodeB的CoinBase帳戶餘額
> web3.fromWei(eth.getBalance("0x22160d844b4016ed8f45ce63c405de72b1946696"),'ether') 12
用於測試的合約,咱們能夠沿用上一篇博客《以太坊智能合約項目-Token合約開發與部署中定義的Token合約。
pragma solidity ^0.4.24; contract EIP20Interface{ //獲取_owner地址的餘額 function balanceOf(address _owner) public view returns (uint256 balance); //轉帳:從本身帳戶向_to地址轉入_value個Token function transfer(address _to, uint256 _value)public returns (bool success); //轉帳:從_from向_to轉_value個Token function transferFrom(address _from, address _to, uint256 _value) returns (bool success); //容許_spender從本身(調用方)帳戶轉走_value個Token function approve(address _spender, uint256 _value) returns (bool success); //本身_owner查詢__spender地址能夠轉走本身多少個Token function allowance(address _owner, address _spender) view returns (uint256 remaining); //轉帳的時候必需要調用的時間,好比Tranfer,TransferFrom event Transfer(address indexed _from, address indexed _to, uint256 _value); //成功執行approve方法後調用的事件 event Approval(address indexed _owner, address indexed _spender, uint256 _value); } contract BFCToken is EIP20Interface { //1.獲取token名字,好比"BruceFeng Coin" string public name; //2.獲取Token簡稱,好比"BFC" string public symbol; //3.獲取小數位,好比以太坊的decimals爲18 uint8 public decimals; //4.獲取token發佈的總量,好比HT 5億 uint256 public totalSupply; mapping(address=>uint256) balances ; mapping(address=>mapping(address=>uint256)) allowances; function BFCToken(string _name,string _symbol, uint8 _decimals,uint256 _totalSupply) public{ name = _name; symbol = _symbol; decimals = _decimals; totalSupply = _totalSupply; balances[msg.sender] = _totalSupply; } //獲取_owner地址的餘額 function balanceOf(address _owner) public view returns (uint256 balance){ return balances[_owner]; } //轉帳:從本身帳戶向_to地址轉入_value個Token function transfer(address _to, uint256 _value)public returns (bool success){ require(_value >0 && balances[_to] + _value > balances[_to] && balances[msg.sender] > _value); balances[_to] += _value; balances[msg.sender] -= _value; Transfer(msg.sender, _to,_value); return true; } //轉帳:從_from向_to轉_value個Token function transferFrom(address _from, address _to, uint256 _value) returns (bool success){ uint256 allowan = allowances[_from][_to]; require(allowan > _value && balances[_from] >= _value && _to == msg.sender && balances[_to] + _value>balances[_to]); allowances[_from][_to] -= _value; balances[_from] -= _value; balances[_to] += _value; Transfer(_from,_to,_value); return true; } //容許_spender從本身(調用方)帳戶轉走_value個Token function approve(address _spender, uint256 _value) returns (bool success){ require(_value >0 && balances[msg.sender] > _value); allowances[msg.sender][_spender] = _value; Approval(msg.sender,_spender,_value); return true; } //本身_owner查詢_spender地址能夠轉走本身多少個Token function allowance(address _owner, address _spender) view returns (uint256 remaining){ return allowances[_owner][_spender]; } }
[ { "constant": true, "inputs": [], "name": "name", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_spender", "type": "address" }, { "name": "_value", "type": "uint256" } ], "name": "approve", "outputs": [ { "name": "success", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_from", "type": "address" }, { "name": "_to", "type": "address" }, { "name": "_value", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "name": "success", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "decimals", "outputs": [ { "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_owner", "type": "address" } ], "name": "balanceOf", "outputs": [ { "name": "balance", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "symbol", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_to", "type": "address" }, { "name": "_value", "type": "uint256" } ], "name": "transfer", "outputs": [ { "name": "success", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_owner", "type": "address" }, { "name": "_spender", "type": "address" } ], "name": "allowance", "outputs": [ { "name": "remaining", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [ { "name": "_name", "type": "string" }, { "name": "_symbol", "type": "string" }, { "name": "_decimals", "type": "uint8" }, { "name": "_totalSupply", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "_from", "type": "address" }, { "indexed": true, "name": "_to", "type": "address" }, { "indexed": false, "name": "_value", "type": "uint256" } ], "name": "Transfer", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "_owner", "type": "address" }, { "indexed": true, "name": "_spender", "type": "address" }, { "indexed": false, "name": "_value", "type": "uint256" } ], "name": "Approval", "type": "event" } ]
經過http://www.bejson.com/zhuanyi/進行JSON壓縮後的結果以下
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_decimals","type":"uint8"},{"name":"_totalSupply","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"}]
在NodeA上執行命令,將以上ABI壓縮字段複製給ABI變量
> ABI = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_decimals","type":"uint8"},{"name":"_totalSupply","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"}]
bruceToken = eth.contract(ABI)
經過BYTECODE獲取Object信息
賦值的時候,切記在前面加上
0x
> bruceHEX = "0x608060405234801561001057600080fd5b50604051610e97380380610e9783398101806040528101908080518201929190602001805182019291906020018051906020019092919080519060200190929190505050836000908051906020019061006a9291906100f1565b5082600190805190602001906100819291906100f1565b5081600260006101000a81548160ff021916908360ff1602179055508060038190555080600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050505050610196565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061013257805160ff1916838001178555610160565b82800160010185558215610160579182015b8281111561015f578251825591602001919060010190610144565b5b50905061016d9190610171565b5090565b61019391905b8082111561018f576000816000905550600101610177565b5090565b90565b610cf2806101a56000396000f300608060405260043610610099576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde031461009e578063095ea7b31461012e57806318160ddd1461019357806323b872dd146101be578063313ce5671461024357806370a082311461027457806395d89b41146102cb578063a9059cbb1461035b578063dd62ed3e146103c0575b600080fd5b3480156100aa57600080fd5b506100b3610437565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f35780820151818401526020810190506100d8565b50505050905090810190601f1680156101205780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561013a57600080fd5b50610179600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506104d5565b604051808215151515815260200191505060405180910390f35b34801561019f57600080fd5b506101a861061f565b6040518082815260200191505060405180910390f35b3480156101ca57600080fd5b50610229600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610625565b604051808215151515815260200191505060405180910390f35b34801561024f57600080fd5b50610258610957565b604051808260ff1660ff16815260200191505060405180910390f35b34801561028057600080fd5b506102b5600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061096a565b6040518082815260200191505060405180910390f35b3480156102d757600080fd5b506102e06109b3565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610320578082015181840152602081019050610305565b50505050905090810190601f16801561034d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561036757600080fd5b506103a6600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610a51565b604051808215151515815260200191505060405180910390f35b3480156103cc57600080fd5b50610421600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c3f565b6040518082815260200191505060405180910390f35b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104cd5780601f106104a2576101008083540402835291602001916104cd565b820191906000526020600020905b8154815290600101906020018083116104b057829003601f168201915b505050505081565b60008082118015610524575081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054115b151561052f57600080fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60035481565b600080600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811180156106f5575082600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410155b801561072c57503373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16145b80156107b75750600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401115b15156107c257600080fd5b82600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555082600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555082600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a360019150509392505050565b600260009054906101000a900460ff1681565b6000600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a495780601f10610a1e57610100808354040283529160200191610a49565b820191906000526020600020905b815481529060010190602001808311610a2c57829003601f168201915b505050505081565b60008082118015610ae15750600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401115b8015610b2b575081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054115b1515610b3657600080fd5b81600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050929150505600a165627a7a72305820eac390c09a7095b2652ffac48f264fa4ad528bc27003ccd6b90fa2f33d8bb7820029"
中秋節Token發給你們,祝你們中秋節快樂 :-)
bruceTokenBZQJT = bruceToken.new("Brucefeng ZHONGQIU Token ","BZQJT",18,8888000000000000000000,{from:eth.accounts[0],data:bruceHEX,gas:3000000})
參數信息
- name : "Brucefeng ZHONGQIU Token "
- symbol: BZQJT"
- decimals: 18
- totalSupply: 8888000000000000000000
記錄下以下信息便可
查看交易池信息
> txpool.status { pending: 1, queued: 0 } >
執行挖礦
miner.start() ; admin.sleepBlocks(1),miner.stop()
由於針對於合約的測試,在本文中並不是是重點,因此,此處只進行簡單的測試
> bruceTokenBZQJT.name() "Brucefeng ZHONGQIU Token "
> bruceTokenBZQJT.symbol() "BZQJT"
> bruceTokenBZQJT.decimals() 18
> bruceTokenBZQJT.totalSupply() 8.888e+21
從當前NodeA的coinbase帳戶轉帳
0.8箇中秋Token
到NodeB的coinbase帳戶
>bruceTokenBZQJT.transfer("0x22160d844b4016ed8f45ce63c405de72b1946696",800000000000000000,{from:eth.accounts[0],data:bruceHEX,gas:3000000})
查看NodeA,NodeB的coinbase帳戶中
中秋Token
的餘額
此處的節點同步並不是同步合約到其餘節點,合約在一臺節點上部署完畢後,全部節點均已經同步,此處的節點同步代指在其餘節點上面想要對合約進行相關的操做時須要準備的操做。
獲取合約的ABI信息
獲取合約對象
以上三個步驟直接參照上文進行變量定義便可,只是不須要執行執行部署的操做了。
經過合約地址直接能夠獲取合約實例
> TokenNodeB = bruceToken.at("0xc191EceD0ddf7D9aE883E24Ff6ed5fd6004c718F")
此時,能夠在新的節點上面對合約進行任意功能內的測試與使用了。
參數名 | 說明 |
---|---|
chainId | 指定獨立的區塊鏈網絡ID,1-4爲保留ID,其中1爲主網ID,其他爲測試網 |
alloc | 用來設置帳號以及帳號的以太幣數量,私有鏈能夠不進行設置 |
coinbase | 用於獲取挖礦獎勵的礦工帳號 |
difficulty | 設置挖礦的難度係數 |
extraData | 附加信息,自定義便可 |
gasLimit | 設置對gas的消耗總量的限制,私有鏈中能夠填寫任意數值(大數值) |
nonce | 用於進行挖礦的隨機數 |
mixhash | 與nonce配合使用,用於挖礦 |
parentHash | 上一個區塊的Hash值,因爲該區塊爲創世區塊,因此父Hash值爲0 |
timestamp | 時間戳 |
data0目錄中的相關文件列表
參數名 | 說明 |
---|---|
identity | 用於標識區塊鏈的名稱 |
init | 用於指定創世區塊的位置,而且建立創世區塊以及相關目錄結構 |
datadir | 設置當前區塊鏈網絡數據存放的位置 |
port | 區塊鏈啓動的監聽端口,默認爲30303 |
rpc | 啓用RPC服務,能夠用於智能合約的部署與調試,默認監聽127.0.0.1,端口爲8545 |
rpcapi | 設置RPC提供的API接口類型,通常爲db,eth.net.web3 |
networkid | 設置當前區塊鏈的網絡ID |
nodiscover | 設置節點不被自動發現,用於控制節點的加入 |
console | 啓用命令行模式,用於執行命令 |
help | 幫助命令,全部參數的彙總 |
以太坊提供了一個交互式的JavaScript環境,能夠在該環境中進行命令或者代碼的執行操做,其中一些經常使用的以太坊JavaScript對象能夠直接被調用。
對象名 | 說明 |
---|---|
eth | 操做區塊鏈相關的方法 |
eth.accounts | 查看當前系統中的全部帳戶地址 |
eth.getBalance() | 查詢帳戶餘額,返回單位爲Wei(1 ether=10^18Wei) |
eth.blockNumber | 列出區塊總數 |
eth.getTransaction() | 獲取指定交易的狀態信息 |
eth.getBlock() | 獲取指定區塊的信息 |
net | 用於查看p2p網絡狀態 |
admin | 管理節點相關的方法 |
admin.peers | 查看通信的節點信息 |
admin.addPeer() | 添加通信P2P節點 |
miner | 啓動/中止挖礦相關方法 |
personal | 用於管理帳戶 |
personal.newAccount() | 建立帳戶 |
personal.unlockAccount() | 解鎖帳戶 |
txpool | 查看交易池信息, txpool.status() |
web3 | 包含了以上對象以及單位換算等方法 |
web3.fromWei() | Wei換算成ether或者其餘單位 |
web3.toWei() | 將ether或者其餘單位換算成Wei |