1、查看该账号目前发起的交易数量:
> eth.getTransactionCount(eth.accounts[0])
2
2、通过交易ID查看堵塞的交易nonce:
> eth.getTransaction("0x6db14bb72145761a90f06c3cc7843803b7750750c12b9c029ef6a701a3cc8de6")
{
from: "0x61863ab78fbd4b889de008594403e74876e00855",
gas: 3000000,
gasPrice: 1000000000,
nonce: 3,
...
}
3、此交易的nonce=3>2,因此该交易会等待交易2完成,所以我们可以增加gas费用让交易2提速完成,或者取消交易2,注意,取消交易也是需要时间的。
4、有时候找不到交易2是在哪里发起的,有可能交易2只是占用了nonce却没有广播出去,这样就永远堵塞了。如果只是一个在私链上不重要的交易,可以直接重启geth即可重置一些数据。(交易处于queued中时,停止geth客户端,交易queued中的交易会被清除掉。)
5、最根本的解决方案是使用正确的nonce创建每一笔交易,使用统一维护的nonce获取接口,并且仅使用此方式获取,以免因使用了其它方式,导致nonce错乱。(具体的nonce获取接口实现在将来实际使用时再补上,暂不深入研究了。)
使用Remix IDE 编写、编译、部署、调用
使用MetaMask 切换要连接的用户
Ballot.sol:
pragma solidity ^0.6.0;
contract Ballot {
struct Voter {
uint weight;
bool voted;
address delegate;
uint vote;
}
struct Proposal {
bytes32 name;
uint voteCount;
}
address public chairperson;
mapping(address => Voter) public voters;
Proposal[] public proposals;
constructor(bytes32[] memory proposalNames) public {
chairperson = msg.sender;
voters[chairperson].weight = 1;
for(uint i = 0;i < proposalNames.length;i++){
proposals.push(Proposal({
name:proposalNames[i],
voteCount:0
}));
}
}
function giveRightToVote(address voter) public{
require(
msg.sender == chairperson,
"Only chairperson can give right to vote.");
require(!voters[voter].voted,
"The voter already voted");
require(voters[voter].weight==0);
voters[voter].weight=1;
}
function delegate(address to) public{
Voter storage sender = voters[msg.sender];
require(!sender.voted,"You already voted.");
require(to!=msg.sender,"Self-delegation is disallowed.");
while(voters[to].delegate!=address(0)){
to = voters[to].delegate;
require(to!=msg.sender);
}
sender.voted = true;
// find last
sender.delegate = to;
Voter storage delegate_ = voters[to];
if(delegate_.voted){
// sum
proposals[delegate_.vote].voteCount + sender.weight;
}else{
delegate_.weight += sender.weight;
}
}
function vote(uint proposal) public {
Voter storage sender = voters[msg.sender];
require(!sender.voted,"You already voted.");
sender.voted = true;
sender.vote = proposal;
proposals[proposal].voteCount+=sender.weight;
}
function winningProposal() public view returns(uint winningProposal_){
uint winnigVoteCount = 0;
for(uint p = 0;p < proposals.length;p++){
if(proposals[p].voteCount>winnigVoteCount){
winnigVoteCount = proposals[p].voteCount;
winningProposal_ = p;
}
}
}
function winnerName() public view returns(bytes32 winnerName_){
winnerName_ = proposals[winningProposal()].name;
}
}
要点一:构造方法,部署前的传入提案名称:
["0x0000000000000000000000000000000000000000000000000000000000000005",
"0x0000000000000000000000000000000000000000000000000000000000000020",
"0x0000000000000000000000000000000000000000000000000000000000000100"]
要点二:部署者为主席,发放投票资格
要点三:投票给提案,传参为提案索引,而不是提案名称
提案5的索引为0:0x0000000000000000000000000000000000000000000000000000000000000000
提案20的索引为1:0x0000000000000000000000000000000000000000000000000000000000000001
提案100的索引为2:0x0000000000000000000000000000000000000000000000000000000000000002
要点四:使用MetaMask切换连接的用户,进行投票
两个投票给索引1的提案,一个账户投票给索引2的提案,因此胜出的提案索引为1,如下:
decoded output {
"0": "uint256: winningProposal_ 1"
}
胜出的提案名称为20,如下:
decoded output {
"0": "bytes32: winnerName_ 0x0000000000000000000000000000000000000000000000000000000000000020"
}
创建账户
> personal.newAccount()
解锁账户
> personal.unlockAccount(eth.accounts[0])
修改矿工账户,挖矿收入账户
> miner.setEtherbase(eth.accounts[1])
发起转账交易
> eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],,value:web3.toWei(25,'ether')})
查询本地账户
> eth.accounts
查询账户余额,单位转以太币
> web3.fromWei(eth.getBalance(eth.accounts[0]),'ether')
查看交易池状态
> txpool.status
查看区块数目
> eth.blockNumber
查看交易详情
> eth.getTransaction("xxx")
查看交易在区块中的详细信息,包括合约部署后的地址信息
> eth.getTransactionReceipt("xxx")
查看区块
> eth.getBlock(10)
查看同步情况
> eth.syncing
开始挖矿,可指定线程数
> miner.start(1)
停止挖矿
> miner.stop()
查看节点的encode url:
> admin.nodeInfo.enode
添加节点
> admin.addPeer("enode://xxx")
后台运行geth
nohup geth --datadir chaindata --port 30303 --networkid 1108 --identity "node1" --rpc --rpcaddr 192.168.78.102 --rpcport 9545 --allow-insecure-unlock --rpccorsdomain "*" > out.log &
运行geth后,可使用以下命令进入console
geth attach ./chaindata/geth.ipc