From aa06d56b984658167f1bd891ad33ed9eabeed8e2 Mon Sep 17 00:00:00 2001 From: Nguyen Sy Thanh Son Date: Thu, 12 Jul 2018 08:15:29 +0000 Subject: [PATCH] log contract code for debug and genensis generator --- accounts/abi/bind/backends/simulated.go | 13 ++ contracts/blocksigner/blocksigner_test.go | 12 ++ contracts/randomize/randomize_test.go | 18 ++- .../validator/contract/TomoValidator.sol | 71 +++++--- contracts/validator/contract/validator.go | 152 +++++++++++++++--- contracts/validator/validator.go | 6 +- contracts/validator/validator_test.go | 18 ++- 7 files changed, 239 insertions(+), 51 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 2b5c5fc4a4..10e16d5ec9 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -157,6 +157,19 @@ func (b *SimulatedBackend) StorageAt(ctx context.Context, contract common.Addres return val[:], nil } +// ForEachStorageAt returns func to read all keys, values in the storage +func (b *SimulatedBackend) ForEachStorageAt(ctx context.Context, contract common.Address, blockNumber *big.Int, f func(key, val common.Hash) bool) error { + b.mu.Lock() + defer b.mu.Unlock() + + if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { + return errBlockNumberUnsupported + } + statedb, _ := b.blockchain.State() + statedb.ForEachStorage(contract, f) + return nil +} + // TransactionReceipt returns the receipt of a transaction. func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { receipt, _, _, _ := core.GetReceipt(b.database, txHash) diff --git a/contracts/blocksigner/blocksigner_test.go b/contracts/blocksigner/blocksigner_test.go index 16c6128aba..6bbdadfe6f 100644 --- a/contracts/blocksigner/blocksigner_test.go +++ b/contracts/blocksigner/blocksigner_test.go @@ -1,8 +1,10 @@ package blocksigner import ( + "context" "math/big" "testing" + "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" @@ -25,6 +27,16 @@ func TestBlockSigner(t *testing.T) { } contractBackend.Commit() + d := time.Now().Add(1000 * time.Millisecond) + ctx, _ := context.WithDeadline(context.Background(), d) + code, _ := contractBackend.CodeAt(ctx, blockSignerAddress, nil) + t.Log("contract code", common.ToHex(code)) + f := func(key, val common.Hash) bool { + t.Log(key.Hex(), val.Hex()) + return true + } + contractBackend.ForEachStorageAt(ctx, blockSignerAddress, nil, f) + signers, err := blockSigner.GetSigners(big.NewInt(0)) if err != nil { t.Fatalf("can't get candidates: %v", err) diff --git a/contracts/randomize/randomize_test.go b/contracts/randomize/randomize_test.go index 76ca30fb96..275e081721 100644 --- a/contracts/randomize/randomize_test.go +++ b/contracts/randomize/randomize_test.go @@ -1,11 +1,14 @@ package randomize import ( + "context" "math/big" "testing" + "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/crypto" ) @@ -20,16 +23,27 @@ func TestRandomize(t *testing.T) { contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}) transactOpts := bind.NewKeyedTransactor(key) - _, randomize, err := DeployRandomize(transactOpts, contractBackend) + randomizeAddress, randomize, err := DeployRandomize(transactOpts, contractBackend) + t.Log("contract address", randomizeAddress.String()) if err != nil { t.Fatalf("can't deploy root registry: %v", err) } contractBackend.Commit() + d := time.Now().Add(1000 * time.Millisecond) + ctx, _ := context.WithDeadline(context.Background(), d) + code, _ := contractBackend.CodeAt(ctx, randomizeAddress, nil) + t.Log("contract code", common.ToHex(code)) + f := func(key, val common.Hash) bool { + t.Log(key.Hex(), val.Hex()) + return true + } + contractBackend.ForEachStorageAt(ctx, randomizeAddress, nil, f) + s, err := randomize.SetSecret(byte0) if err != nil { t.Fatalf("can't get secret: %v", err) } - t.Log("secret", s) + t.Log("tx data", s) contractBackend.Commit() } diff --git a/contracts/validator/contract/TomoValidator.sol b/contracts/validator/contract/TomoValidator.sol index 84b3450bc0..20b79c2853 100644 --- a/contracts/validator/contract/TomoValidator.sol +++ b/contracts/validator/contract/TomoValidator.sol @@ -11,7 +11,7 @@ contract TomoValidator is IValidator { event Propose(address _owner, address _candidate, uint256 _cap); event Resign(address _owner, address _candidate); event SetNodeUrl(address _owner, address _candidate, string _nodeUrl); - event Withdraw(address _owner, address _candidate, uint256 _cap); + event Withdraw(address _owner, uint256 _blockNumber, uint256 _cap); struct ValidatorState { address owner; @@ -22,6 +22,13 @@ contract TomoValidator is IValidator { mapping(address => uint256) voters; } + struct WithdrawState { + mapping(uint256 => uint256) caps; + uint256[] blockNumbers; + } + + mapping(address => WithdrawState) withdrawsState; + mapping(address => ValidatorState) validatorsState; mapping(address => address[]) voters; address[] public candidates = [ @@ -29,10 +36,13 @@ contract TomoValidator is IValidator { 0x31b249fE6F267aa2396Eb2DC36E9c79351d97Ec5, 0xfC5571921c6d3672e13B58EA23DEA534f2b35fA0 ]; - uint256 candidateCount = 3; + + address public firstOwner = 0x487d62d33467c4842c5e54Eb370837E4E88BBA0F; + uint256 public candidateCount = 3; uint256 public minCandidateCap; uint256 public maxValidatorNumber; - uint256 public candidateWithdrawDelay; // blocks + uint256 public candidateWithdrawDelay; + uint256 public voterWithdrawDelay; modifier onlyValidCandidateCap { // anyone can deposit X TOMO to become a candidate @@ -50,12 +60,6 @@ contract TomoValidator is IValidator { _; } - modifier onlyAlreadyResigned(address _candidate) { - require(validatorsState[_candidate].withdrawBlockNumber > 0); - require(block.number >= validatorsState[_candidate].withdrawBlockNumber); - _; - } - modifier onlyValidCandidate (address _candidate) { require(validatorsState[_candidate].isCandidate); _; @@ -71,23 +75,35 @@ contract TomoValidator is IValidator { _; } + modifier onlyValidWithdraw (uint256 _blockNumber, uint _index) { + require(_blockNumber > 0); + require(block.number >= _blockNumber); + require(withdrawsState[msg.sender].caps[_blockNumber] > 0); + require(withdrawsState[msg.sender].blockNumbers[_index] == _blockNumber); + _; + } + function TomoValidator ( uint256 _minCandidateCap, uint256 _maxValidatorNumber, - uint256 _candidateWithdrawDelay + uint256 _candidateWithdrawDelay, + uint256 _voterWithdrawDelay ) public { minCandidateCap = _minCandidateCap; maxValidatorNumber = _maxValidatorNumber; candidateWithdrawDelay = _candidateWithdrawDelay; + voterWithdrawDelay = _voterWithdrawDelay; for (uint256 i = 0; i < candidates.length; i++) { validatorsState[candidates[i]] = ValidatorState({ - owner: 0x487d62d33467c4842c5e54Eb370837E4E88BBA0F, + owner: firstOwner, nodeUrl: '', isCandidate: true, withdrawBlockNumber: 0, cap: minCandidateCap }); + voters[candidates[i]].push(firstOwner); + validatorsState[candidates[i]].voters[firstOwner] = minCandidateCap; } } @@ -102,6 +118,7 @@ contract TomoValidator is IValidator { }); validatorsState[_candidate].voters[msg.sender] = msg.value; candidateCount = candidateCount + 1; + voters[_candidate].push(_candidate); emit Propose(msg.sender, _candidate, msg.value); } @@ -146,11 +163,19 @@ contract TomoValidator is IValidator { return validatorsState[_candidate].isCandidate; } + function getWithdrawBlockNumbers() public view returns(uint256[]) { + return withdrawsState[msg.sender].blockNumbers; + } + function unvote(address _candidate, uint256 _cap) public onlyValidVote(_candidate, _cap) { validatorsState[_candidate].cap = validatorsState[_candidate].cap.sub(_cap); validatorsState[_candidate].voters[msg.sender] = validatorsState[_candidate].voters[msg.sender].sub(_cap); - // refunding to user after unvoting - msg.sender.transfer(_cap); + + // refund after delay X blocks + uint256 withdrawBlockNumber = voterWithdrawDelay.add(block.number); + withdrawsState[msg.sender].caps[withdrawBlockNumber] = withdrawsState[msg.sender].caps[withdrawBlockNumber].add(_cap); + withdrawsState[msg.sender].blockNumbers.push(withdrawBlockNumber); + emit Unvote(msg.sender, _candidate, _cap); } @@ -168,17 +193,21 @@ contract TomoValidator is IValidator { break; } } - // refunding after retiring X blocks - validatorsState[_candidate].withdrawBlockNumber = validatorsState[_candidate].withdrawBlockNumber.add(block.number).add(candidateWithdrawDelay); - emit Resign(msg.sender, _candidate); - } - - function withdraw(address _candidate) public onlyOwner(_candidate) onlyNotCandidate(_candidate) onlyAlreadyResigned(_candidate) { uint256 cap = validatorsState[_candidate].voters[msg.sender]; validatorsState[_candidate].cap = validatorsState[_candidate].cap.sub(cap); validatorsState[_candidate].voters[msg.sender] = 0; - validatorsState[_candidate].withdrawBlockNumber = 0; + // refunding after retiring X blocks + uint256 withdrawBlockNumber = candidateWithdrawDelay.add(block.number); + withdrawsState[msg.sender].caps[withdrawBlockNumber] = withdrawsState[msg.sender].caps[withdrawBlockNumber].add(cap); + withdrawsState[msg.sender].blockNumbers.push(withdrawBlockNumber); + emit Resign(msg.sender, _candidate); + } + + function withdraw(uint256 _blockNumber, uint _index) public onlyValidWithdraw(_blockNumber, _index) { + uint256 cap = withdrawsState[msg.sender].caps[_blockNumber]; + delete withdrawsState[msg.sender].caps[_blockNumber]; + delete withdrawsState[msg.sender].blockNumbers[_index]; msg.sender.transfer(cap); - emit Withdraw(msg.sender, _candidate, cap); + emit Withdraw(msg.sender, _blockNumber, cap); } } diff --git a/contracts/validator/contract/validator.go b/contracts/validator/contract/validator.go index c3af56acd7..3f69d6c521 100644 --- a/contracts/validator/contract/validator.go +++ b/contracts/validator/contract/validator.go @@ -380,18 +380,18 @@ func (_SafeMath *SafeMathTransactorRaw) Transact(opts *bind.TransactOpts, method } // TomoValidatorABI is the input ABI used to generate the binding from. -const TomoValidatorABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"},{\"name\":\"_cap\",\"type\":\"uint256\"}],\"name\":\"unvote\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getCandidates\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"getCandidateWithdrawBlockNumber\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"getVoters\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"},{\"name\":\"_voter\",\"type\":\"address\"}],\"name\":\"getVoterCap\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"candidates\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"getCandidateCap\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"vote\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"},{\"name\":\"_nodeUrl\",\"type\":\"string\"}],\"name\":\"setNodeUrl\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"resign\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"getCandidateOwner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxValidatorNumber\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"candidateWithdrawDelay\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"isCandidate\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minCandidateCap\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"},{\"name\":\"_nodeUrl\",\"type\":\"string\"}],\"name\":\"propose\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"getCandidateNodeUrl\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_minCandidateCap\",\"type\":\"uint256\"},{\"name\":\"_maxValidatorNumber\",\"type\":\"uint256\"},{\"name\":\"_candidateWithdrawDelay\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_voter\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_candidate\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_cap\",\"type\":\"uint256\"}],\"name\":\"Vote\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_voter\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_candidate\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_cap\",\"type\":\"uint256\"}],\"name\":\"Unvote\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_candidate\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_cap\",\"type\":\"uint256\"}],\"name\":\"Propose\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"Resign\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_candidate\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_nodeUrl\",\"type\":\"string\"}],\"name\":\"SetNodeUrl\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_candidate\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_cap\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"}]" +const TomoValidatorABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"},{\"name\":\"_cap\",\"type\":\"uint256\"}],\"name\":\"unvote\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getCandidates\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"getCandidateWithdrawBlockNumber\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"getVoters\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getWithdrawBlockNumbers\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"},{\"name\":\"_voter\",\"type\":\"address\"}],\"name\":\"getVoterCap\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"candidates\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_blockNumber\",\"type\":\"uint256\"},{\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"getCandidateCap\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"firstOwner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"vote\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"},{\"name\":\"_nodeUrl\",\"type\":\"string\"}],\"name\":\"setNodeUrl\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"candidateCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"voterWithdrawDelay\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"resign\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"getCandidateOwner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxValidatorNumber\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"candidateWithdrawDelay\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"isCandidate\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minCandidateCap\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"},{\"name\":\"_nodeUrl\",\"type\":\"string\"}],\"name\":\"propose\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"getCandidateNodeUrl\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_minCandidateCap\",\"type\":\"uint256\"},{\"name\":\"_maxValidatorNumber\",\"type\":\"uint256\"},{\"name\":\"_candidateWithdrawDelay\",\"type\":\"uint256\"},{\"name\":\"_voterWithdrawDelay\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_voter\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_candidate\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_cap\",\"type\":\"uint256\"}],\"name\":\"Vote\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_voter\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_candidate\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_cap\",\"type\":\"uint256\"}],\"name\":\"Unvote\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_candidate\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_cap\",\"type\":\"uint256\"}],\"name\":\"Propose\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"Resign\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_candidate\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_nodeUrl\",\"type\":\"string\"}],\"name\":\"SetNodeUrl\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_blockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"_cap\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"}]" // TomoValidatorBin is the compiled bytecode used for deploying new contracts. -const TomoValidatorBin = `0x60606040526060604051908101604090815273f99805b536609cc03acbb2604dfac11e9e54a44882527331b249fe6f267aa2396eb2dc36e9c79351d97ec5602083015273fc5571921c6d3672e13b58ea23dea534f2b35fa0908201526200006b906002906003620001cc565b506003805534156200007c57600080fd5b6040516060806200149a8339810160405280805191906020018051919060200180516004859055600584905560068190559150600090505b600254811015620001c25760a06040519081016040528073487d62d33467c4842c5e54eb370837e4e88bba0f600160a060020a0316815260200160206040519081016040528060008152508152602001600115158152602001600454815260200160008152506000806002848154811015156200012d57fe5b6000918252602080832090910154600160a060020a03168352820192909252604001902081518154600160a060020a031916600160a060020a03919091161781556020820151816001019080516200018a92916020019062000238565b50604082015160028201805460ff191691151591909117905560608201518160030155608082015160049091015550600101620000b4565b5050505062000300565b82805482825590600052602060002090810192821562000226579160200282015b82811115620002265782518254600160a060020a031916600160a060020a039190911617825560209290920191600190910190620001ed565b5062000234929150620002b9565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200027b57805160ff1916838001178555620002ab565b82800160010185558215620002ab579182015b82811115620002ab5782518255916020019190600101906200028e565b5062000234929150620002e3565b620002e091905b8082111562000234578054600160a060020a0319168155600101620002c0565b90565b620002e091905b80821115620002345760008155600101620002ea565b61118a80620003106000396000f3006060604052600436106100fb5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166302aa9be2811461010057806306a49fce14610124578063282652941461018a5780632d15cc04146101bb578063302b6872146101da5780633477ee2e146101ff57806351cff8d91461023157806358e7525f146102505780636dd7d8ea1461026f578063a3ec796514610283578063ae6e43f5146102e2578063b642facd14610301578063d09f1ab414610320578063d161c76714610333578063d51b9e9314610346578063d55b7dff14610379578063d6f0948c1461038c578063da67b599146103ac575b600080fd5b341561010b57600080fd5b610122600160a060020a0360043516602435610442565b005b341561012f57600080fd5b61013761059a565b60405160208082528190810183818151815260200191508051906020019060200280838360005b8381101561017657808201518382015260200161015e565b505050509050019250505060405180910390f35b341561019557600080fd5b6101a9600160a060020a0360043516610603565b60405190815260200160405180910390f35b34156101c657600080fd5b610137600160a060020a0360043516610621565b34156101e557600080fd5b6101a9600160a060020a03600435811690602435166106ae565b341561020a57600080fd5b6102156004356106db565b604051600160a060020a03909116815260200160405180910390f35b341561023c57600080fd5b610122600160a060020a0360043516610703565b341561025b57600080fd5b6101a9600160a060020a03600435166108b4565b610122600160a060020a03600435166108d2565b341561028e57600080fd5b61012260048035600160a060020a03169060446024803590810190830135806020601f82018190048102016040519081016040528181529291906020840183838082843750949650610a7c95505050505050565b34156102ed57600080fd5b610122600160a060020a0360043516610b8c565b341561030c57600080fd5b610215600160a060020a0360043516610d4e565b341561032b57600080fd5b6101a9610d6c565b341561033e57600080fd5b6101a9610d72565b341561035157600080fd5b610365600160a060020a0360043516610d78565b604051901515815260200160405180910390f35b341561038457600080fd5b6101a9610d99565b61012260048035600160a060020a03169060248035908101910135610d9f565b34156103b757600080fd5b6103cb600160a060020a0360043516610f9e565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156104075780820151838201526020016103ef565b50505050905090810190601f1680156104345780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600160a060020a03808316600090815260208181526040808320339094168352600590930190522054829082908190101561047c57600080fd5b600160a060020a0384166000908152602081905260409020600301546104a8908463ffffffff61106316565b600160a060020a03808616600090815260208181526040808320600381019590955533909316825260059093019092529020546104eb908463ffffffff61106316565b600160a060020a0380861660009081526020818152604080832033909416808452600590940190915290819020929092559084156108fc0290859051600060405180830381858888f19350505050151561054457600080fd5b7faa0e554f781c3c3b2be110a0557f260f11af9a8aa2c64bc1e7a31dbb21e32fa2338585604051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a150505050565b6105a261108b565b60028054806020026020016040519081016040528092919081815260200182805480156105f857602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116105da575b505050505090505b90565b600160a060020a031660009081526020819052604090206004015490565b61062961108b565b6001600083600160a060020a0316600160a060020a031681526020019081526020016000208054806020026020016040519081016040528092919081815260200182805480156106a257602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610684575b50505050509050919050565b600160a060020a039182166000908152602081815260408083209390941682526005909201909152205490565b60028054829081106106e957fe5b600091825260209091200154600160a060020a0316905081565b600160a060020a038181166000908152602081905260408120549091839133821691161461073057600080fd5b600160a060020a038316600090815260208190526040902060020154839060ff161561075b57600080fd5b600160a060020a0384166000908152602081905260408120600401548591901161078457600080fd5b600160a060020a0381166000908152602081905260409020600401544310156107ac57600080fd5b600160a060020a03808616600081815260208181526040808320339095168352600585018252822054928252526003909101549094506107f2908563ffffffff61106316565b600160a060020a0380871660008181526020818152604080832060038101969096553390941680835260058601825284832083905592825281905260049093019290925585156108fc0290869051600060405180830381858888f19350505050151561085d57600080fd5b7f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb338686604051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a15050505050565b600160a060020a031660009081526020819052604090206003015490565b600160a060020a038116600090815260208190526040902060020154819060ff1615156108fe57600080fd5b600160a060020a03821660009081526020819052604090206003015461092a903463ffffffff61107516565b600160a060020a038084166000908152602081815260408083206003810195909555339093168252600590930190925290205415156109c157600160a060020a038216600090815260016020819052604090912080549091810161098e838261109d565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff191633600160a060020a03161790555b600160a060020a038083166000908152602081815260408083203390941683526005909301905220546109fa903463ffffffff61107516565b600160a060020a0380841660009081526020818152604080832033948516845260050190915290819020929092557f66a9138482c99e9baf08860110ef332cc0c23b4a199a53593d8db0fc8f96fbfc918490349051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a15050565b600160a060020a038281166000908152602081905260409020548391338116911614610aa757600080fd5b600160a060020a0383166000908152602081905260409020600101828051610ad39291602001906110c6565b507f63f303264cd4b7a198f0163f96e0b6b1f972f9b73359a70c44241b862879d8a4338484604051600160a060020a0380851682528316602082015260606040820181815290820183818151815260200191508051906020019080838360005b83811015610b4b578082015183820152602001610b33565b50505050905090810190601f168015610b785780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a1505050565b600160a060020a0381811660009081526020819052604081205490918391338216911614610bb957600080fd5b600160a060020a038316600090815260208190526040902060020154839060ff161515610be557600080fd5b600160a060020a0384166000908152602081905260408120600201805460ff191690556003805460001901905592505b600254831015610c975783600160a060020a0316600284815481101515610c3857fe5b600091825260209091200154600160a060020a03161415610c8c576002805484908110610c6157fe5b6000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff19169055610c97565b600190920191610c15565b600654600160a060020a038516600090815260208190526040902060040154610cd79190610ccb904363ffffffff61107516565b9063ffffffff61107516565b60008086600160a060020a0316600160a060020a03168152602001908152602001600020600401819055507f4edf3e325d0063213a39f9085522994a1c44bea5f39e7d63ef61260a1e58c6d33385604051600160a060020a039283168152911660208201526040908101905180910390a150505050565b600160a060020a039081166000908152602081905260409020541690565b60055481565b60065481565b600160a060020a031660009081526020819052604090206002015460ff1690565b60045481565b600454341015610dae57600080fd5b600160a060020a038316600090815260208190526040902060020154839060ff1615610dd957600080fd5b6002805460018101610deb838261109d565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03861617905560a06040519081016040528033600160a060020a0316815260200184848080601f0160208091040260200160405190810160405281815292919060208401838380828437505050928452505060016020808401919091523460408085019190915260006060909401849052600160a060020a03891684529083905290912090508151815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0391909116178155602082015181600101908051610ee19291602001906110c6565b50604082015160028201805460ff191691151591909117905560608201518160030155608082015160049091015550600160a060020a038085166000908152602081815260408083203394851684526005019091529081902034908190556003805460010190557f7635f1d87b47fba9f2b09e56eb4be75cca030e0cb179c1602ac9261d39a8f5c1929187919051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a150505050565b610fa661108b565b60008083600160a060020a0316600160a060020a031681526020019081526020016000206001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156106a25780601f10611036576101008083540402835291602001916106a2565b820191906000526020600020905b8154815290600101906020018083116110445750939695505050505050565b60008282111561106f57fe5b50900390565b60008282018381101561108457fe5b9392505050565b60206040519081016040526000815290565b8154818355818115116110c1576000838152602090206110c1918101908301611144565b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061110757805160ff1916838001178555611134565b82800160010185558215611134579182015b82811115611134578251825591602001919060010190611119565b50611140929150611144565b5090565b61060091905b80821115611140576000815560010161114a5600a165627a7a72305820643a4d877b1248c19e7e8749d7279654d953dd5ebfd06be341ab10da6ae4d4d70029` +const TomoValidatorBin = `0x60606040526060604051908101604090815273f99805b536609cc03acbb2604dfac11e9e54a44882527331b249fe6f267aa2396eb2dc36e9c79351d97ec5602083015273fc5571921c6d3672e13b58ea23dea534f2b35fa0908201526200006a9060039081620002bb565b5060048054600160a060020a03191673487d62d33467c4842c5e54eb370837e4e88bba0f17905560036005553415620000a257600080fd5b604051608080620017ec8339810160405280805191906020018051919060200180519190602001805160068690556007859055600884905560098190559150600090505b600354811015620002b05760a06040519081016040908152600454600160a060020a0316825260208083019151908101604052806000815250815260200160011515815260200160065481526020016000815250600160006003848154811015156200014e57fe5b6000918252602080832090910154600160a060020a03168352820192909252604001902081518154600160a060020a031916600160a060020a0391909116178155602082015181600101908051620001ab92916020019062000327565b50604082015160028201805460ff1916911515919091179055606082015181600301556080820151816004015590505060026000600383815481101515620001ef57fe5b6000918252602080832090910154600160a060020a031683528201929092526040019020805460018101620002258382620003a8565b5060009182526020822060045491018054600160a060020a031916600160a060020a03909216919091179055600654600380549192600192909190859081106200026b57fe5b6000918252602080832090910154600160a060020a039081168452838201949094526040928301822060045490941682526005909301909252902055600101620000e6565b50505050506200041b565b82805482825590600052602060002090810192821562000315579160200282015b82811115620003155782518254600160a060020a031916600160a060020a039190911617825560209290920191600190910190620002dc565b5062000323929150620003d4565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200036a57805160ff19168380011785556200039a565b828001600101855582156200039a579182015b828111156200039a5782518255916020019190600101906200037d565b5062000323929150620003fe565b815481835581811511620003cf57600083815260209020620003cf918101908301620003fe565b505050565b620003fb91905b8082111562000323578054600160a060020a0319168155600101620003db565b90565b620003fb91905b8082111562000323576000815560010162000405565b6113c1806200042b6000396000f3006060604052600436106101275763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166302aa9be2811461012c57806306a49fce1461015057806328265294146101b65780632d15cc04146101e75780632f9c4bba14610206578063302b6872146102195780633477ee2e1461023e578063441a3e701461027057806358e7525f146102895780636bc28781146102a85780636dd7d8ea146102bb578063a3ec7965146102cf578063a9a981a31461032e578063a9ff959e14610341578063ae6e43f514610354578063b642facd14610373578063d09f1ab414610392578063d161c767146103a5578063d51b9e93146103b8578063d55b7dff146103eb578063d6f0948c146103fe578063da67b5991461041e575b600080fd5b341561013757600080fd5b61014e600160a060020a03600435166024356104b4565b005b341561015b57600080fd5b61016361067c565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156101a257808201518382015260200161018a565b505050509050019250505060405180910390f35b34156101c157600080fd5b6101d5600160a060020a03600435166106e5565b60405190815260200160405180910390f35b34156101f257600080fd5b610163600160a060020a0360043516610703565b341561021157600080fd5b610163610790565b341561022457600080fd5b6101d5600160a060020a0360043581169060243516610812565b341561024957600080fd5b610254600435610841565b604051600160a060020a03909116815260200160405180910390f35b341561027b57600080fd5b61014e600435602435610869565b341561029457600080fd5b6101d5600160a060020a03600435166109d0565b34156102b357600080fd5b6102546109ee565b61014e600160a060020a03600435166109fd565b34156102da57600080fd5b61014e60048035600160a060020a03169060446024803590810190830135806020601f82018190048102016040519081016040528181529291906020840183838082843750949650610baa95505050505050565b341561033957600080fd5b6101d5610cbb565b341561034c57600080fd5b6101d5610cc1565b341561035f57600080fd5b61014e600160a060020a0360043516610cc7565b341561037e57600080fd5b610254600160a060020a0360043516610f3a565b341561039d57600080fd5b6101d5610f58565b34156103b057600080fd5b6101d5610f5e565b34156103c357600080fd5b6103d7600160a060020a0360043516610f64565b604051901515815260200160405180910390f35b34156103f657600080fd5b6101d5610f85565b61014e60048035600160a060020a03169060248035908101910135610f8b565b341561042957600080fd5b61043d600160a060020a03600435166111d4565b60405160208082528190810183818151815260200191508051906020019080838360005b83811015610479578082015183820152602001610461565b50505050905090810190601f1680156104a65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600160a060020a038083166000908152600160209081526040808320339094168352600590930190529081205483908390819010156104f257600080fd5b600160a060020a03851660009081526001602052604090206003015461051e908563ffffffff61129a16565b600160a060020a03808716600090815260016020908152604080832060038101959095553390931682526005909301909252902054610563908563ffffffff61129a16565b600160a060020a0380871660009081526001602090815260408083203390941683526005909301905220556009546105a1904363ffffffff6112ac16565b600160a060020a0333166000908152602081815260408083208484529091529020549093506105d6908563ffffffff6112ac16565b600160a060020a033316600081815260208181526040808320888452808352908320949094559181529052600190810180549091810161061683826112c2565b5060009182526020909120018390557faa0e554f781c3c3b2be110a0557f260f11af9a8aa2c64bc1e7a31dbb21e32fa2338686604051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a15050505050565b6106846112eb565b60038054806020026020016040519081016040528092919081815260200182805480156106da57602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116106bc575b505050505090505b90565b600160a060020a031660009081526001602052604090206004015490565b61070b6112eb565b6002600083600160a060020a0316600160a060020a0316815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561078457602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610766575b50505050509050919050565b6107986112eb565b60008033600160a060020a0316600160a060020a031681526020019081526020016000206001018054806020026020016040519081016040528092919081815260200182805480156106da57602002820191906000526020600020905b8154815260200190600101908083116107f5575050505050905090565b600160a060020a0391821660009081526001602090815260408083209390941682526005909201909152205490565b600380548290811061084f57fe5b600091825260209091200154600160a060020a0316905081565b6000828282821161087957600080fd5b438290101561088757600080fd5b600160a060020a033316600090815260208181526040808320858452909152812054116108b357600080fd5b600160a060020a03331660009081526020819052604090206001018054839190839081106108dd57fe5b600091825260209091200154146108f357600080fd5b600160a060020a0333166000818152602081815260408083208984528083529083208054908490559383529190526001018054919450908590811061093457fe5b6000918252602082200155600160a060020a03331683156108fc0284604051600060405180830381858888f19350505050151561097057600080fd5b7ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5683386856040518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a15050505050565b600160a060020a031660009081526001602052604090206003015490565b600454600160a060020a031681565b600160a060020a038116600090815260016020526040902060020154819060ff161515610a2957600080fd5b600160a060020a038216600090815260016020526040902060030154610a55903463ffffffff6112ac16565b600160a060020a038084166000908152600160209081526040808320600381019590955533909316825260059093019092529020541515610aeb57600160a060020a0382166000908152600260205260409020805460018101610ab883826112c2565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff191633600160a060020a03161790555b600160a060020a038083166000908152600160209081526040808320339094168352600590930190522054610b26903463ffffffff6112ac16565b600160a060020a03808416600090815260016020908152604080832033948516845260050190915290819020929092557f66a9138482c99e9baf08860110ef332cc0c23b4a199a53593d8db0fc8f96fbfc918490349051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a15050565b600160a060020a038281166000908152600160205260409020548391338116911614610bd557600080fd5b600160a060020a038316600090815260016020819052604090912001828051610c029291602001906112fd565b507f63f303264cd4b7a198f0163f96e0b6b1f972f9b73359a70c44241b862879d8a4338484604051600160a060020a0380851682528316602082015260606040820181815290820183818151815260200191508051906020019080838360005b83811015610c7a578082015183820152602001610c62565b50505050905090810190601f168015610ca75780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a1505050565b60055481565b60095481565b600160a060020a038181166000908152600160205260408120549091829182918591338216911614610cf857600080fd5b600160a060020a038516600090815260016020526040902060020154859060ff161515610d2457600080fd5b600160a060020a0386166000908152600160205260408120600201805460ff191690556005805460001901905594505b600354851015610dd65785600160a060020a0316600386815481101515610d7757fe5b600091825260209091200154600160a060020a03161415610dcb576003805486908110610da057fe5b6000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff19169055610dd6565b600190940193610d54565b600160a060020a038087166000818152600160208181526040808420339096168452600586018252832054939092529052600390910154909450610e20908563ffffffff61129a16565b600160a060020a03808816600090815260016020908152604080832060038101959095553390931682526005909301909252812055600854610e68904363ffffffff6112ac16565b600160a060020a033316600090815260208181526040808320848452909152902054909350610e9d908563ffffffff6112ac16565b600160a060020a0333166000818152602081815260408083208884528083529083209490945591815290526001908101805490918101610edd83826112c2565b5060009182526020909120018390557f4edf3e325d0063213a39f9085522994a1c44bea5f39e7d63ef61260a1e58c6d33387604051600160a060020a039283168152911660208201526040908101905180910390a1505050505050565b600160a060020a039081166000908152600160205260409020541690565b60075481565b60085481565b600160a060020a031660009081526001602052604090206002015460ff1690565b60065481565b600654341015610f9a57600080fd5b600160a060020a038316600090815260016020526040902060020154839060ff1615610fc557600080fd5b6003805460018101610fd783826112c2565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03861617905560a06040519081016040528033600160a060020a0316815260200184848080601f01602080910402602001604051908101604052818152929190602084018383808284375050509284525050600160208084018290523460408086019190915260006060909501859052600160a060020a038a16855291905290912090508151815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03919091161781556020820151816001019080516110cb9291602001906112fd565b50604082015160028201805460ff191691151591909117905560608201518160030155608082015160049091015550600160a060020a038085166000818152600160208181526040808420339096168452600595860182528084203490558554830190955592825260029092529190912080549091810161114c83826112c2565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0386161790557f7635f1d87b47fba9f2b09e56eb4be75cca030e0cb179c1602ac9261d39a8f5c1338534604051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a150505050565b6111dc6112eb565b6001600083600160a060020a0316600160a060020a031681526020019081526020016000206001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156107845780601f1061126d57610100808354040283529160200191610784565b820191906000526020600020905b81548152906001019060200180831161127b5750939695505050505050565b6000828211156112a657fe5b50900390565b6000828201838110156112bb57fe5b9392505050565b8154818355818115116112e6576000838152602090206112e691810190830161137b565b505050565b60206040519081016040526000815290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061133e57805160ff191683800117855561136b565b8280016001018555821561136b579182015b8281111561136b578251825591602001919060010190611350565b5061137792915061137b565b5090565b6106e291905b8082111561137757600081556001016113815600a165627a7a72305820479a652c5721d1178b9d8443fe6dd8b949fe0bf883ba1dd1879aab405681fbf70029` // DeployTomoValidator deploys a new Ethereum contract, binding an instance of TomoValidator to it. -func DeployTomoValidator(auth *bind.TransactOpts, backend bind.ContractBackend, _minCandidateCap *big.Int, _maxValidatorNumber *big.Int, _candidateWithdrawDelay *big.Int) (common.Address, *types.Transaction, *TomoValidator, error) { +func DeployTomoValidator(auth *bind.TransactOpts, backend bind.ContractBackend, _minCandidateCap *big.Int, _maxValidatorNumber *big.Int, _candidateWithdrawDelay *big.Int, _voterWithdrawDelay *big.Int) (common.Address, *types.Transaction, *TomoValidator, error) { parsed, err := abi.JSON(strings.NewReader(TomoValidatorABI)) if err != nil { return common.Address{}, nil, nil, err } - address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(TomoValidatorBin), backend, _minCandidateCap, _maxValidatorNumber, _candidateWithdrawDelay) + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(TomoValidatorBin), backend, _minCandidateCap, _maxValidatorNumber, _candidateWithdrawDelay, _voterWithdrawDelay) if err != nil { return common.Address{}, nil, nil, err } @@ -540,6 +540,32 @@ func (_TomoValidator *TomoValidatorTransactorRaw) Transact(opts *bind.TransactOp return _TomoValidator.Contract.contract.Transact(opts, method, params...) } +// CandidateCount is a free data retrieval call binding the contract method 0xa9a981a3. +// +// Solidity: function candidateCount() constant returns(uint256) +func (_TomoValidator *TomoValidatorCaller) CandidateCount(opts *bind.CallOpts) (*big.Int, error) { + var ( + ret0 = new(*big.Int) + ) + out := ret0 + err := _TomoValidator.contract.Call(opts, out, "candidateCount") + return *ret0, err +} + +// CandidateCount is a free data retrieval call binding the contract method 0xa9a981a3. +// +// Solidity: function candidateCount() constant returns(uint256) +func (_TomoValidator *TomoValidatorSession) CandidateCount() (*big.Int, error) { + return _TomoValidator.Contract.CandidateCount(&_TomoValidator.CallOpts) +} + +// CandidateCount is a free data retrieval call binding the contract method 0xa9a981a3. +// +// Solidity: function candidateCount() constant returns(uint256) +func (_TomoValidator *TomoValidatorCallerSession) CandidateCount() (*big.Int, error) { + return _TomoValidator.Contract.CandidateCount(&_TomoValidator.CallOpts) +} + // CandidateWithdrawDelay is a free data retrieval call binding the contract method 0xd161c767. // // Solidity: function candidateWithdrawDelay() constant returns(uint256) @@ -592,6 +618,32 @@ func (_TomoValidator *TomoValidatorCallerSession) Candidates(arg0 *big.Int) (com return _TomoValidator.Contract.Candidates(&_TomoValidator.CallOpts, arg0) } +// FirstOwner is a free data retrieval call binding the contract method 0x6bc28781. +// +// Solidity: function firstOwner() constant returns(address) +func (_TomoValidator *TomoValidatorCaller) FirstOwner(opts *bind.CallOpts) (common.Address, error) { + var ( + ret0 = new(common.Address) + ) + out := ret0 + err := _TomoValidator.contract.Call(opts, out, "firstOwner") + return *ret0, err +} + +// FirstOwner is a free data retrieval call binding the contract method 0x6bc28781. +// +// Solidity: function firstOwner() constant returns(address) +func (_TomoValidator *TomoValidatorSession) FirstOwner() (common.Address, error) { + return _TomoValidator.Contract.FirstOwner(&_TomoValidator.CallOpts) +} + +// FirstOwner is a free data retrieval call binding the contract method 0x6bc28781. +// +// Solidity: function firstOwner() constant returns(address) +func (_TomoValidator *TomoValidatorCallerSession) FirstOwner() (common.Address, error) { + return _TomoValidator.Contract.FirstOwner(&_TomoValidator.CallOpts) +} + // GetCandidateCap is a free data retrieval call binding the contract method 0x58e7525f. // // Solidity: function getCandidateCap(_candidate address) constant returns(uint256) @@ -774,6 +826,32 @@ func (_TomoValidator *TomoValidatorCallerSession) GetVoters(_candidate common.Ad return _TomoValidator.Contract.GetVoters(&_TomoValidator.CallOpts, _candidate) } +// GetWithdrawBlockNumbers is a free data retrieval call binding the contract method 0x2f9c4bba. +// +// Solidity: function getWithdrawBlockNumbers() constant returns(uint256[]) +func (_TomoValidator *TomoValidatorCaller) GetWithdrawBlockNumbers(opts *bind.CallOpts) ([]*big.Int, error) { + var ( + ret0 = new([]*big.Int) + ) + out := ret0 + err := _TomoValidator.contract.Call(opts, out, "getWithdrawBlockNumbers") + return *ret0, err +} + +// GetWithdrawBlockNumbers is a free data retrieval call binding the contract method 0x2f9c4bba. +// +// Solidity: function getWithdrawBlockNumbers() constant returns(uint256[]) +func (_TomoValidator *TomoValidatorSession) GetWithdrawBlockNumbers() ([]*big.Int, error) { + return _TomoValidator.Contract.GetWithdrawBlockNumbers(&_TomoValidator.CallOpts) +} + +// GetWithdrawBlockNumbers is a free data retrieval call binding the contract method 0x2f9c4bba. +// +// Solidity: function getWithdrawBlockNumbers() constant returns(uint256[]) +func (_TomoValidator *TomoValidatorCallerSession) GetWithdrawBlockNumbers() ([]*big.Int, error) { + return _TomoValidator.Contract.GetWithdrawBlockNumbers(&_TomoValidator.CallOpts) +} + // IsCandidate is a free data retrieval call binding the contract method 0xd51b9e93. // // Solidity: function isCandidate(_candidate address) constant returns(bool) @@ -852,6 +930,32 @@ func (_TomoValidator *TomoValidatorCallerSession) MinCandidateCap() (*big.Int, e return _TomoValidator.Contract.MinCandidateCap(&_TomoValidator.CallOpts) } +// VoterWithdrawDelay is a free data retrieval call binding the contract method 0xa9ff959e. +// +// Solidity: function voterWithdrawDelay() constant returns(uint256) +func (_TomoValidator *TomoValidatorCaller) VoterWithdrawDelay(opts *bind.CallOpts) (*big.Int, error) { + var ( + ret0 = new(*big.Int) + ) + out := ret0 + err := _TomoValidator.contract.Call(opts, out, "voterWithdrawDelay") + return *ret0, err +} + +// VoterWithdrawDelay is a free data retrieval call binding the contract method 0xa9ff959e. +// +// Solidity: function voterWithdrawDelay() constant returns(uint256) +func (_TomoValidator *TomoValidatorSession) VoterWithdrawDelay() (*big.Int, error) { + return _TomoValidator.Contract.VoterWithdrawDelay(&_TomoValidator.CallOpts) +} + +// VoterWithdrawDelay is a free data retrieval call binding the contract method 0xa9ff959e. +// +// Solidity: function voterWithdrawDelay() constant returns(uint256) +func (_TomoValidator *TomoValidatorCallerSession) VoterWithdrawDelay() (*big.Int, error) { + return _TomoValidator.Contract.VoterWithdrawDelay(&_TomoValidator.CallOpts) +} + // Propose is a paid mutator transaction binding the contract method 0xd6f0948c. // // Solidity: function propose(_candidate address, _nodeUrl string) returns() @@ -957,25 +1061,25 @@ func (_TomoValidator *TomoValidatorTransactorSession) Vote(_candidate common.Add return _TomoValidator.Contract.Vote(&_TomoValidator.TransactOpts, _candidate) } -// Withdraw is a paid mutator transaction binding the contract method 0x51cff8d9. +// Withdraw is a paid mutator transaction binding the contract method 0x441a3e70. // -// Solidity: function withdraw(_candidate address) returns() -func (_TomoValidator *TomoValidatorTransactor) Withdraw(opts *bind.TransactOpts, _candidate common.Address) (*types.Transaction, error) { - return _TomoValidator.contract.Transact(opts, "withdraw", _candidate) +// Solidity: function withdraw(_blockNumber uint256, _index uint256) returns() +func (_TomoValidator *TomoValidatorTransactor) Withdraw(opts *bind.TransactOpts, _blockNumber *big.Int, _index *big.Int) (*types.Transaction, error) { + return _TomoValidator.contract.Transact(opts, "withdraw", _blockNumber, _index) } -// Withdraw is a paid mutator transaction binding the contract method 0x51cff8d9. +// Withdraw is a paid mutator transaction binding the contract method 0x441a3e70. // -// Solidity: function withdraw(_candidate address) returns() -func (_TomoValidator *TomoValidatorSession) Withdraw(_candidate common.Address) (*types.Transaction, error) { - return _TomoValidator.Contract.Withdraw(&_TomoValidator.TransactOpts, _candidate) +// Solidity: function withdraw(_blockNumber uint256, _index uint256) returns() +func (_TomoValidator *TomoValidatorSession) Withdraw(_blockNumber *big.Int, _index *big.Int) (*types.Transaction, error) { + return _TomoValidator.Contract.Withdraw(&_TomoValidator.TransactOpts, _blockNumber, _index) } -// Withdraw is a paid mutator transaction binding the contract method 0x51cff8d9. +// Withdraw is a paid mutator transaction binding the contract method 0x441a3e70. // -// Solidity: function withdraw(_candidate address) returns() -func (_TomoValidator *TomoValidatorTransactorSession) Withdraw(_candidate common.Address) (*types.Transaction, error) { - return _TomoValidator.Contract.Withdraw(&_TomoValidator.TransactOpts, _candidate) +// Solidity: function withdraw(_blockNumber uint256, _index uint256) returns() +func (_TomoValidator *TomoValidatorTransactorSession) Withdraw(_blockNumber *big.Int, _index *big.Int) (*types.Transaction, error) { + return _TomoValidator.Contract.Withdraw(&_TomoValidator.TransactOpts, _blockNumber, _index) } // TomoValidatorProposeIterator is returned from FilterPropose and is used to iterate over the raw logs and unpacked data for Propose events raised by the TomoValidator contract. @@ -1666,15 +1770,15 @@ func (it *TomoValidatorWithdrawIterator) Close() error { // TomoValidatorWithdraw represents a Withdraw event raised by the TomoValidator contract. type TomoValidatorWithdraw struct { - Owner common.Address - Candidate common.Address - Cap *big.Int - Raw types.Log // Blockchain specific contextual infos + Owner common.Address + BlockNumber *big.Int + Cap *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterWithdraw is a free log retrieval operation binding the contract event 0x9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb. +// FilterWithdraw is a free log retrieval operation binding the contract event 0xf279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568. // -// Solidity: event Withdraw(_owner address, _candidate address, _cap uint256) +// Solidity: event Withdraw(_owner address, _blockNumber uint256, _cap uint256) func (_TomoValidator *TomoValidatorFilterer) FilterWithdraw(opts *bind.FilterOpts) (*TomoValidatorWithdrawIterator, error) { logs, sub, err := _TomoValidator.contract.FilterLogs(opts, "Withdraw") @@ -1684,9 +1788,9 @@ func (_TomoValidator *TomoValidatorFilterer) FilterWithdraw(opts *bind.FilterOpt return &TomoValidatorWithdrawIterator{contract: _TomoValidator.contract, event: "Withdraw", logs: logs, sub: sub}, nil } -// WatchWithdraw is a free log subscription operation binding the contract event 0x9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb. +// WatchWithdraw is a free log subscription operation binding the contract event 0xf279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568. // -// Solidity: event Withdraw(_owner address, _candidate address, _cap uint256) +// Solidity: event Withdraw(_owner address, _blockNumber uint256, _cap uint256) func (_TomoValidator *TomoValidatorFilterer) WatchWithdraw(opts *bind.WatchOpts, sink chan<- *TomoValidatorWithdraw) (event.Subscription, error) { logs, sub, err := _TomoValidator.contract.WatchLogs(opts, "Withdraw") diff --git a/contracts/validator/validator.go b/contracts/validator/validator.go index f9e7891e07..f3bcc2ae77 100644 --- a/contracts/validator/validator.go +++ b/contracts/validator/validator.go @@ -1,6 +1,7 @@ package validator import ( + "fmt" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/contracts/validator/contract" @@ -28,7 +29,10 @@ func NewValidator(transactOpts *bind.TransactOpts, contractAddr common.Address, } func DeployValidator(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend) (common.Address, *Validator, error) { - validatorAddr, _, _, err := contract.DeployTomoValidator(transactOpts, contractBackend, big.NewInt(50000), big.NewInt(99), big.NewInt(100)) + minDeposit := new(big.Int) + minDeposit.SetString("50000000000000000000000", 10) + fmt.Println("--->", common.BigToHash(minDeposit).Hex()) + validatorAddr, _, _, err := contract.DeployTomoValidator(transactOpts, contractBackend, minDeposit, big.NewInt(99), big.NewInt(100), big.NewInt(100)) if err != nil { return validatorAddr, nil, err } diff --git a/contracts/validator/validator_test.go b/contracts/validator/validator_test.go index 000fc165c6..9ccdbd5f34 100644 --- a/contracts/validator/validator_test.go +++ b/contracts/validator/validator_test.go @@ -1,17 +1,19 @@ package validator import ( + "context" "math/big" "testing" + "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/contracts" "github.com/ethereum/go-ethereum/contracts/validator/contract" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/crypto" "math/rand" - "time" ) var ( @@ -31,12 +33,22 @@ func TestValidator(t *testing.T) { contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}) transactOpts := bind.NewKeyedTransactor(key) - _, validator, err := DeployValidator(transactOpts, contractBackend) + validatorAddress, validator, err := DeployValidator(transactOpts, contractBackend) if err != nil { t.Fatalf("can't deploy root registry: %v", err) } contractBackend.Commit() + d := time.Now().Add(1000 * time.Millisecond) + ctx, _ := context.WithDeadline(context.Background(), d) + code, _ := contractBackend.CodeAt(ctx, validatorAddress, nil) + t.Log("contract code", common.ToHex(code)) + f := func(key, val common.Hash) bool { + t.Log(key.Hex(), val.Hex()) + return true + } + contractBackend.ForEachStorageAt(ctx, validatorAddress, nil, f) + candidates, err := validator.GetCandidates() if err != nil { t.Fatalf("can't get candidates: %v", err) @@ -61,7 +73,7 @@ func TestRewardBalance(t *testing.T) { accounts := []*bind.TransactOpts{acc1Opts, acc2Opts} transactOpts := bind.NewKeyedTransactor(acc1Key) - validatorAddr, _, baseValidator, err := contract.DeployTomoValidator(transactOpts, contractBackend, big.NewInt(50000), big.NewInt(99), big.NewInt(100)) + validatorAddr, _, baseValidator, err := contract.DeployTomoValidator(transactOpts, contractBackend, big.NewInt(50000), big.NewInt(99), big.NewInt(100), big.NewInt(100)) if err != nil { t.Fatalf("can't deploy root registry: %v", err) }