geth进阶:部署合约,查看区块,交易信息,挖矿

geth进阶:部署合约,查看区块,交易信息,挖矿

    • 前言
    • geth:搭建私链,挖矿,管理账户,查看区块,交易信息
    • node:部署合约,调用合约
    • 开始挖矿
      • 部署合约
      • 调用合约
      • 查看交易信息:window2
      • 温馨提示

前言

刚开始接触区块链,就是跟着网上资料逐步搭建自己的私链和部署hello world,所以给我的印象就是–geth就只能干干搭建私链,管理账户和部署简单合约。
然而,当我了解完以太坊原理和机制之后,就在想区块链上的交易信息,区块,账户信息在哪实现的…

geth:搭建私链,挖矿,管理账户,查看区块,交易信息

  • 概念:geth的全称是Go-ethereum,是一个以太坊客户端,用go语言编写,应该是目前最常用的客户端
  • 前提:为了查看运行逻辑,需要开启3个窗口
    window1:区块的信息显示(只读)
    window2:挖矿的实现(操作eth)
    window3:部署合约,实现与区块链的交互,显示合约信息(node,web3)
    
  • 事例文件结构:
    geth进阶:部署合约,查看区块,交易信息,挖矿_第1张图片
  • 前期知识储备:
    • web3.js
    • node.js
    • solc

搭建私有链:
window1:geth --rpc --rpcport 8545 --rpcaddr "localhost" --testnet --nodiscover --rpcapi "web3,net,personal,eth,txpool"
参数具体信息

INFO [01-10|11:02:48.871] Maximum peer count                       ETH=25 LES=0 total=25
INFO [01-10|11:02:48.878] Starting peer-to-peer node               instance=Geth/v1.8.16-stable-477eb093/windows-amd64/go1.11
INFO [01-10|11:02:48.883] Allocated cache and file handles         database=C:\\Users\\wuchan4x\\AppData\\Roaming\\Ethereum\\testnet\\geth\\chaindata cache=768 handles=1024
INFO [01-10|11:02:49.041] Persisted trie from memory database      nodes=355 size=51.89kB time=3.0085ms gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [01-10|11:02:49.062] Initialised chain configuration          config="{ChainID: 3 Homestead: 0 DAO:  DAOSupport: true EIP150: 0 EIP155: 10 EIP158: 10 Byzantium: 1700000 Constantinople:  Engine: ethash}"
INFO [01-10|11:02:49.082] Disk storage enabled for ethash caches   dir=C:\\Users\\wuchan4x\\AppData\\Roaming\\Ethereum\\testnet\\geth\\ethash count=3
INFO [01-10|11:02:49.089] Disk storage enabled for ethash DAGs     dir=C:\\Users\\wuchan4x\\AppData\\Ethash                                   count=2
INFO [01-10|11:02:49.097] Initialising Ethereum protocol           versions="[63 62]" network=3
INFO [01-10|11:02:49.102] Loaded most recent local header          number=4500 hash=d56e6e…fb1dd8 td=12808123260 age=22s
INFO [01-10|11:02:49.108] Loaded most recent local full block      number=4500 hash=d56e6e…fb1dd8 td=12808123260 age=22s
INFO [01-10|11:02:49.113] Loaded most recent local fast block      number=4500 hash=d56e6e…fb1dd8 td=12808123260 age=22s
INFO [01-10|11:02:49.117] Loaded local transaction journal         transactions=0 dropped=0
INFO [01-10|11:02:49.120] Regenerated local transaction journal    transactions=0 accounts=0
WARN [01-10|11:02:49.123] Blockchain not empty, fast sync disabled
INFO [01-10|11:02:49.126] Starting P2P networking
INFO [01-10|11:02:49.128] RLPx listener up                         self="enode://58f7d4f9851f9f219dcc11bc9472290d95e79722527637faff8e74058c87ff1f62048a420f295cafbb885360fac440af9b9249ec54eeac066724551bb6367e12@[::]:30303?discport=0"
INFO [01-10|11:02:49.129] IPC endpoint opened                      url=\\\\.\\pipe\\geth.ipc
INFO [01-10|11:02:49.139] HTTP endpoint opened                     url=http://localhost:8545 cors= vhosts=localhost

建立连接:
window2:geth attach \\.\pipe\geth.ipc

instance: Geth/v1.8.16-stable-477eb093/windows-amd64/go1.11
coinbase: 0x436ef52588b8c2fb1ee14844afe94bb78a4072b7
at block: 4498 (Thu, 10 Jan 2019 11:02:04 CST)
 datadir: C:\Users\wuchan4x\AppData\Roaming\Ethereum\testnet
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

>

window1–显示发现矿工:

INFO [01-10|11:02:52.273] Etherbase automatically configured       address=0x436ef52588B8c2fB1eE14844aFe94BB78a4072b7
INFO [01-10|11:09:34.862] Updated mining threads                   threads=12
INFO [01-10|11:09:34.865] Transaction pool price threshold updated price=1000000000

node:部署合约,调用合约

  • 部署环境
1.mkdir SmartContract && cd SmartContract
2.npm init 生成package.json
3.写入package.json
{
  "name": "smartcontract",
  "version": "0.0.1",
  "dependencies": {
    "fs": "0.0.1-security",
    "solc": "^0.4.21",
    "web3": "^0.20.0"//web3版本设置很重要,每个版本的部署合约方式不一样,能使用异步调用
  }
}
4.npm install

智能合约:Hello.sol

pragma solidity ^0.4.20;
contract Hello {
    uint public _c;
    uint public _b;
    constructor(uint a,uint b) public{
        _c = a;
        _b = b;
    }
    function say(string name) public pure returns (string) {
        return name;
    }
    function set() public{
      _c += 2;
    }
}

部署脚本:deployed.js

//设置web3连接
var Web3 = require('web3');
//'http://localhost:8545',该端口与搭建私链的端口一致,否则无法部署到私链
var web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
//读取合约
var fs = require('fs');
var contractCode = fs.readFileSync('Hello.sol').toString();
//编译合约代码
var solc = require('solc');
var compileCode = solc.compile(contractCode);

console.log(compileCode);

//获取合约abi和字节码
var abi = JSON.parse(compileCode.contracts[':Hello'].interface);
var byteCode = compileCode.contracts[':Hello'].bytecode;

//在节点的VM节点中执行一个消息调用,或交易。但是不会合入区块链中。返回使用的gas量
//json: cannot unmarshal hex string without 0x prefix into Go value of type hexutil.Bytes
//let gasEstimate = web3.eth.estimateGas({data:"0x"+byteCode});
//console.log("gasEstimate",gasEstimate);
//创建合约对象
var VotingContract = web3.eth.contract(abi);
//部署合约,并返回部署对象
//web3<@1.0.0:异步调用很重要,可以清楚的查看合约部署,矿工挖矿成功的log,才返回交易hash,生成合约地址address
var deployedContract = VotingContract.new(3,7,{
    data:"0x"+byteCode,
    from:web3.eth.accounts[0],  //部署合约的外部账户地址
    //Error: gas required exceeds allowance or always failing transaction
    //maxGas过多:
    gas:1000000},function(err,result){ //部署合约的矿工费
      if(err){console.log(err)
      }else{console.log(result,result.address,result.transactionHash)}
    });

console.log(deployedContract);
//eth.getHashrate(function(err,result){if(err){console.log(err)}else{console.log}})

调用脚本:call.js

//设置web3连接
var Web3 = require('web3');
//http://localhost:7545 为Ganache提供的节点链接
var web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
//读取合约
var fs = require('fs');
var contractCode = fs.readFileSync('Hello.sol').toString();
//编译合约代码
var solc = require('solc');
var compileCode = solc.compile(contractCode);
//获取合约abi和字节码
var abi = JSON.parse(compileCode.contracts[':Hello'].interface);

/*
solcjs --bin --abi Hello.sol
var abi = JSON.parse(fs.readFileSync("Hello.abi"))
var bin = fs.readFileSync("Hellp.bin")
*/

//创建合约对象
var addr = "0x00ede8b236d83909f5b9888686296df6e9cc4d77";
var VotingContract = web3.eth.contract(abi).at(addr);

//node deployed.js部署之后的合约地址:0x00ede8b236d83909f5b9888686296df6e9cc4d77

var myContract = VotingContract.set({from:web3.eth.coinbase,gas:100000},function(err,result){
  if(err){
    console.log(err);
  }else{
    console.log("eilinge",result);
  }
})

console.log(VotingContract);
//console.log(VotingContract.say.call("hello,my love"));
//调用合约方法的2种方式
console.log(VotingContract.say("hello,my love"));
/*
//每一个方法,都有默认的以下函数可以调用
say:
 { [Function: bound ]
   request: [Function: bound ],
   call: [Function: bound ],
   sendTransaction: [Function: bound ],
   estimateGas: [Function: bound ],
   getData: [Function: bound ],
   string: [Circular] },
*/
//console.log(VotingContract._c.sendTransaction({data:"0x"+abi,from:web3.eth.coinbase,gas:gasEstimate}));
//console.log(web3.toBigNumber(VotingContract._c.call()));
console.log(web3.toBigNumber(VotingContract._b()));
VotingContract._c(function(err,result){
  if(err){
    console.log(err);
  }else{
    console.log("_c",result);
  }
})

开始挖矿

部署合约

window3:node deployed.js

...
transactionHash: '0xdb4b03f06fe797e424a11fa4d548c0a810e687d8154984a55c9dea33fd41302f',
  address: undefined,
  abi:
   [ { constant: true,
       inputs: [],
       name: '_b',
       outputs: [Array],
       payable: false,
       stateMutability: 'view',
       type: 'function' },
     { constant: false,
       inputs: [],
       name: 'set',
       outputs: [],
       payable: false,
       stateMutability: 'nonpayable',
       type: 'function' },
     { constant: true,
       inputs: [Array],
       name: 'say',
       outputs: [Array],
       payable: false,
       stateMutability: 'pure',
       type: 'function' },
     { constant: true,
       inputs: [],
       name: '_c',
       outputs: [Array],
       payable: false,
       stateMutability: 'view',
       type: 'function' },
     { inputs: [Array],
       payable: false,
       stateMutability: 'nonpayable',
       type: 'constructor' } ] } undefined '0xdb4b03f06fe797e424a11fa4d548c0a810e687d8154984a55c9dea33fd41302f'

window1–捕捉到交易:

INFO [01-10|13:02:49.089] Regenerated local transaction journal    transactions=0 accounts=0
INFO [01-10|14:02:49.059] Regenerated local transaction journal    transactions=0 accounts=0
INFO [01-10|14:55:56.656] Submitted contract creation              fullhash=0xdb4b03f06fe797e424a11fa4d548c0a810e687d8154984a55c9dea33fd41302f contract=0xE201d875eCcFfD85290e41199e6ac0D9E56BEe83

window2:miner.start()
window1:开始挖矿->挖矿结束

INFO [01-10|14:55:56.656] Submitted contract creation              fullhash=0xdb4b03f06fe797e424a11fa4d548c0a810e687d8154984a55c9dea33fd41302f contract=0xE201d875eCcFfD85290e41199e6ac0D9E56BEe83
INFO [01-10|14:58:00.925] Updated mining threads                   threads=12
INFO [01-10|14:58:00.928] Transaction pool price threshold updated price=1000000000
INFO [01-10|14:58:00.937] Commit new mining work                   number=4514 sealhash=6ddd98…50ed17 uncles=0 txs=0 gas=0      fees=0           elapsed=0s
INFO [01-10|14:58:00.957] Commit new mining work                   number=4514 sealhash=a4bcfc…ba884b uncles=0 txs=1 gas=236187 fees=0.000236187 elapsed=20.053ms
INFO [01-10|14:58:09.469] Successfully sealed new block            number=4514 sealhash=a4bcfc…ba884b hash=0c5c50…4beedc elapsed=8.512s
INFO [01-10|14:58:09.473] ? block reached canonical chain          number=4507 hash=88e074…96e38c
INFO [01-10|14:58:09.485] ? mined potential block                  number=4514 hash=0c5c50…4beedc

window3:挖矿结束

...
  _b:
   { [Function: bound ]
     request: [Function: bound ],
     call: [Function: bound ],
     sendTransaction: [Function: bound ],
     estimateGas: [Function: bound ],
     getData: [Function: bound ],
     '': [Circular] },
  set:
   { [Function: bound ]
     request: [Function: bound ],
     call: [Function: bound ],
     sendTransaction: [Function: bound ],
     estimateGas: [Function: bound ],
     getData: [Function: bound ],
     '': [Circular] },
  say:
   { [Function: bound ]
     request: [Function: bound ],
     call: [Function: bound ],
     sendTransaction: [Function: bound ],
     estimateGas: [Function: bound ],
     getData: [Function: bound ],
     string: [Circular] },
  _c:
   { [Function: bound ]
     request: [Function: bound ],
     call: [Function: bound ],
     sendTransaction: [Function: bound ],
     estimateGas: [Function: bound ],
     getData: [Function: bound ],
     '': [Circular] },
  allEvents: [Function: bound ] } '0xe201d875eccffd85290e41199e6ac0d9e56bee83' '0xdb4b03f06fe797e424a11fa4d548c0a810e687d8154984a55c9dea33fd41302f
  //call.js中调用的合约地址:'0xe201d875eccffd85290e41199e6ac0d9e56bee83' 

调用合约

window3:node call.js

  _b:
   { [Function: bound ]
     request: [Function: bound ],
     call: [Function: bound ],
     sendTransaction: [Function: bound ],
     estimateGas: [Function: bound ],
     getData: [Function: bound ],
     '': [Circular] },
  set:
   { [Function: bound ]
     request: [Function: bound ],
     call: [Function: bound ],
     sendTransaction: [Function: bound ],
     estimateGas: [Function: bound ],
     getData: [Function: bound ],
     '': [Circular] },
  say:
   { [Function: bound ]
     request: [Function: bound ],
     call: [Function: bound ],
     sendTransaction: [Function: bound ],
     estimateGas: [Function: bound ],
     getData: [Function: bound ],
     string: [Circular] },
  _c:
   { [Function: bound ]
     request: [Function: bound ],
     call: [Function: bound ],
     sendTransaction: [Function: bound ],
     estimateGas: [Function: bound ],
     getData: [Function: bound ],
     '': [Circular] },
  allEvents: [Function: bound ] }
hello,my love
BigNumber { s: 1, e: 0, c: [ 7 ] }//部署合约时,对构造函数进行传输的参数
_c BigNumber { s: 1, e: 0, c: [ 3 ] }//部署合约时,对构造函数进行传输的参数,set方法需要挖矿成功之后,才对_c修改成功;再次运行node call.js会发现_c修改成了5
eilinge 0x51a984d9b05c1bc9ad518e91af3291b139d52c71b1b22e89bd3dfc6ce6ae84c0

window1–显示当前交易:

INFO [01-10|15:09:14.612] Submitted transaction                    fullhash=0xb7414a141a38292f80a080b4662a0afdb6fa433b4cbece15b3855174872d989c recipient=0xE201d875eCcFfD85290e41199e6ac0D9E56BEe83

window2–开始挖矿:miner.start()
window1–挖矿结束信息:

INFO [01-10|15:09:14.612] Submitted transaction                    fullhash=0xb7414a141a38292f80a080b4662a0afdb6fa433b4cbece15b3855174872d989c recipient=0xE201d875eCcFfD85290e41199e6ac0D9E56BEe83
INFO [01-10|15:11:58.447] Updated mining threads                   threads=12
INFO [01-10|15:11:58.450] Transaction pool price threshold updated price=1000000000
INFO [01-10|15:11:58.460] Commit new mining work                   number=4515 sealhash=ae4928…4fb444 uncles=0 txs=0 gas=0      fees=0           elapsed=0s
INFO [01-10|15:11:58.492] Commit new mining work                   number=4515 sealhash=37a302…efd3df uncles=0 txs=2 gas=53320  fees=5.332e-05   elapsed=32.084ms
INFO [01-10|15:11:58.688] Successfully sealed new block            number=4515 sealhash=37a302…efd3df hash=dd24a6…f17e8e elapsed=196.523ms
INFO [01-10|15:11:58.692] ? block reached canonical chain          number=4508 hash=dcca54…6504d0
INFO [01-10|15:11:58.699] ? mined potential block                  number=4515 hash=dd24a6…f17e8e

查看交易信息:window2

> eth.getTransaction("0x51a984d9b05c1bc9ad518e91af3291b139d52c71b1b22e89bd3dfc6ce6ae84c0")

{
  blockHash: "0xdd24a60d774249fefadb45e31062320d2692c8cbbf5d6000236436b593f17e8e",
  blockNumber: 4515,
  from: "0x436ef52588b8c2fb1ee14844afe94bb78a4072b7",
  gas: 100000,
  gasPrice: 1000000000,
  hash: "0x51a984d9b05c1bc9ad518e91af3291b139d52c71b1b22e89bd3dfc6ce6ae84c0",
  input: "0xb8e010de",
  nonce: 65,
  r: "0xeb0107ed8884d97303937c8cedd7352424bd9eadd860520f288a2b08ae48001b",
  s: "0x3e9e550c6f1a2f0dc8e8ed54622dc24a446ca0495503abf5bb4ae60931a4bf57",
  to: "0x00ede8b236d83909f5b9888686296df6e9cc4d77",
  transactionIndex: 0,
  v: "0x2a",
  value: 0
}

> eth.getBlock(4517)

{
  difficulty: 6707532,
  extraData: "0xda8301080c846765746888676f312e31302e338777696e646f7773",
  gasLimit: 4712388,
  gasUsed: 0,
  hash: "0x8d29b5f3c28641bd2936c74272db9d6d348ebc3ba992928519cc590b7fb071f9",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x436ef52588b8c2fb1ee14844afe94bb78a4072b7",
  mixHash: "0x2b8e232dad56941985057fda7339eb23260b3e2f1a7694c3ba5fa7252608b836",
  nonce: "0x34cd5b72294a43f0",
  number: 4517,
  parentHash: "0xa8d07c850109824910d0b45f36ec6879c3c516f666ff06bb108cc291e7d0e940",
  receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 540,
  stateRoot: "0x59deb328110a944f3336882ceae206a3e9d0f64dc62ff439f5dce8c66829398a",
  timestamp: 1541514003,
  totalDifficulty: 14755003421,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}

> eth.getCode("0x00ede8b236d83909f5b9888686296df6e9cc4d77")

"0x608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680632537499614610064578063b8e010de1461008f578063d5c61301146100a6578063f5376e0314610188575b005b34801561007057600080fd5b506100796101b3565b6040518082815260200191505060405180910390f35b34801561009b57600080fd5b506100a46101b9565b005b3480156100b257600080fd5b5061010d600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101cb565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561014d578082015181840152602081019050610132565b50505050905090810190601f16801561017a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561019457600080fd5b5061019d6101d5565b6040518082815260200191505060405180910390f35b60015481565b60026000808282540192505081905550565b6060819050919050565b600054815600a165627a7a723058205063e6870296aed82f6772d1ce86e55ae0c55b1ee0b1c269aaf8b9ddaaf794890029"

区块链eth.大家自己多尝试下,与web3 rpc api的调用方式一样

eth._requestManager            eth.getBlockUncleCount         eth.getWork
eth.accounts                   eth.getCode                    eth.hashrate
eth.blockNumber                eth.getCoinbase                eth.iban
eth.call                       eth.getCompilers               eth.icapNamereg
eth.coinbase                   eth.getGasPrice                eth.isSyncing
eth.compile                    eth.getHashrate                eth.mining
eth.constructor                eth.getMining                  eth.namereg
eth.contract                   eth.getPendingTransactions     eth.pendingTransactions
eth.defaultAccount             eth.getProtocolVersion         eth.protocolVersion
eth.defaultBlock               eth.getRawTransaction          eth.resend
eth.estimateGas                eth.getRawTransactionFromBlock eth.sendIBANTransaction
eth.filter                     eth.getStorageAt               eth.sendRawTransaction
eth.gasPrice                   eth.getSyncing                 eth.sendTransaction
eth.getAccounts                eth.getTransaction             eth.sign
eth.getBalance                 eth.getTransactionCount        eth.signTransaction
eth.getBlock                   eth.getTransactionFromBlock    eth.submitTransaction
eth.getBlockNumber             eth.getTransactionReceipt      eth.submitWork
eth.getBlockTransactionCount   eth.getUncle                   eth.syncing

矿工:miner.

miner.constructor          miner.propertyIsEnumerable miner.setRecommitInterval  miner.toString
miner.getHashrate          miner.setEtherbase         miner.start                miner.valueOf
miner.hasOwnProperty       miner.setExtra             miner.stop
miner.isPrototypeOf        miner.setGasPrice          miner.toLocaleString

网络:net.

net._requestManager net.getListening    net.getVersion      net.peerCount
net.constructor     net.getPeerCount    net.listening       net.version

账户:personal.

personal._requestManager personal.getListAccounts personal.listWallets     personal.sendTransaction
personal.constructor     personal.getListWallets  personal.lockAccount     personal.sign
personal.deriveAccount   personal.importRawKey    personal.newAccount      personal.signTransaction
personal.ecRecover       personal.listAccounts    personal.openWallet      personal.unlockAccount

交易池:txpool.

txpool.constructor          txpool.getStatus            txpool.propertyIsEnumerable txpool.valueOf
txpool.content              txpool.hasOwnProperty       txpool.status
txpool.getContent           txpool.inspect              txpool.toLocaleString
txpool.getInspect           txpool.isPrototypeOf        txpool.toString

温馨提示

我也是在学习区块链的路上,很多方法都需要自己去尝试,希望自己不要放弃
参考博客
web3.js Api

你可能感兴趣的:(区块链)