[root@greg02 ~]#mkdir mychain [root@greg02 ~]#cd mychain [root@greg02 mychain]#geth --networkid 123 --dev --datadir data1 --rpc --rpcaddr 192.168.179.130 --rpcport 8989 --port 3000 #運行後產生以下文件 [root@greg02 mychain]#ls data1 [root@greg02 mychain]#ls data1/ geth geth.ipc keystore
各項含義:linux
--identity:指定節點 ID; --rpc:表示開啓 HTTP-RPC 服務; --rpcaddr:HTTP-RPC 服務ip地址; --rpcport:指定 HTTP-RPC 服務監聽端口號(默認爲 8545); --datadir:指定區塊鏈數據的存儲位置; --port:指定和其餘節點鏈接所用的端口號(默認爲 30303); --nodiscover:關閉節點發現機制,防止加入有一樣初始配置的陌生節點。
保持節點的運行,不要關閉終端,從新打開一個終端,使用geth attach
鏈接節點,而且打開geth console
web
[root@greg02 mychain]#geth attach ipc:/root/mychain/data1/geth.ipc Welcome to the Geth JavaScript console! instance: Geth/v1.8.3-unstable-746392cf/linux-amd64/go1.9.2 coinbase: 0x804bf1ee046894d6425a8bed1abe553f776ae0df at block: 0 (Thu, 01 Jan 1970 08:00:00 CST) datadir: /root/mychain/data1 modules: admin:1.0 clique:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0 >
這是一個交互式的 JavaScript 執行環境,在這裏面能夠執行 JavaScript 代碼,其中 > 是命令提示符。在這個環境裏也內置了一些用來操做以太坊的 JavaScript 對象,能夠直接使用這些對象。這些對象主要包括:shell
eth:包含一些跟操做區塊鏈相關的方法; net:包含一些查看p2p網絡狀態的方法; admin:包含一些與管理節點相關的方法; miner:包含啓動&中止挖礦的一些方法; personal:主要包含一些管理帳戶的方法; txpool:包含一些查看交易內存池的方法; web3:包含了以上對象,還包含一些單位換算的方法。
> personal.newAccount('grego') "0x88d6725760f34a91059485e396759d422441e427" > personal.listAccounts ["0x804bf1ee046894d6425a8bed1abe553f776ae0df" > web3.eth.coinbase "0x804bf1ee046894d6425a8bed1abe553f776ae0df"
pragma solidity ^0.4.0; contract Ballot { struct Voter { uint weight; bool voted; uint8 vote; address delegate; } struct Proposal { uint voteCount; } address chairperson; mapping(address => Voter) voters; Proposal[] proposals; /// Create a new ballot with $(_numProposals) different proposals. function Ballot(uint8 _numProposals) public { chairperson = msg.sender; voters[chairperson].weight = 1; proposals.length = _numProposals; } /// Give $(toVoter) the right to vote on this ballot. /// May only be called by $(chairperson). function giveRightToVote(address toVoter) public { if (msg.sender != chairperson || voters[toVoter].voted) return; voters[toVoter].weight = 1; } /// Delegate your vote to the voter $(to). function delegate(address to) public { Voter storage sender = voters[msg.sender]; // assigns reference if (sender.voted) return; while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender) to = voters[to].delegate; if (to == msg.sender) return; sender.voted = true; sender.delegate = to; Voter storage delegateTo = voters[to]; if (delegateTo.voted) proposals[delegateTo.vote].voteCount += sender.weight; else delegateTo.weight += sender.weight; } /// Give a single vote to proposal $(toProposal). function vote(uint8 toProposal) public { Voter storage sender = voters[msg.sender]; if (sender.voted || toProposal >= proposals.length) return; sender.voted = true; sender.vote = toProposal; proposals[toProposal].voteCount += sender.weight; } function winningProposal() public constant returns (uint8 _winningProposal) { uint256 winningVoteCount = 0; for (uint8 prop = 0; prop < proposals.length; prop++) if (proposals[prop].voteCount > winningVoteCount) { winningVoteCount = proposals[prop].voteCount; _winningProposal = prop; } } }
BYTECODE:json
ABI:網絡
[ { "constant": false, "inputs": [ { "name": "to", "type": "address" } ], "name": "delegate", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "winningProposal", "outputs": [ { "name": "_winningProposal", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "toVoter", "type": "address" } ], "name": "giveRightToVote", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "toProposal", "type": "uint8" } ], "name": "vote", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "name": "_numProposals", "type": "uint8" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" } ]
ABI刪除空格並轉義app
[{\"constant\":false,\"inputs\":[{\"name\":\"to\",\"type\":\"address\"}],\"name\":\"delegate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"winningProposal\",\"outputs\":[{\"name\":\"_winningProposal\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"toVoter\",\"type\":\"address\"}],\"name\":\"giveRightToVote\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"toProposal\",\"type\":\"uint8\"}],\"name\":\"vote\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_numProposals\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]
在console裏建立ABI合約對象ide
> var abi=JSON.parse('[{\"constant\":false,\"inputs\":[{\"name\":\"to\",\"type\":\"address\"}],\"name\":\"delegate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"winningProposal\",\"outputs\":[{\"name\":\"_winningProposal\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"toVoter\",\"type\":\"address\"}],\"name\":\"giveRightToVote\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"toProposal\",\"type\":\"uint8\"}],\"name\":\"vote\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_numProposals\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]') undefined > myContract=web3.eth.contract(abi) { abi: [{ constant: false, inputs: [{...}], name: "delegate", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "winningProposal", outputs: [{...}], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [{...}], name: "giveRightToVote", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [{...}], name: "vote", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { inputs: [{...}], payable: false, stateMutability: "nonpayable", type: "constructor" }], eth: { accounts: ["0x804bf1ee046894d6425a8bed1abe553f776ae0df", "0x88d6725760f34a91059485e396759d422441e427", "0x44d18ce9e2e54c93cf382e0a1e571e5e16173156"], blockNumber: 0, coinbase: "0x804bf1ee046894d6425a8bed1abe553f776ae0df", compile: { lll: function(), serpent: function(), solidity: function() }, defaultAccount: undefined, defaultBlock: "latest", gasPrice: 1, hashrate: 0, mining: true, pendingTransactions: [], protocolVersion: "0x3f", syncing: false, call: function(), contract: function(abi), estimateGas: function(), filter: function(options, callback, filterCreationErrorCallback), getAccounts: function(callback), getBalance: function(), getBlock: function(), getBlockNumber: function(callback), getBlockTransactionCount: function(), getBlockUncleCount: function(), getCode: function(), getCoinbase: function(callback), getCompilers: function(), getGasPrice: function(callback), getHashrate: function(callback), getMining: function(callback), getPendingTransactions: function(callback), getProtocolVersion: function(callback), getRawTransaction: function(), getRawTransactionFromBlock: function(), getStorageAt: function(), getSyncing: function(callback), getTransaction: function(), getTransactionCount: function(), getTransactionFromBlock: function(), getTransactionReceipt: function(), getUncle: function(), getWork: function(), iban: function(iban), icapNamereg: function(), isSyncing: function(callback), namereg: function(), resend: function(), sendIBANTransaction: function(), sendRawTransaction: function(), sendTransaction: function(), sign: function(), signTransaction: function(), submitTransaction: function(), submitWork: function() }, at: function(address, callback), getData: function(), new: function() }
> account1=web3.eth.coinbase "0x804bf1ee046894d6425a8bed1abe553f776ae0df" > web3.eth.getBalance(account1) 1.15792089237316195423570985008687907853269984665640564039457584007913129639927e+77
> web3.eth.coinbase "0x804bf1ee046894d6425a8bed1abe553f776ae0df" > personal.unlockAccount(account1, '') true
> web3.eth.estimateGas({data:bytecode}) 597031
字節碼前面須要添加0x
。手續費大概爲597031``gas
區塊鏈
> contractInstance = myContract.new({data: bytecode gas: 1000000, from: account1}, function(e, contract){ ...... if(!e){ ......... if(!contract.address){ ............ console.log("Contract transaction send: Transaction Hash: "+contract.transactionHash+" waiting to be mined..."); ............ }else{ ............ console.log("Contract mined! Address: "+contract.address); ............ console.log(contract); ............ } ......... }else{ ......... console.log(e) ......... } ...... }) Contract transaction send: Transaction Hash: 0xca1561453f4cc9541ec84dd4ef3a25cbb61ef4d1e9bf1f829fef5107f9017266 waiting to be mined... { abi: [{ constant: false, inputs: [{...}], name: "delegate", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "winningProposal", outputs: [{...}], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [{...}], name: "giveRightToVote", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [{...}], name: "vote", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { inputs: [{...}], payable: false, stateMutability: "nonpayable", type: "constructor" }], address: undefined, transactionHash: "0xca1561453f4cc9541ec84dd4ef3a25cbb61ef4d1e9bf1f829fef5107f9017266" }
合約等待挖礦ui
> miner.start() null > miner.stop() true