刚开始接触区块链,就是跟着网上资料逐步搭建自己的私链和部署hello world,所以给我的印象就是–geth就只能干干搭建私链,管理账户和部署简单合约。
然而,当我了解完以太坊原理和机制之后,就在想区块链上的交易信息,区块,账户信息在哪实现的…
为了查看运行逻辑,需要开启3个窗口
window1:区块的信息显示(只读)
window2:挖矿的实现(操作eth)
window3:部署合约,实现与区块链的交互,显示合约信息(node,web3)
搭建私有链:
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
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
> 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