From 29a7cf8f2bb3645c7dc309abec34322de1bb34b4 Mon Sep 17 00:00:00 2001 From: Nguyen Sy Thanh Son Date: Fri, 13 Apr 2018 09:29:15 +0000 Subject: [PATCH] update validator smart contract --- .../validator/contract/TomoValidator.sol | 49 +++- contracts/validator/contract/validator.go | 233 +++++++++++++++++- 2 files changed, 279 insertions(+), 3 deletions(-) diff --git a/contracts/validator/contract/TomoValidator.sol b/contracts/validator/contract/TomoValidator.sol index 513ed03c89..4b9ed33fef 100644 --- a/contracts/validator/contract/TomoValidator.sol +++ b/contracts/validator/contract/TomoValidator.sol @@ -10,13 +10,18 @@ contract TomoValidator is IValidator { bool isValidator; bool isCandidate; uint256 cap; + mapping(address => uint256) voters; } mapping(address => ValidatorState) validatorsState; + address[] public validators; + address[] public candidates; uint256 threshold = 1000 * 10** 18; // 1000 TOMO function TomoValidator(address[] _validators, uint256[] _caps) public { - + validators = _validators; + candidates = _validators; + for (uint256 i = 0; i < _validators.length; i++) { validatorsState[_validators[i]] = ValidatorState({ isValidator: true, @@ -30,6 +35,9 @@ contract TomoValidator is IValidator { function propose(address _candidate) external payable { // only validator can propose a candidate require(validatorsState[msg.sender].isValidator); + if (!validatorsState[_candidate].isCandidate) { + candidates.push(_candidate); + } validatorsState[_candidate] = ValidatorState({ isValidator: false, isCandidate: true, @@ -43,7 +51,46 @@ contract TomoValidator is IValidator { require(validatorsState[_candidate].isCandidate); validatorsState[_candidate].cap = validatorsState[_candidate].cap.add(msg.value); if (validatorsState[_candidate].cap >= threshold) { + if (!validatorsState[_candidate].isValidator) { + validators.push(_candidate); + } validatorsState[_candidate].isValidator = true; + validatorsState[_candidate].voters[msg.sender] = validatorsState[_candidate].voters[msg.sender].add(msg.value); } } + + function getValidators() public view returns(address[]) { + return validators; + } + + function getCandidates() public view returns(address[]) { + return candidates; + } + + function getCandidateCap(address _candidate) public view returns(uint256) { + return validatorsState[_candidate].cap; + } + + function getVoterCap(address _candidate, address _voter) public view returns(uint256) { + return validatorsState[_candidate].voters[_voter]; + } + + function isValidator(address _candidate) public view returns(bool) { + return validatorsState[_candidate].isValidator; + } + + function isCandidate(address _candidate) public view returns(bool) { + return validatorsState[_candidate].isCandidate; + } + + function unvote(address _candidate, uint256 _cap) public { + // only unvote for candidate who does not become validator yet + require(!validatorsState[_candidate].isValidator); + require(validatorsState[_candidate].isCandidate); + require(validatorsState[_candidate].voters[msg.sender] >= _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); + } } diff --git a/contracts/validator/contract/validator.go b/contracts/validator/contract/validator.go index 6c5db002bc..593442a3f2 100644 --- a/contracts/validator/contract/validator.go +++ b/contracts/validator/contract/validator.go @@ -357,10 +357,10 @@ 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\":\"propose\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"vote\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_validators\",\"type\":\"address[]\"},{\"name\":\"_caps\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]" +const TomoValidatorABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_candidate\",\"type\":\"address\"}],\"name\":\"propose\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"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\":\"_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\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"validators\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"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\":true,\"inputs\":[],\"name\":\"getValidators\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"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\":\"_candidate\",\"type\":\"address\"}],\"name\":\"isValidator\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_validators\",\"type\":\"address[]\"},{\"name\":\"_caps\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]" // TomoValidatorBin is the compiled bytecode used for deploying new contracts. -const TomoValidatorBin = `0x6060604052683635c9adc5dea00000600155341561001c57600080fd5b6040516102ed3803806102ed83398101604052808051820191906020018051909101905060005b82518110156100eb576060604051908101604090815260018083526020830152810183838151811061007157fe5b90602001906020020151905260008085848151811061008c57fe5b90602001906020020151600160a060020a0316815260208101919091526040016000208151815460ff1916901515178155602082015181549015156101000261ff00199091161781556040820151600191820155919091019050610043565b5050506101f0806100fd6000396000f30060606040526004361061004b5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630126795181146100505780636dd7d8ea14610066575b600080fd5b610064600160a060020a036004351661007a565b005b610064600160a060020a0360043516610108565b600160a060020a03331660009081526020819052604090205460ff1615156100a157600080fd5b60606040519081016040908152600080835260016020808501919091523483850152600160a060020a0385168252819052208151815460ff1916901515178155602082015181549015156101000261ff001990911617815560408201516001909101555050565b600160a060020a038116600090815260208190526040902054610100900460ff16151561013457600080fd5b600160a060020a038116600090815260208190526040902060010154610160903463ffffffff6101ae16565b600160a060020a038216600090815260208190526040902060019081018290555490106101ab57600160a060020a0381166000908152602081905260409020805460ff191660011790555b50565b6000828201838110156101bd57fe5b93925050505600a165627a7a7230582022f965615b62147c104c686c2a37c0d96bf4b82497507420007f36a8c04a2a400029` +const TomoValidatorBin = `0x6060604052683635c9adc5dea00000600355341561001c57600080fd5b604051610a06380380610a068339810160405280805182019190602001805190910190506000600183805161005592916020019061011f565b50600283805161006992916020019061011f565b50600090505b8251811015610117576060604051908101604090815260018083526020830152810183838151811061009d57fe5b9060200190602002015190526000808584815181106100b857fe5b90602001906020020151600160a060020a0316815260208101919091526040016000208151815460ff1916901515178155602082015181549015156101000261ff0019909116178155604082015160019182015591909101905061006f565b5050506101ad565b828054828255906000526020600020908101928215610176579160200282015b828111156101765782518254600160a060020a031916600160a060020a03919091161782556020929092019160019091019061013f565b50610182929150610186565b5090565b6101aa91905b80821115610182578054600160a060020a031916815560010161018c565b90565b61084a806101bc6000396000f3006060604052600436106100ae5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630126795181146100b357806302aa9be2146100c957806306a49fce146100eb578063302b6872146101515780633477ee2e1461018857806335aa2e44146101ba57806358e7525f146101d05780636dd7d8ea146101ef578063b7ab4db514610203578063d51b9e9314610216578063facd743b14610249575b600080fd5b6100c7600160a060020a0360043516610268565b005b34156100d457600080fd5b6100c7600160a060020a0360043516602435610362565b34156100f657600080fd5b6100fe6104b6565b60405160208082528190810183818151815260200191508051906020019060200280838360005b8381101561013d578082015183820152602001610125565b505050509050019250505060405180910390f35b341561015c57600080fd5b610176600160a060020a036004358116906024351661051f565b60405190815260200160405180910390f35b341561019357600080fd5b61019e60043561054c565b604051600160a060020a03909116815260200160405180910390f35b34156101c557600080fd5b61019e600435610574565b34156101db57600080fd5b610176600160a060020a0360043516610582565b6100c7600160a060020a03600435166105a0565b341561020e57600080fd5b6100fe6106f6565b341561022157600080fd5b610235600160a060020a036004351661075c565b604051901515815260200160405180910390f35b341561025457600080fd5b610235600160a060020a036004351661077f565b600160a060020a03331660009081526020819052604090205460ff16151561028f57600080fd5b600160a060020a038116600090815260208190526040902054610100900460ff1615156102fb5760028054600181016102c883826107c5565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b60606040519081016040908152600080835260016020808501919091523483850152600160a060020a0385168252819052208151815460ff1916901515178155602082015181549015156101000261ff001990911617815560408201516001909101555050565b600160a060020a03821660009081526020819052604090205460ff161561038857600080fd5b600160a060020a038216600090815260208190526040902054610100900460ff1615156103b457600080fd5b600160a060020a03808316600090815260208181526040808320339094168352600290930190522054819010156103ea57600080fd5b600160a060020a038216600090815260208190526040902060010154610416908263ffffffff61079d16565b600160a060020a0380841660009081526020818152604080832060018101959095553390931682526002909301909252902054610459908263ffffffff61079d16565b600160a060020a0380841660009081526020818152604080832033909416808452600290940190915290819020929092559082156108fc0290839051600060405180830381858888f1935050505015156104b257600080fd5b5050565b6104be6107ee565b600280548060200260200160405190810160405280929190818152602001828054801561051457602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116104f6575b505050505090505b90565b600160a060020a039182166000908152602081815260408083209390941682526002909201909152205490565b600280548290811061055a57fe5b600091825260209091200154600160a060020a0316905081565b600180548290811061055a57fe5b600160a060020a031660009081526020819052604090206001015490565b600160a060020a038116600090815260208190526040902054610100900460ff1615156105cc57600080fd5b600160a060020a0381166000908152602081905260409020600101546105f8903463ffffffff6107af16565b600160a060020a038216600090815260208190526040902060010181905560035490106106f357600160a060020a03811660009081526020819052604090205460ff161515610685576001805480820161065283826107c5565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b600160a060020a03808216600090815260208181526040808320805460ff191660011781553390941683526002909301905220546106c9903463ffffffff6107af16565b600160a060020a038083166000908152602081815260408083203390941683526002909301905220555b50565b6106fe6107ee565b600180548060200260200160405190810160405280929190818152602001828054801561051457602002820191906000526020600020908154600160a060020a031681526001909101906020018083116104f6575050505050905090565b600160a060020a0316600090815260208190526040902054610100900460ff1690565b600160a060020a031660009081526020819052604090205460ff1690565b6000828211156107a957fe5b50900390565b6000828201838110156107be57fe5b9392505050565b8154818355818115116107e9576000838152602090206107e9918101908301610800565b505050565b60206040519081016040526000815290565b61051c91905b8082111561081a5760008155600101610806565b50905600a165627a7a723058202ad1e9fda0e95a1d0040266c6438e7a86b19a47ec3debbaaf3a2ce2608178ff50029` // DeployTomoValidator deploys a new Ethereum contract, binding an instance of TomoValidator to it. func DeployTomoValidator(auth *bind.TransactOpts, backend bind.ContractBackend, _validators []common.Address, _caps []*big.Int) (common.Address, *types.Transaction, *TomoValidator, error) { @@ -517,6 +517,214 @@ func (_TomoValidator *TomoValidatorTransactorRaw) Transact(opts *bind.TransactOp return _TomoValidator.Contract.contract.Transact(opts, method, params...) } +// Candidates is a free data retrieval call binding the contract method 0x3477ee2e. +// +// Solidity: function candidates( uint256) constant returns(address) +func (_TomoValidator *TomoValidatorCaller) Candidates(opts *bind.CallOpts, arg0 *big.Int) (common.Address, error) { + var ( + ret0 = new(common.Address) + ) + out := ret0 + err := _TomoValidator.contract.Call(opts, out, "candidates", arg0) + return *ret0, err +} + +// Candidates is a free data retrieval call binding the contract method 0x3477ee2e. +// +// Solidity: function candidates( uint256) constant returns(address) +func (_TomoValidator *TomoValidatorSession) Candidates(arg0 *big.Int) (common.Address, error) { + return _TomoValidator.Contract.Candidates(&_TomoValidator.CallOpts, arg0) +} + +// Candidates is a free data retrieval call binding the contract method 0x3477ee2e. +// +// Solidity: function candidates( uint256) constant returns(address) +func (_TomoValidator *TomoValidatorCallerSession) Candidates(arg0 *big.Int) (common.Address, error) { + return _TomoValidator.Contract.Candidates(&_TomoValidator.CallOpts, arg0) +} + +// GetCandidateCap is a free data retrieval call binding the contract method 0x58e7525f. +// +// Solidity: function getCandidateCap(_candidate address) constant returns(uint256) +func (_TomoValidator *TomoValidatorCaller) GetCandidateCap(opts *bind.CallOpts, _candidate common.Address) (*big.Int, error) { + var ( + ret0 = new(*big.Int) + ) + out := ret0 + err := _TomoValidator.contract.Call(opts, out, "getCandidateCap", _candidate) + return *ret0, err +} + +// GetCandidateCap is a free data retrieval call binding the contract method 0x58e7525f. +// +// Solidity: function getCandidateCap(_candidate address) constant returns(uint256) +func (_TomoValidator *TomoValidatorSession) GetCandidateCap(_candidate common.Address) (*big.Int, error) { + return _TomoValidator.Contract.GetCandidateCap(&_TomoValidator.CallOpts, _candidate) +} + +// GetCandidateCap is a free data retrieval call binding the contract method 0x58e7525f. +// +// Solidity: function getCandidateCap(_candidate address) constant returns(uint256) +func (_TomoValidator *TomoValidatorCallerSession) GetCandidateCap(_candidate common.Address) (*big.Int, error) { + return _TomoValidator.Contract.GetCandidateCap(&_TomoValidator.CallOpts, _candidate) +} + +// GetCandidates is a free data retrieval call binding the contract method 0x06a49fce. +// +// Solidity: function getCandidates() constant returns(address[]) +func (_TomoValidator *TomoValidatorCaller) GetCandidates(opts *bind.CallOpts) ([]common.Address, error) { + var ( + ret0 = new([]common.Address) + ) + out := ret0 + err := _TomoValidator.contract.Call(opts, out, "getCandidates") + return *ret0, err +} + +// GetCandidates is a free data retrieval call binding the contract method 0x06a49fce. +// +// Solidity: function getCandidates() constant returns(address[]) +func (_TomoValidator *TomoValidatorSession) GetCandidates() ([]common.Address, error) { + return _TomoValidator.Contract.GetCandidates(&_TomoValidator.CallOpts) +} + +// GetCandidates is a free data retrieval call binding the contract method 0x06a49fce. +// +// Solidity: function getCandidates() constant returns(address[]) +func (_TomoValidator *TomoValidatorCallerSession) GetCandidates() ([]common.Address, error) { + return _TomoValidator.Contract.GetCandidates(&_TomoValidator.CallOpts) +} + +// GetValidators is a free data retrieval call binding the contract method 0xb7ab4db5. +// +// Solidity: function getValidators() constant returns(address[]) +func (_TomoValidator *TomoValidatorCaller) GetValidators(opts *bind.CallOpts) ([]common.Address, error) { + var ( + ret0 = new([]common.Address) + ) + out := ret0 + err := _TomoValidator.contract.Call(opts, out, "getValidators") + return *ret0, err +} + +// GetValidators is a free data retrieval call binding the contract method 0xb7ab4db5. +// +// Solidity: function getValidators() constant returns(address[]) +func (_TomoValidator *TomoValidatorSession) GetValidators() ([]common.Address, error) { + return _TomoValidator.Contract.GetValidators(&_TomoValidator.CallOpts) +} + +// GetValidators is a free data retrieval call binding the contract method 0xb7ab4db5. +// +// Solidity: function getValidators() constant returns(address[]) +func (_TomoValidator *TomoValidatorCallerSession) GetValidators() ([]common.Address, error) { + return _TomoValidator.Contract.GetValidators(&_TomoValidator.CallOpts) +} + +// GetVoterCap is a free data retrieval call binding the contract method 0x302b6872. +// +// Solidity: function getVoterCap(_candidate address, _voter address) constant returns(uint256) +func (_TomoValidator *TomoValidatorCaller) GetVoterCap(opts *bind.CallOpts, _candidate common.Address, _voter common.Address) (*big.Int, error) { + var ( + ret0 = new(*big.Int) + ) + out := ret0 + err := _TomoValidator.contract.Call(opts, out, "getVoterCap", _candidate, _voter) + return *ret0, err +} + +// GetVoterCap is a free data retrieval call binding the contract method 0x302b6872. +// +// Solidity: function getVoterCap(_candidate address, _voter address) constant returns(uint256) +func (_TomoValidator *TomoValidatorSession) GetVoterCap(_candidate common.Address, _voter common.Address) (*big.Int, error) { + return _TomoValidator.Contract.GetVoterCap(&_TomoValidator.CallOpts, _candidate, _voter) +} + +// GetVoterCap is a free data retrieval call binding the contract method 0x302b6872. +// +// Solidity: function getVoterCap(_candidate address, _voter address) constant returns(uint256) +func (_TomoValidator *TomoValidatorCallerSession) GetVoterCap(_candidate common.Address, _voter common.Address) (*big.Int, error) { + return _TomoValidator.Contract.GetVoterCap(&_TomoValidator.CallOpts, _candidate, _voter) +} + +// IsCandidate is a free data retrieval call binding the contract method 0xd51b9e93. +// +// Solidity: function isCandidate(_candidate address) constant returns(bool) +func (_TomoValidator *TomoValidatorCaller) IsCandidate(opts *bind.CallOpts, _candidate common.Address) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _TomoValidator.contract.Call(opts, out, "isCandidate", _candidate) + return *ret0, err +} + +// IsCandidate is a free data retrieval call binding the contract method 0xd51b9e93. +// +// Solidity: function isCandidate(_candidate address) constant returns(bool) +func (_TomoValidator *TomoValidatorSession) IsCandidate(_candidate common.Address) (bool, error) { + return _TomoValidator.Contract.IsCandidate(&_TomoValidator.CallOpts, _candidate) +} + +// IsCandidate is a free data retrieval call binding the contract method 0xd51b9e93. +// +// Solidity: function isCandidate(_candidate address) constant returns(bool) +func (_TomoValidator *TomoValidatorCallerSession) IsCandidate(_candidate common.Address) (bool, error) { + return _TomoValidator.Contract.IsCandidate(&_TomoValidator.CallOpts, _candidate) +} + +// IsValidator is a free data retrieval call binding the contract method 0xfacd743b. +// +// Solidity: function isValidator(_candidate address) constant returns(bool) +func (_TomoValidator *TomoValidatorCaller) IsValidator(opts *bind.CallOpts, _candidate common.Address) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _TomoValidator.contract.Call(opts, out, "isValidator", _candidate) + return *ret0, err +} + +// IsValidator is a free data retrieval call binding the contract method 0xfacd743b. +// +// Solidity: function isValidator(_candidate address) constant returns(bool) +func (_TomoValidator *TomoValidatorSession) IsValidator(_candidate common.Address) (bool, error) { + return _TomoValidator.Contract.IsValidator(&_TomoValidator.CallOpts, _candidate) +} + +// IsValidator is a free data retrieval call binding the contract method 0xfacd743b. +// +// Solidity: function isValidator(_candidate address) constant returns(bool) +func (_TomoValidator *TomoValidatorCallerSession) IsValidator(_candidate common.Address) (bool, error) { + return _TomoValidator.Contract.IsValidator(&_TomoValidator.CallOpts, _candidate) +} + +// Validators is a free data retrieval call binding the contract method 0x35aa2e44. +// +// Solidity: function validators( uint256) constant returns(address) +func (_TomoValidator *TomoValidatorCaller) Validators(opts *bind.CallOpts, arg0 *big.Int) (common.Address, error) { + var ( + ret0 = new(common.Address) + ) + out := ret0 + err := _TomoValidator.contract.Call(opts, out, "validators", arg0) + return *ret0, err +} + +// Validators is a free data retrieval call binding the contract method 0x35aa2e44. +// +// Solidity: function validators( uint256) constant returns(address) +func (_TomoValidator *TomoValidatorSession) Validators(arg0 *big.Int) (common.Address, error) { + return _TomoValidator.Contract.Validators(&_TomoValidator.CallOpts, arg0) +} + +// Validators is a free data retrieval call binding the contract method 0x35aa2e44. +// +// Solidity: function validators( uint256) constant returns(address) +func (_TomoValidator *TomoValidatorCallerSession) Validators(arg0 *big.Int) (common.Address, error) { + return _TomoValidator.Contract.Validators(&_TomoValidator.CallOpts, arg0) +} + // Propose is a paid mutator transaction binding the contract method 0x01267951. // // Solidity: function propose(_candidate address) returns() @@ -538,6 +746,27 @@ func (_TomoValidator *TomoValidatorTransactorSession) Propose(_candidate common. return _TomoValidator.Contract.Propose(&_TomoValidator.TransactOpts, _candidate) } +// Unvote is a paid mutator transaction binding the contract method 0x02aa9be2. +// +// Solidity: function unvote(_candidate address, _cap uint256) returns() +func (_TomoValidator *TomoValidatorTransactor) Unvote(opts *bind.TransactOpts, _candidate common.Address, _cap *big.Int) (*types.Transaction, error) { + return _TomoValidator.contract.Transact(opts, "unvote", _candidate, _cap) +} + +// Unvote is a paid mutator transaction binding the contract method 0x02aa9be2. +// +// Solidity: function unvote(_candidate address, _cap uint256) returns() +func (_TomoValidator *TomoValidatorSession) Unvote(_candidate common.Address, _cap *big.Int) (*types.Transaction, error) { + return _TomoValidator.Contract.Unvote(&_TomoValidator.TransactOpts, _candidate, _cap) +} + +// Unvote is a paid mutator transaction binding the contract method 0x02aa9be2. +// +// Solidity: function unvote(_candidate address, _cap uint256) returns() +func (_TomoValidator *TomoValidatorTransactorSession) Unvote(_candidate common.Address, _cap *big.Int) (*types.Transaction, error) { + return _TomoValidator.Contract.Unvote(&_TomoValidator.TransactOpts, _candidate, _cap) +} + // Vote is a paid mutator transaction binding the contract method 0x6dd7d8ea. // // Solidity: function vote(_candidate address) returns()