# blockchain workshop 1 ###### tags: `blockchain` ### 1. install geth 首先使用 Geth 來安裝 Ethereum Node windows 安裝 https://geth.ethereum.org/downloads/ Mac 安裝 ``` $ brew tap ethereum/ethereum $ brew install ethereum ``` 檢查是否安裝成功 ``` $ geth -h ``` ### 2. create directory structure 建立一資料夾,隨意取名,「myPrivateChain」,cd 進資料夾 ### 3. create a genesis configuration 建立創世區塊的參數用檔案,檔案取名為 `genesis.json` ```json= { "config": { "chainID": 123456, "homesteadBlock": 0, "eip150Block": 0, "eip155Block": 0, "eip158Block": 0 }, "nonce": "0x0000000000000042", "difficulty": "0x020", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x0000000000000000000000000000000000000000", "timestamp": "0x00", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x2fefd8", "alloc": { "0x0000000000000000000000000000000000000001": { "balance": "11111111111" }, "0x0000000000000000000000000000000000000002": { "balance": "22222222222" } } } ``` 參數介紹 | 參數 | 介紹 | | -------- | -------- | | chainID | chainID 漢 networkid 一樣由 EIP 155 提供 chainid values 的建議來代稱不同的網路.只有當 networkid 及 chainID、創世區塊的配置都相同時,才是同一條鏈 | |nounce | 用於挖礦的 64bits 隨機數,與 pow 機制有關 | |difficulty|定義了每次挖礦時,最終確定 nonce 的難度 | |mixhash|與 nonce 配合用於挖礦,由上一個區塊的部分產生雜湊值| |coinbase|預設為第一個建立挖礦的礦工| |timestamp|創世區塊的時間戳| |parentHash|指定了本區塊的上一個區塊 hash,因此創世區塊的parenthash 為 0| |gasLimit|規定該區塊鏈中,交易使用的 gas 上限,某種程度上是規定區塊中能包含交易信息量的總和| |alloc|可以從創世塊塊預設帳號及帳號內的金額,單位是 wei 不是 eth| > gas 是合約進行交易時的手續費,當我們傳送一些指令給 Ethereum Virtual Machine(EVM) 來進行互動時就會消耗一定量的 gas ### 4. initial the genesis.json 初始化,輸入以下指令來建立初始區塊 ``` $ geth --datadir data init genesis.json ``` `--datadir data`: 使區塊儲存於 data 資料夾 ### 5. start your blockchain! 啟動私有鏈 ``` $ geth --datadir data --networkid 123456 console ``` networkid 就是剛剛 genesis.json 中設置的 chainID |測試網| nerwork| |----|----| |Oympic testnet|0| |Ethereum Mainnet(frontier)|1| |Ethereum's Morden testnet|2| |Ropsten testnet|3| |Rinkeby|4| |Kovan|42| ### 6. Attach javascript console 在這個交互式的 javascript 的執行環境中,內置了一些用來操作以太坊的 javascript 對象,可以直接使用 ||| |-----|-----| |eth|操作區塊鏈| |net|查看 P2P 網路狀態| |miner|啟動&停止挖礦| |personal|管理帳戶| |txpool|查看 transaction pool| |web3|包含以上對象,以及換算單位的方法| ### 7. management the private Chain 查看所有帳號 ```c > eth.accounts ``` 查看節點資訊 ```c > admin.nodeInfo ``` 建立新帳戶,其中的字串為預設密碼 ```c > personal.newAccount("6666") ``` 查看帳號存款 ```c > eth.getBalance("Ox........") // 也可以用陣列取值 > eth.getBalance(eth.accounts[0]) ``` 查看礦工帳號,系統預設礦工帳號為第一個帳號 ```c > eth.coinbase ``` ### 8. Transfer Ether 解鎖帳號.每次進行交易都需要解鎖帳號 ```c > personal.unlockAccount(eth.accounts[0]) ``` 之後出現的 `passphrase` 就是輸入密碼 發送交易 ```c > amount = web3.toWei(1, 'ether') "1000000000000000000" > eth.sendTransaction({from: eth.account[0], to: eth.account[1], value: amount}) ``` 如果匯出的帳號沒錢就會出錯誤! `Error: insufficient funds for transfer` ### 9. Mining Time 可以使用以下指令來更改礦工帳號,這樣挖礦就會轉到對應的帳號 ```c > miner.setEtherbase(eth.account[1]) ``` 開始挖礦,start 裡的數字是 cpu 使用數 ```c > miner.start(1) > miner.stop() ``` 再回來看帳戶有有多少錢 ```c > eth.getBalance(eth.accounts[1]) ``` unlock 帳號 1 後再次進行交易 ```c > eth.sendTransaction({from: eth.account[1], to: eth.account[0], value: amount}) ``` 查看 txpool,此時可以發現有一條 pending 的交易,代表已提交但還未被處理的交易 ```c > txpool // 或直接查看狀態 > txpool.status { pending: 1, queued: 0 } ``` 要讓交易被處理就要挖礦啦~ ### 補充 直接下 geth 會同步主網的資料 ```c $ geth ``` ### Private Chain 連結其他 Node 兩個 Node 是分開的,並不知道彼此的存在 ```c Node 1 > admin.peers [] Node 2 > admin.peers [] ``` 查看 blockNumber: ```c Node 1 > eth.blockNumber 16 Node 2 > eth.blockNumber 0 ``` 我們會發現 Node 1 有 16 個區塊了,但 Node 2 還沒有任何區塊。我們在 Node 1 取得 Node 的位址相關資訊: ```c Node 1 > admin.nodeInfo.enode "enode://cf2d54937d2e7ee080e69ecde67352837fd8230482fea2cc34ec756e2f36c10608d2cdbb66f7788c84a0069c162f043fa1f660a942dddf8fcdf9d74de87061b4@[::]:30303" ``` 將 [::] 改成 Node 1 的 Private IP,然後在 Node 2 加入這個 Peer: ```c Node 2 > cadmin.addPeer("enode://cf2d54937d2e7ee080e69ecde67352837fd8230482fea2cc34ec756e2f36c10608d2cdbb66f7788c84a0069c162f043fa1f660a942dddf8fcdf9d74de87061b4@172.31.22.132:30303") ``` 之後我們查看: ```c Node 1 > eth.blockNumber 16 Node 2 > eth.blockNumber 16 ```