mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 02:40:45 +00:00
removed kyc smart contract for stable version
This commit is contained in:
parent
b493f4b6ca
commit
c6886f92f2
13 changed files with 631 additions and 1112 deletions
33
contracts/blockSignerReader.go
Normal file
33
contracts/blockSignerReader.go
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
package contracts
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
slotBlockSignerMapping = map[string]uint64{
|
||||||
|
"blockSigners": 0,
|
||||||
|
"blocks": 1,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetSigners(statedb *state.StateDB, block *types.Block) []common.Address {
|
||||||
|
slot := slotBlockSignerMapping["blockSigners"]
|
||||||
|
keys := []common.Hash{}
|
||||||
|
keyArrSlot := getLocMappingAtKey(block.Hash(), slot)
|
||||||
|
arrSlot := statedb.GetState(common.HexToAddress(common.BlockSigners), common.BigToHash(keyArrSlot))
|
||||||
|
arrLength := arrSlot.Big().Uint64()
|
||||||
|
for i := uint64(0); i < arrLength; i++ {
|
||||||
|
key := getLocDynamicArrAtElement(common.BigToHash(keyArrSlot), i, 1)
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
rets := []common.Address{}
|
||||||
|
for _, key := range keys {
|
||||||
|
ret := statedb.GetState(common.HexToAddress(common.BlockSigners), key)
|
||||||
|
rets = append(rets, common.HexToAddress(ret.Hex()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return rets
|
||||||
|
}
|
||||||
|
|
@ -436,7 +436,7 @@ func (_MultiSigWallet *MultiSigWalletCallerSession) Owners(arg0 *big.Int) (commo
|
||||||
return _MultiSigWallet.Contract.Owners(&_MultiSigWallet.CallOpts, arg0)
|
return _MultiSigWallet.Contract.Owners(&_MultiSigWallet.CallOpts, arg0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required is a free data retrieval call binding the contract method 0XDC8452cd.
|
// Required is a free data retrieval call binding the contract method 0xdc8452cd.
|
||||||
//
|
//
|
||||||
// Solidity: function required() constant returns(uint256)
|
// Solidity: function required() constant returns(uint256)
|
||||||
func (_MultiSigWallet *MultiSigWalletCaller) Required(opts *bind.CallOpts) (*big.Int, error) {
|
func (_MultiSigWallet *MultiSigWalletCaller) Required(opts *bind.CallOpts) (*big.Int, error) {
|
||||||
|
|
@ -448,14 +448,14 @@ func (_MultiSigWallet *MultiSigWalletCaller) Required(opts *bind.CallOpts) (*big
|
||||||
return *ret0, err
|
return *ret0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required is a free data retrieval call binding the contract method 0XDC8452cd.
|
// Required is a free data retrieval call binding the contract method 0xdc8452cd.
|
||||||
//
|
//
|
||||||
// Solidity: function required() constant returns(uint256)
|
// Solidity: function required() constant returns(uint256)
|
||||||
func (_MultiSigWallet *MultiSigWalletSession) Required() (*big.Int, error) {
|
func (_MultiSigWallet *MultiSigWalletSession) Required() (*big.Int, error) {
|
||||||
return _MultiSigWallet.Contract.Required(&_MultiSigWallet.CallOpts)
|
return _MultiSigWallet.Contract.Required(&_MultiSigWallet.CallOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required is a free data retrieval call binding the contract method 0XDC8452cd.
|
// Required is a free data retrieval call binding the contract method 0xdc8452cd.
|
||||||
//
|
//
|
||||||
// Solidity: function required() constant returns(uint256)
|
// Solidity: function required() constant returns(uint256)
|
||||||
func (_MultiSigWallet *MultiSigWalletCallerSession) Required() (*big.Int, error) {
|
func (_MultiSigWallet *MultiSigWalletCallerSession) Required() (*big.Int, error) {
|
||||||
|
|
|
||||||
37
contracts/randomizeReader.go
Normal file
37
contracts/randomizeReader.go
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
package contracts
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
slotRandomizeMapping = map[string]uint64{
|
||||||
|
"randomSecret": 0,
|
||||||
|
"randomOpening": 1,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetSecret(statedb *state.StateDB, address common.Address) [][32]byte {
|
||||||
|
slot := slotRandomizeMapping["randomSecret"]
|
||||||
|
locSecret := getLocMappingAtKey(address.Hash(), slot)
|
||||||
|
arrLength := statedb.GetState(common.HexToAddress(common.RandomizeSMC), common.BigToHash(locSecret))
|
||||||
|
keys := []common.Hash{}
|
||||||
|
for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
|
||||||
|
key := getLocDynamicArrAtElement(common.BigToHash(locSecret), i, 1)
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
rets := [][32]byte{}
|
||||||
|
for _, key := range keys {
|
||||||
|
ret := statedb.GetState(common.HexToAddress(common.RandomizeSMC), key)
|
||||||
|
rets = append(rets, ret)
|
||||||
|
}
|
||||||
|
return rets
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetOpening(statedb *state.StateDB, address common.Address) [32]byte {
|
||||||
|
slot := slotRandomizeMapping["randomOpening"]
|
||||||
|
locOpening := getLocMappingAtKey(address.Hash(), slot)
|
||||||
|
ret := statedb.GetState(common.HexToAddress(common.RandomizeSMC), common.BigToHash(locOpening))
|
||||||
|
return ret
|
||||||
|
}
|
||||||
34
contracts/smcUtils.go
Normal file
34
contracts/smcUtils.go
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
package contracts
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getLocSimpleVariable(slot uint64) common.Hash {
|
||||||
|
slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
|
||||||
|
return slotHash
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLocMappingAtKey(key common.Hash, slot uint64) *big.Int {
|
||||||
|
slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
|
||||||
|
retByte := crypto.Keccak256(key.Bytes(), slotHash.Bytes())
|
||||||
|
ret := new(big.Int)
|
||||||
|
ret.SetBytes(retByte)
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLocDynamicArrAtElement(slotHash common.Hash, index uint64, elementSize uint64) common.Hash {
|
||||||
|
slotKecBig := crypto.Keccak256Hash(slotHash.Bytes()).Big()
|
||||||
|
//arrBig = slotKecBig + index * elementSize
|
||||||
|
arrBig := slotKecBig.Add(slotKecBig, new(big.Int).SetUint64(index*elementSize))
|
||||||
|
return common.BigToHash(arrBig)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLocFixedArrAtElement(slot uint64, index uint64, elementSize uint64) common.Hash {
|
||||||
|
slotBig := new(big.Int).SetUint64(slot)
|
||||||
|
arrBig := slotBig.Add(slotBig, new(big.Int).SetUint64(index*elementSize))
|
||||||
|
return common.BigToHash(arrBig)
|
||||||
|
}
|
||||||
282
contracts/test.go
Normal file
282
contracts/test.go
Normal file
|
|
@ -0,0 +1,282 @@
|
||||||
|
package contracts
|
||||||
|
|
||||||
|
//
|
||||||
|
//import (
|
||||||
|
// "fmt"
|
||||||
|
// "math/big"
|
||||||
|
// "time"
|
||||||
|
//
|
||||||
|
// "github.com/ethereum/go-ethereum/common"
|
||||||
|
// "github.com/ethereum/go-ethereum/core"
|
||||||
|
// "github.com/ethereum/go-ethereum/core/state"
|
||||||
|
// "github.com/ethereum/go-ethereum/crypto"
|
||||||
|
// "github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
// "github.com/ethereum/go-ethereum/core/types"
|
||||||
|
//)
|
||||||
|
//
|
||||||
|
//var (
|
||||||
|
// slotValidatorMapping = map[string]uint64{
|
||||||
|
// "withdrawsState": 0,
|
||||||
|
// "validatorsState": 1,
|
||||||
|
// "voters": 2,
|
||||||
|
// "candidates": 3,
|
||||||
|
// "candidateCount": 4,
|
||||||
|
// "minCandidateCap": 5,
|
||||||
|
// "minVoterCap": 6,
|
||||||
|
// "maxValidatorNumber": 7,
|
||||||
|
// "candidateWithdrawDelay": 8,
|
||||||
|
// "voterWithdrawDelay": 9,
|
||||||
|
// }
|
||||||
|
// slotBlockSignerMapping = map[string]uint64{
|
||||||
|
// "blockSigners": 0,
|
||||||
|
// "blocks": 1,
|
||||||
|
// }
|
||||||
|
// slotRandomizeMapping = map[string]uint64{
|
||||||
|
// "randomSecret": 0,
|
||||||
|
// "randomOpening": 1,
|
||||||
|
// }
|
||||||
|
// datadir = "/mnt/sgp1_tuna_chaindata3/data/XDC/chaindata"
|
||||||
|
// candidate = "0xd6fa3e7a89bf8c84f0ccd204a15c0d259daf2091"
|
||||||
|
//)
|
||||||
|
//
|
||||||
|
//func main() {
|
||||||
|
// //Init
|
||||||
|
// chaindb, err := ethdb.NewLDBDatabase(datadir, 0, 0)
|
||||||
|
// if err != nil || chaindb == nil {
|
||||||
|
// fmt.Printf("Can't get chaindb: %v", err)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// headHash := core.GetHeadBlockHash(chaindb)
|
||||||
|
// blockNumber := core.GetBlockNumber(chaindb, headHash)
|
||||||
|
// block := core.GetBlock(chaindb, headHash, blockNumber)
|
||||||
|
// if block == nil {
|
||||||
|
// fmt.Println("Can't get head block")
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// database := state.NewDatabase(chaindb)
|
||||||
|
// headerRootHash := block.Header().Root
|
||||||
|
// headHeaderHash := core.GetHeadHeaderHash(chaindb)
|
||||||
|
// statedb, _ := state.New(headHeaderHash, database)
|
||||||
|
// if statedb == nil {
|
||||||
|
// headHeaderHash = headerRootHash
|
||||||
|
// }
|
||||||
|
// candidateAddress := common.HexToAddress(candidate)
|
||||||
|
// fmt.Printf("Block head :%d, header root:%v\n", blockNumber, headerRootHash.Hex())
|
||||||
|
// statedb, _ = state.New(headHeaderHash, database)
|
||||||
|
// if statedb == nil {
|
||||||
|
// fmt.Println("Can't get state db")
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //GetCandidates
|
||||||
|
// _ = GetCandidates(statedb)
|
||||||
|
//
|
||||||
|
// //GetCandidateOwner
|
||||||
|
// _ = GetCandidateOwner(statedb, candidateAddress)
|
||||||
|
//
|
||||||
|
// //GetCandidateCap
|
||||||
|
// _ = GetCandidateCap(statedb, candidateAddress)
|
||||||
|
//
|
||||||
|
// //GetVoters
|
||||||
|
// voters := GetVoters(statedb, candidateAddress)
|
||||||
|
//
|
||||||
|
// start := time.Now()
|
||||||
|
// fmt.Printf("--------GetVoterCap---------\n")
|
||||||
|
// for _, voter := range voters {
|
||||||
|
// //GetVoterCap
|
||||||
|
// _ = GetVoterCap(statedb, candidateAddress, voter)
|
||||||
|
// }
|
||||||
|
// elapsed := time.Since(start)
|
||||||
|
// fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
|
//
|
||||||
|
// //GetSigners
|
||||||
|
// blockInput := core.GetBlock(chaindb, common.HexToHash("0x632f2403ea19697082d794900275632eb3373f7a9943b1407461995bbbc2816a"), uint64(1800))
|
||||||
|
// _ = GetSigners(statedb, blockInput)
|
||||||
|
//
|
||||||
|
// //GetOpening
|
||||||
|
// _ = GetOpening(statedb, candidateAddress)
|
||||||
|
// //GetSecret
|
||||||
|
// _ = GetSecret(statedb, candidateAddress)
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func GetCandidates(statedb *state.StateDB) []common.Address {
|
||||||
|
// start := time.Now()
|
||||||
|
// fmt.Printf("--------GetCandidates---------\n")
|
||||||
|
//
|
||||||
|
// slot := slotValidatorMapping["candidates"]
|
||||||
|
// slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
|
||||||
|
// arrLength := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), slotHash)
|
||||||
|
// fmt.Printf("Candidates length: %v\n", arrLength.Hex())
|
||||||
|
// keys := []common.Hash{}
|
||||||
|
// for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
|
||||||
|
// key := getLocDynamicArrAtElement(slotHash, i, 1)
|
||||||
|
// keys = append(keys, key)
|
||||||
|
// }
|
||||||
|
// rets := []common.Address{}
|
||||||
|
// for _, key := range keys {
|
||||||
|
// ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), key)
|
||||||
|
// rets = append(rets, common.HexToAddress(ret.Hex()))
|
||||||
|
// fmt.Printf("%v\n", common.HexToAddress(ret.Hex()).Hex())
|
||||||
|
// }
|
||||||
|
// elapsed := time.Since(start)
|
||||||
|
// fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
|
// return rets
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func GetCandidateOwner(statedb *state.StateDB, candidate common.Address) common.Address {
|
||||||
|
// start := time.Now()
|
||||||
|
// fmt.Printf("--------GetCandidateOwner---------\n")
|
||||||
|
//
|
||||||
|
// slot := slotValidatorMapping["validatorsState"]
|
||||||
|
// // validatorsState[_candidate].owner;
|
||||||
|
// locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
|
||||||
|
// locCandidateOwner := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(0)))
|
||||||
|
// ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locCandidateOwner))
|
||||||
|
// fmt.Printf("ret: %v\n", common.HexToAddress(ret.Hex()).Hex())
|
||||||
|
//
|
||||||
|
// elapsed := time.Since(start)
|
||||||
|
// fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
|
// return common.HexToAddress(ret.Hex())
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func GetCandidateCap(statedb *state.StateDB, candidate common.Address) string {
|
||||||
|
// start := time.Now()
|
||||||
|
// fmt.Printf("--------GetCandidateCap---------\n")
|
||||||
|
//
|
||||||
|
// slot := slotValidatorMapping["validatorsState"]
|
||||||
|
// // validatorsState[_candidate].cap;
|
||||||
|
// locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
|
||||||
|
// locCandidateCap := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(1)))
|
||||||
|
// ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locCandidateCap))
|
||||||
|
// fmt.Printf("cap: %v\n", ret.Big().String())
|
||||||
|
//
|
||||||
|
// elapsed := time.Since(start)
|
||||||
|
// fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
|
// return ret.Hex()
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func GetVoterCap(state *state.StateDB, candidate, voter common.Address) *big.Int {
|
||||||
|
// //validatorsState[_candidate].voters[_voter]
|
||||||
|
// slot := slotValidatorMapping["validatorsState"]
|
||||||
|
// locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
|
||||||
|
// locCandidateVoters := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(2)))
|
||||||
|
// retByte := crypto.Keccak256(voter.Hash().Bytes(), common.BigToHash(locCandidateVoters).Bytes())
|
||||||
|
// ret := state.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BytesToHash(retByte))
|
||||||
|
// fmt.Printf("voter: %v - cap: %v\n", voter.Hex(), ret.Big().String())
|
||||||
|
// return ret.Big()
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func GetVoters(statedb *state.StateDB, candidate common.Address) []common.Address {
|
||||||
|
// start := time.Now()
|
||||||
|
// fmt.Printf("--------GetVoters---------\n")
|
||||||
|
//
|
||||||
|
// //mapping(address => address[]) voters;
|
||||||
|
// slot := slotValidatorMapping["voters"]
|
||||||
|
// locVoters := getLocMappingAtKey(candidate.Hash(), slot)
|
||||||
|
// arrLength := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locVoters))
|
||||||
|
// fmt.Printf("Voters length: %v\n", arrLength.Hex())
|
||||||
|
// keys := []common.Hash{}
|
||||||
|
// for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
|
||||||
|
// key := getLocDynamicArrAtElement(common.BigToHash(locVoters), i, 1)
|
||||||
|
// keys = append(keys, key)
|
||||||
|
// }
|
||||||
|
// rets := []common.Address{}
|
||||||
|
// for _, key := range keys {
|
||||||
|
// ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), key)
|
||||||
|
// rets = append(rets, common.HexToAddress(ret.Hex()))
|
||||||
|
// fmt.Printf("%v\n", common.HexToAddress(ret.Hex()).Hex())
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// elapsed := time.Since(start)
|
||||||
|
// fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
|
// return rets
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func GetSigners(statedb *state.StateDB, block *types.Block) []common.Address {
|
||||||
|
// methodName := "getSigners"
|
||||||
|
// fmt.Printf("---%s---\n", methodName)
|
||||||
|
// start := time.Now()
|
||||||
|
// slot := slotBlockSignerMapping["blockSigners"]
|
||||||
|
// keys := []common.Hash{}
|
||||||
|
// keyArrSlot := getLocMappingAtKey(block.Hash(), slot)
|
||||||
|
// arrSlot := statedb.GetState(common.HexToAddress(common.BlockSigners), common.BigToHash(keyArrSlot))
|
||||||
|
// arrLength := arrSlot.Big().Uint64()
|
||||||
|
// for i := uint64(0); i < arrLength; i++ {
|
||||||
|
// key := getLocDynamicArrAtElement(common.BigToHash(keyArrSlot), i, 1)
|
||||||
|
// keys = append(keys, key)
|
||||||
|
// }
|
||||||
|
// rets := []common.Address{}
|
||||||
|
// for _, key := range keys {
|
||||||
|
// ret := statedb.GetState(common.HexToAddress(common.BlockSigners), key)
|
||||||
|
// rets = append(rets, common.HexToAddress(ret.Hex()))
|
||||||
|
// fmt.Printf("%v\n", common.HexToAddress(ret.Hex()).Hex())
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// elapsed := time.Since(start)
|
||||||
|
// fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
|
// return rets
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func GetSecret(statedb *state.StateDB, address common.Address) [][32]byte {
|
||||||
|
// start := time.Now()
|
||||||
|
// fmt.Printf("--------GetSecret---------\n")
|
||||||
|
//
|
||||||
|
// slot := slotRandomizeMapping["randomSecret"]
|
||||||
|
// locSecret := getLocMappingAtKey(address.Hash(), slot)
|
||||||
|
// arrLength := statedb.GetState(common.HexToAddress(common.RandomizeSMC), common.BigToHash(locSecret))
|
||||||
|
// fmt.Printf("Secret length: %v\n", arrLength.Hex())
|
||||||
|
// keys := []common.Hash{}
|
||||||
|
// for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
|
||||||
|
// key := getLocDynamicArrAtElement(common.BigToHash(locSecret), i, 1)
|
||||||
|
// keys = append(keys, key)
|
||||||
|
// }
|
||||||
|
// rets := [][32]byte{}
|
||||||
|
// for _, key := range keys {
|
||||||
|
// ret := statedb.GetState(common.HexToAddress(common.RandomizeSMC), key)
|
||||||
|
// rets = append(rets, ret)
|
||||||
|
// fmt.Printf("ret hex: %v - ret byte: %v\n", ret.Hex(), ret.Bytes())
|
||||||
|
// }
|
||||||
|
// elapsed := time.Since(start)
|
||||||
|
//
|
||||||
|
// fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
|
// return rets
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func GetOpening(statedb *state.StateDB, address common.Address) [32]byte {
|
||||||
|
// start := time.Now()
|
||||||
|
// fmt.Printf("--------GetOpening---------\n")
|
||||||
|
//
|
||||||
|
// slot := slotRandomizeMapping["randomOpening"]
|
||||||
|
// locOpening := getLocMappingAtKey(address.Hash(), slot)
|
||||||
|
// ret := statedb.GetState(common.HexToAddress(common.RandomizeSMC), common.BigToHash(locOpening))
|
||||||
|
// fmt.Printf("ret hex: %v - ret byte: %v\n", ret.Hex(), ret.Bytes())
|
||||||
|
// elapsed := time.Since(start)
|
||||||
|
// fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
|
// return ret
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//////////////////////////////////////
|
||||||
|
///////////// Common lib /////////////
|
||||||
|
//////////////////////////////////////
|
||||||
|
//
|
||||||
|
//func getLocMappingAtKey(key common.Hash, slot uint64) *big.Int {
|
||||||
|
// slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
|
||||||
|
// retByte := crypto.Keccak256(key.Bytes(), slotHash.Bytes())
|
||||||
|
// ret := new(big.Int)
|
||||||
|
// ret.SetBytes(retByte)
|
||||||
|
// return ret
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func getLocDynamicArrAtElement(slotHash common.Hash, index uint64, elementSize uint64) common.Hash {
|
||||||
|
// slotKecBig := crypto.Keccak256Hash(slotHash.Bytes()).Big()
|
||||||
|
// //arrBig = slotKecBig + index * elementSize
|
||||||
|
// arrBig := slotKecBig.Add(slotKecBig, new(big.Int).SetUint64(index*elementSize))
|
||||||
|
// return common.BigToHash(arrBig)
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func getLocFixedArrAtElement(slot uint64, index uint64, elementSize uint64) common.Hash {
|
||||||
|
// slotBig := new(big.Int).SetUint64(slot)
|
||||||
|
// arrBig := slotBig.Add(slotBig, new(big.Int).SetUint64(index*elementSize))
|
||||||
|
// return common.BigToHash(arrBig)
|
||||||
|
//}
|
||||||
|
|
@ -38,7 +38,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/consensus/XDPoS"
|
"github.com/ethereum/go-ethereum/consensus/XDPoS"
|
||||||
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
|
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
|
||||||
randomizeContract "github.com/ethereum/go-ethereum/contracts/randomize/contract"
|
randomizeContract "github.com/ethereum/go-ethereum/contracts/randomize/contract"
|
||||||
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
|
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
|
@ -85,7 +84,8 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
||||||
// Add tx signed to local tx pool.
|
// Add tx signed to local tx pool.
|
||||||
err = pool.AddLocal(txSigned)
|
err = pool.AddLocal(txSigned)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Fail to add tx sign to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
log.Error("Fail to add tx sign to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create secret tx.
|
// Create secret tx.
|
||||||
|
|
@ -114,6 +114,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
||||||
err = pool.AddLocal(txSigned)
|
err = pool.AddLocal(txSigned)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to add tx secret to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
log.Error("Fail to add tx secret to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put randomize key into chainDb.
|
// Put randomize key into chainDb.
|
||||||
|
|
@ -125,6 +126,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
||||||
randomizeKeyValue, err := chainDb.Get(randomizeKeyName)
|
randomizeKeyValue, err := chainDb.Get(randomizeKeyName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to get randomize key from state db.", "error", err)
|
log.Error("Fail to get randomize key from state db.", "error", err)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
tx, err := BuildTxOpeningRandomize(nonce+1, common.HexToAddress(common.RandomizeSMC), randomizeKeyValue)
|
tx, err := BuildTxOpeningRandomize(nonce+1, common.HexToAddress(common.RandomizeSMC), randomizeKeyValue)
|
||||||
|
|
@ -141,6 +143,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
||||||
err = pool.AddLocal(txSigned)
|
err = pool.AddLocal(txSigned)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to add tx opening to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
log.Error("Fail to add tx opening to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear randomize key in state db.
|
// Clear randomize key in state db.
|
||||||
|
|
@ -195,7 +198,12 @@ func BuildTxOpeningRandomize(nonce uint64, randomizeAddr common.Address, randomi
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get signers signed for blockNumber from blockSigner contract.
|
// Get signers signed for blockNumber from blockSigner contract.
|
||||||
func GetSignersFromContract(addrBlockSigner common.Address, client bind.ContractBackend, blockHash common.Hash) ([]common.Address, error) {
|
func GetSignersFromContract(state *state.StateDB, block *types.Block) ([]common.Address, error) {
|
||||||
|
return GetSigners(state, block), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get signers signed for blockNumber from blockSigner contract.
|
||||||
|
func GetSignersByExecutingEVM(addrBlockSigner common.Address, client bind.ContractBackend, blockHash common.Hash) ([]common.Address, error) {
|
||||||
blockSigner, err := contract.NewBlockSigner(addrBlockSigner, client)
|
blockSigner, err := contract.NewBlockSigner(addrBlockSigner, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail get instance of blockSigner", "error", err)
|
log.Error("Fail get instance of blockSigner", "error", err)
|
||||||
|
|
@ -207,7 +215,6 @@ func GetSignersFromContract(addrBlockSigner common.Address, client bind.Contract
|
||||||
log.Error("Fail get block signers", "error", err)
|
log.Error("Fail get block signers", "error", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return addrs, nil
|
return addrs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -289,6 +296,7 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
|
||||||
intNumber, err := strconv.Atoi(decryptSecret)
|
intNumber, err := strconv.Atoi(decryptSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Can not convert string to integer", "error", err)
|
log.Error("Can not convert string to integer", "error", err)
|
||||||
|
return -1, err
|
||||||
}
|
}
|
||||||
random = int64(intNumber)
|
random = int64(intNumber)
|
||||||
}
|
}
|
||||||
|
|
@ -299,23 +307,44 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate reward for reward checkpoint.
|
// Calculate reward for reward checkpoint.
|
||||||
func GetRewardForCheckpoint(chain consensus.ChainReader, blockSignerAddr common.Address, number uint64, rCheckpoint uint64, client bind.ContractBackend, totalSigner *uint64) (map[common.Address]*rewardLog, error) {
|
func GetRewardForCheckpoint(c *XDPoS.XDPoS, chain consensus.ChainReader, header *types.Header, rCheckpoint uint64, totalSigner *uint64) (map[common.Address]*rewardLog, error) {
|
||||||
// Not reward for singer of genesis block and only calculate reward at checkpoint block.
|
// Not reward for singer of genesis block and only calculate reward at checkpoint block.
|
||||||
|
number := header.Number.Uint64()
|
||||||
prevCheckpoint := number - (rCheckpoint * 2)
|
prevCheckpoint := number - (rCheckpoint * 2)
|
||||||
startBlockNumber := prevCheckpoint + 1
|
startBlockNumber := prevCheckpoint + 1
|
||||||
endBlockNumber := startBlockNumber + rCheckpoint - 1
|
endBlockNumber := startBlockNumber + rCheckpoint - 1
|
||||||
signers := make(map[common.Address]*rewardLog)
|
signers := make(map[common.Address]*rewardLog)
|
||||||
prevHeaderCheckpoint := chain.GetHeaderByNumber(prevCheckpoint)
|
mapBlkHash := map[uint64]common.Hash{}
|
||||||
masternodes := XDPoS.GetMasternodesFromCheckpointHeader(prevHeaderCheckpoint)
|
|
||||||
|
|
||||||
if len(masternodes) > 0 {
|
data := make(map[common.Hash][]common.Address)
|
||||||
for i := startBlockNumber; i <= endBlockNumber; i++ {
|
for i := prevCheckpoint + (rCheckpoint * 2) - 1; i >= startBlockNumber; i-- {
|
||||||
block := chain.GetHeaderByNumber(i)
|
header = chain.GetHeader(header.ParentHash, i)
|
||||||
addrs, err := GetSignersFromContract(blockSignerAddr, client, block.Hash())
|
mapBlkHash[i] = header.Hash()
|
||||||
if err != nil {
|
signData, ok := c.BlockSigners.Get(header.Hash())
|
||||||
log.Error("Fail to get signers from smartcontract.", "error", err, "blockNumber", i)
|
if !ok {
|
||||||
return nil, err
|
log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", i)
|
||||||
|
block := chain.GetBlock(header.Hash(), i)
|
||||||
|
txs := block.Transactions()
|
||||||
|
if !chain.Config().IsTIPSigning(header.Number) {
|
||||||
|
receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), i)
|
||||||
|
signData = c.CacheData(header, txs, receipts)
|
||||||
|
} else {
|
||||||
|
signData = c.CacheSigner(header.Hash(), txs)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
txs := signData.([]*types.Transaction)
|
||||||
|
for _, tx := range txs {
|
||||||
|
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
|
||||||
|
from := *tx.From()
|
||||||
|
data[blkHash] = append(data[blkHash], from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header = chain.GetHeader(header.ParentHash, prevCheckpoint)
|
||||||
|
masternodes := XDPoS.GetMasternodesFromCheckpointHeader(header)
|
||||||
|
|
||||||
|
for i := startBlockNumber; i <= endBlockNumber; i++ {
|
||||||
|
if i%common.MergeSignRange == 0 || !chain.Config().IsTIP2019(big.NewInt(int64(i))) {
|
||||||
|
addrs := data[mapBlkHash[i]]
|
||||||
// Filter duplicate address.
|
// Filter duplicate address.
|
||||||
if len(addrs) > 0 {
|
if len(addrs) > 0 {
|
||||||
addrSigners := make(map[common.Address]bool)
|
addrSigners := make(map[common.Address]bool)
|
||||||
|
|
@ -374,46 +403,27 @@ func CalculateRewardForSigner(chainReward *big.Int, signers map[common.Address]*
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get candidate owner by address.
|
// Get candidate owner by address.
|
||||||
func GetCandidatesOwnerBySigner(validator *contractValidator.XDCValidator, signerAddr common.Address) common.Address {
|
func GetCandidatesOwnerBySigner(state *state.StateDB, signerAddr common.Address) common.Address {
|
||||||
owner := signerAddr
|
owner := GetCandidateOwner(state, signerAddr)
|
||||||
opts := new(bind.CallOpts)
|
|
||||||
owner, err := validator.GetCandidateOwner(opts, signerAddr)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Fail get candidate owner", "error", err)
|
|
||||||
return owner
|
|
||||||
}
|
|
||||||
|
|
||||||
return owner
|
return owner
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate reward for holders.
|
func CalculateRewardForHolders(foundationWalletAddr common.Address, state *state.StateDB, signer common.Address, calcReward *big.Int, blockNumber uint64) (error, map[common.Address]*big.Int) {
|
||||||
func CalculateRewardForHolders(foudationWalletAddr common.Address, validator *contractValidator.XDCValidator, state *state.StateDB, signer common.Address, calcReward *big.Int) (error, map[common.Address]*big.Int) {
|
rewards, err := GetRewardBalancesRate(foundationWalletAddr, state, signer, calcReward, blockNumber)
|
||||||
rewards, err := GetRewardBalancesRate(foudationWalletAddr, signer, calcReward, validator)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err, nil
|
return err, nil
|
||||||
}
|
}
|
||||||
if len(rewards) > 0 {
|
|
||||||
for holder, reward := range rewards {
|
|
||||||
state.AddBalance(holder, reward)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, rewards
|
return nil, rewards
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get reward balance rates for master node, founder and holders.
|
func GetRewardBalancesRate(foundationWalletAddr common.Address, state *state.StateDB, masterAddr common.Address, totalReward *big.Int, blockNumber uint64) (map[common.Address]*big.Int, error) {
|
||||||
func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common.Address, totalReward *big.Int, validator *contractValidator.XDCValidator) (map[common.Address]*big.Int, error) {
|
owner := GetCandidatesOwnerBySigner(state, masterAddr)
|
||||||
owner := GetCandidatesOwnerBySigner(validator, masterAddr)
|
|
||||||
balances := make(map[common.Address]*big.Int)
|
balances := make(map[common.Address]*big.Int)
|
||||||
rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardMasterPercent))
|
rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardMasterPercent))
|
||||||
rewardMaster = new(big.Int).Div(rewardMaster, new(big.Int).SetInt64(100))
|
rewardMaster = new(big.Int).Div(rewardMaster, new(big.Int).SetInt64(100))
|
||||||
balances[owner] = rewardMaster
|
balances[owner] = rewardMaster
|
||||||
// Get voters for masternode.
|
// Get voters for masternode.
|
||||||
opts := new(bind.CallOpts)
|
voters := GetVoters(state, masterAddr)
|
||||||
voters, err := validator.GetVoters(opts, masterAddr)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Fail to get voters", "error", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(voters) > 0 {
|
if len(voters) > 0 {
|
||||||
totalVoterReward := new(big.Int).Mul(totalReward, new(big.Int).SetUint64(common.RewardVoterPercent))
|
totalVoterReward := new(big.Int).Mul(totalReward, new(big.Int).SetUint64(common.RewardVoterPercent))
|
||||||
|
|
@ -422,12 +432,10 @@ func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common
|
||||||
// Get voters capacities.
|
// Get voters capacities.
|
||||||
voterCaps := make(map[common.Address]*big.Int)
|
voterCaps := make(map[common.Address]*big.Int)
|
||||||
for _, voteAddr := range voters {
|
for _, voteAddr := range voters {
|
||||||
voterCap, err := validator.GetVoterCap(opts, masterAddr, voteAddr)
|
if _, ok := voterCaps[voteAddr]; ok && common.TIP2019Block.Uint64() <= blockNumber {
|
||||||
if err != nil {
|
continue
|
||||||
log.Error("Fail to get vote capacity", "error", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
voterCap := GetVoterCap(state, masterAddr, voteAddr)
|
||||||
totalCap.Add(totalCap, voterCap)
|
totalCap.Add(totalCap, voterCap)
|
||||||
voterCaps[voteAddr] = voterCap
|
voterCaps[voteAddr] = voterCap
|
||||||
}
|
}
|
||||||
|
|
@ -447,9 +455,9 @@ func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foudationReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardFoundationPercent))
|
foundationReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardFoundationPercent))
|
||||||
foudationReward = new(big.Int).Div(foudationReward, new(big.Int).SetInt64(100))
|
foundationReward = new(big.Int).Div(foundationReward, new(big.Int).SetInt64(100))
|
||||||
balances[foudationWalletAddr] = foudationReward
|
balances[foundationWalletAddr] = foundationReward
|
||||||
|
|
||||||
jsonHolders, err := json.Marshal(balances)
|
jsonHolders, err := json.Marshal(balances)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -1,656 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"constant": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "_candidate",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "propose",
|
|
||||||
"outputs": [],
|
|
||||||
"payable": true,
|
|
||||||
"stateMutability": "payable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "_candidate",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "resign",
|
|
||||||
"outputs": [],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "_candidate",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "_cap",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "unvote",
|
|
||||||
"outputs": [],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "kychash",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "uploadKYC",
|
|
||||||
"outputs": [],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "_candidate",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "vote",
|
|
||||||
"outputs": [],
|
|
||||||
"payable": true,
|
|
||||||
"stateMutability": "payable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "_invalidCandidate",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "voteInvalidKYC",
|
|
||||||
"outputs": [],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "_blockNumber",
|
|
||||||
"type": "uint256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "_index",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "withdraw",
|
|
||||||
"outputs": [],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "_candidates",
|
|
||||||
"type": "address[]"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "_caps",
|
|
||||||
"type": "uint256[]"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "_firstOwner",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "_minCandidateCap",
|
|
||||||
"type": "uint256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "_minVoterCap",
|
|
||||||
"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": "_blockNumber",
|
|
||||||
"type": "uint256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"indexed": false,
|
|
||||||
"name": "_cap",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "Withdraw",
|
|
||||||
"type": "event"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "candidateCount",
|
|
||||||
"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": "candidateWithdrawDelay",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"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": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "_candidate",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "getCandidateOwner",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "getCandidates",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "address[]"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "_address",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "getKYC",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "getOwnerCount",
|
|
||||||
"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": "_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": "_blockNumber",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "getWithdrawCap",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "hasVotedInvalid",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "bool"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "invalidKYCCount",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "_invalidCandidate",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "invalidPercent",
|
|
||||||
"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": "",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "KYCString",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"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": "minCandidateCap",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "minVoterCap",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "owners",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "ownerToCandidate",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "voterWithdrawDelay",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,54 +1,8 @@
|
||||||
pragma solidity ^0.4.21;
|
pragma solidity ^0.4.21;
|
||||||
|
|
||||||
// This contract is under development.
|
import "./libs/SafeMath.sol";
|
||||||
// Refer to readme for further details.
|
|
||||||
|
|
||||||
|
contract XDCalidator {
|
||||||
library SafeMath {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Multiplies two numbers, throws on overflow.
|
|
||||||
*/
|
|
||||||
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
|
|
||||||
if (a == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
uint256 c = a * b;
|
|
||||||
assert(c / a == b);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Integer division of two numbers, truncating the quotient.
|
|
||||||
*/
|
|
||||||
function div(uint256 a, uint256 b) internal pure returns (uint256) {
|
|
||||||
// assert(b > 0); // Solidity automatically throws when dividing by 0
|
|
||||||
// uint256 c = a / b;
|
|
||||||
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
|
|
||||||
return a / b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
|
|
||||||
*/
|
|
||||||
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
|
|
||||||
assert(b <= a);
|
|
||||||
return a - b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Adds two numbers, throws on overflow.
|
|
||||||
*/
|
|
||||||
function add(uint256 a, uint256 b) internal pure returns (uint256) {
|
|
||||||
uint256 c = a + b;
|
|
||||||
assert(c >= a);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
contract XDCValidator {
|
|
||||||
using SafeMath for uint256;
|
using SafeMath for uint256;
|
||||||
|
|
||||||
event Vote(address _voter, address _candidate, uint256 _cap);
|
event Vote(address _voter, address _candidate, uint256 _cap);
|
||||||
|
|
@ -73,14 +27,6 @@ contract XDCValidator {
|
||||||
|
|
||||||
mapping(address => ValidatorState) validatorsState;
|
mapping(address => ValidatorState) validatorsState;
|
||||||
mapping(address => address[]) voters;
|
mapping(address => address[]) voters;
|
||||||
|
|
||||||
// Mapping structures added for KYC feature.
|
|
||||||
mapping(address => string) public KYCString;
|
|
||||||
mapping(address => uint) public invalidKYCCount;
|
|
||||||
mapping(address => mapping(address => bool)) public hasVotedInvalid;
|
|
||||||
mapping(address => address[]) public ownerToCandidate;
|
|
||||||
address[] public owners;
|
|
||||||
|
|
||||||
address[] public candidates;
|
address[] public candidates;
|
||||||
|
|
||||||
uint256 public candidateCount = 0;
|
uint256 public candidateCount = 0;
|
||||||
|
|
@ -91,26 +37,16 @@ contract XDCValidator {
|
||||||
uint256 public voterWithdrawDelay;
|
uint256 public voterWithdrawDelay;
|
||||||
|
|
||||||
modifier onlyValidCandidateCap {
|
modifier onlyValidCandidateCap {
|
||||||
// anyone can deposit X XDC to become a candidate
|
// anyone can deposit X XDCto become a candidate
|
||||||
require(msg.value >= minCandidateCap);
|
require(msg.value >= minCandidateCap);
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier onlyValidVoterCap {
|
modifier onlyValidVoterCap {
|
||||||
|
|
||||||
require(msg.value >= minVoterCap);
|
require(msg.value >= minVoterCap);
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier onlyKYCWhitelisted {
|
|
||||||
if(bytes(KYCString[msg.sender]).length != 0)
|
|
||||||
{_;}
|
|
||||||
else{
|
|
||||||
if (ownerToCandidate[msg.sender].length > 0)
|
|
||||||
{_;}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
modifier onlyOwner(address _candidate) {
|
modifier onlyOwner(address _candidate) {
|
||||||
require(validatorsState[_candidate].owner == msg.sender);
|
require(validatorsState[_candidate].owner == msg.sender);
|
||||||
_;
|
_;
|
||||||
|
|
@ -147,7 +83,7 @@ contract XDCValidator {
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
function XDCValidator (
|
function XDCalidator (
|
||||||
address[] _candidates,
|
address[] _candidates,
|
||||||
uint256[] _caps,
|
uint256[] _caps,
|
||||||
address _firstOwner,
|
address _firstOwner,
|
||||||
|
|
@ -163,7 +99,7 @@ contract XDCValidator {
|
||||||
candidateWithdrawDelay = _candidateWithdrawDelay;
|
candidateWithdrawDelay = _candidateWithdrawDelay;
|
||||||
voterWithdrawDelay = _voterWithdrawDelay;
|
voterWithdrawDelay = _voterWithdrawDelay;
|
||||||
candidateCount = _candidates.length;
|
candidateCount = _candidates.length;
|
||||||
owners.push(_firstOwner);
|
|
||||||
for (uint256 i = 0; i < _candidates.length; i++) {
|
for (uint256 i = 0; i < _candidates.length; i++) {
|
||||||
candidates.push(_candidates[i]);
|
candidates.push(_candidates[i]);
|
||||||
validatorsState[_candidates[i]] = ValidatorState({
|
validatorsState[_candidates[i]] = ValidatorState({
|
||||||
|
|
@ -172,20 +108,11 @@ contract XDCValidator {
|
||||||
cap: _caps[i]
|
cap: _caps[i]
|
||||||
});
|
});
|
||||||
voters[_candidates[i]].push(_firstOwner);
|
voters[_candidates[i]].push(_firstOwner);
|
||||||
ownerToCandidate[_firstOwner].push(_candidates[i]);
|
|
||||||
validatorsState[_candidates[i]].voters[_firstOwner] = minCandidateCap;
|
validatorsState[_candidates[i]].voters[_firstOwner] = minCandidateCap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function propose(address _candidate) external payable onlyValidCandidateCap onlyNotCandidate(_candidate) {
|
||||||
// uploadKYC : anyone can upload a KYC; its not equivalent to becoming an owner.
|
|
||||||
function uploadKYC(string kychash) external {
|
|
||||||
require(bytes(KYCString[msg.sender]).length==0);
|
|
||||||
KYCString[msg.sender]=kychash;
|
|
||||||
}
|
|
||||||
|
|
||||||
// propose : any non-candidate who has uploaded its KYC can become an owner by proposing a candidate.
|
|
||||||
function propose(address _candidate) external payable onlyValidCandidateCap onlyKYCWhitelisted onlyNotCandidate(_candidate) {
|
|
||||||
uint256 cap = validatorsState[_candidate].cap.add(msg.value);
|
uint256 cap = validatorsState[_candidate].cap.add(msg.value);
|
||||||
candidates.push(_candidate);
|
candidates.push(_candidate);
|
||||||
validatorsState[_candidate] = ValidatorState({
|
validatorsState[_candidate] = ValidatorState({
|
||||||
|
|
@ -195,11 +122,6 @@ contract XDCValidator {
|
||||||
});
|
});
|
||||||
validatorsState[_candidate].voters[msg.sender] = validatorsState[_candidate].voters[msg.sender].add(msg.value);
|
validatorsState[_candidate].voters[msg.sender] = validatorsState[_candidate].voters[msg.sender].add(msg.value);
|
||||||
candidateCount = candidateCount.add(1);
|
candidateCount = candidateCount.add(1);
|
||||||
if (ownerToCandidate[msg.sender].length ==0){
|
|
||||||
owners.push(msg.sender);
|
|
||||||
|
|
||||||
}
|
|
||||||
ownerToCandidate[msg.sender].push(_candidate);
|
|
||||||
voters[_candidate].push(msg.sender);
|
voters[_candidate].push(msg.sender);
|
||||||
emit Propose(msg.sender, _candidate, msg.value);
|
emit Propose(msg.sender, _candidate, msg.value);
|
||||||
}
|
}
|
||||||
|
|
@ -276,59 +198,6 @@ contract XDCValidator {
|
||||||
emit Resign(msg.sender, _candidate);
|
emit Resign(msg.sender, _candidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// voteInvalidKYC : any candidate can vote for invalid KYC i.e. a particular candidate's owner has uploaded a bad KYC.
|
|
||||||
// On securing 75% votes against an owner ( not candidate ), owner & all its candidates will lose their funds.
|
|
||||||
function voteInvalidKYC(address _invalidCandidate) onlyValidCandidate(msg.sender) onlyValidCandidate(_invalidCandidate) public {
|
|
||||||
address candidateOwner = getCandidateOwner(msg.sender);
|
|
||||||
address _invalidMasternode = getCandidateOwner(_invalidCandidate);
|
|
||||||
require(!hasVotedInvalid[candidateOwner][_invalidMasternode]);
|
|
||||||
hasVotedInvalid[candidateOwner][_invalidMasternode] = true;
|
|
||||||
invalidKYCCount[_invalidMasternode] += 1;
|
|
||||||
if( invalidKYCCount[_invalidMasternode]*100/getOwnerCount() >= 75 ){
|
|
||||||
// 75% owners say that the KYC is invalid
|
|
||||||
for (uint i=0;i<candidates.length;i++){
|
|
||||||
if (getCandidateOwner(candidates[i])==_invalidMasternode){
|
|
||||||
// logic to remove cap.
|
|
||||||
candidateCount = candidateCount.sub(1);
|
|
||||||
delete candidates[i];
|
|
||||||
delete validatorsState[candidates[i]];
|
|
||||||
delete KYCString[_invalidMasternode];
|
|
||||||
delete ownerToCandidate[_invalidMasternode];
|
|
||||||
delete invalidKYCCount[_invalidMasternode];
|
|
||||||
for(uint k=0;k<owners.length;k++){
|
|
||||||
if (owners[k]==_invalidMasternode){
|
|
||||||
delete owners[k];
|
|
||||||
owners.length--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// invalidPercent : get votes against an owner in percentage.
|
|
||||||
function invalidPercent(address _invalidCandidate) onlyValidCandidate(_invalidCandidate) view public returns(uint){
|
|
||||||
address _invalidMasternode = getCandidateOwner(_invalidCandidate);
|
|
||||||
return (invalidKYCCount[_invalidMasternode]*100/getOwnerCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// getOwnerCount : get count of total owners; accounts who own atleast one masternode.
|
|
||||||
function getOwnerCount() view public returns (uint){
|
|
||||||
return owners.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// getKYC : get KYC uploaded of the owner of the given masternode or the owner themselves
|
|
||||||
function getKYC(address _address) view public returns (string) {
|
|
||||||
if(isCandidate(_address)){
|
|
||||||
return KYCString[getCandidateOwner(_address)];
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
return KYCString[_address];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function withdraw(uint256 _blockNumber, uint _index) public onlyValidWithdraw(_blockNumber, _index) {
|
function withdraw(uint256 _blockNumber, uint _index) public onlyValidWithdraw(_blockNumber, _index) {
|
||||||
uint256 cap = withdrawsState[msg.sender].caps[_blockNumber];
|
uint256 cap = withdrawsState[msg.sender].caps[_blockNumber];
|
||||||
delete withdrawsState[msg.sender].caps[_blockNumber];
|
delete withdrawsState[msg.sender].caps[_blockNumber];
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -16,11 +16,10 @@
|
||||||
package validator
|
package validator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/contracts/validator/contract"
|
"github.com/ethereum/go-ethereum/contracts/validator/contract"
|
||||||
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Validator struct {
|
type Validator struct {
|
||||||
|
|
@ -45,12 +44,12 @@ func NewValidator(transactOpts *bind.TransactOpts, contractAddr common.Address,
|
||||||
|
|
||||||
func DeployValidator(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend, validatorAddress []common.Address, caps []*big.Int, ownerAddress common.Address) (common.Address, *Validator, error) {
|
func DeployValidator(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend, validatorAddress []common.Address, caps []*big.Int, ownerAddress common.Address) (common.Address, *Validator, error) {
|
||||||
minDeposit := new(big.Int)
|
minDeposit := new(big.Int)
|
||||||
minDeposit.SetString("10000000000000000000000000", 10)
|
minDeposit.SetString("50000000000000000000000", 10)
|
||||||
minVoterCap := new(big.Int)
|
minVoterCap := new(big.Int)
|
||||||
minVoterCap.SetString("25000000000000000000000", 10)
|
minVoterCap.SetString("10000000000000000000", 10)
|
||||||
// Deposit 10Mil XDC
|
// Deposit 50K XDC
|
||||||
// Min Voter Cap 25K XDC
|
// Min Voter Cap 10 XDC
|
||||||
// 21 masternodes
|
// 150 masternodes
|
||||||
// Candidate Delay Withdraw 30 days = 1296000 blocks
|
// Candidate Delay Withdraw 30 days = 1296000 blocks
|
||||||
// Voter Delay Withdraw 2 days = 86400 blocks
|
// Voter Delay Withdraw 2 days = 86400 blocks
|
||||||
validatorAddr, _, _, err := contract.DeployXDCValidator(transactOpts, contractBackend, validatorAddress, caps, ownerAddress, minDeposit, minVoterCap, big.NewInt(150), big.NewInt(1296000), big.NewInt(86400))
|
validatorAddr, _, _, err := contract.DeployXDCValidator(transactOpts, contractBackend, validatorAddress, caps, ownerAddress, minDeposit, minVoterCap, big.NewInt(150), big.NewInt(1296000), big.NewInt(86400))
|
||||||
|
|
|
||||||
|
|
@ -17,18 +17,19 @@ package validator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/contracts"
|
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
|
||||||
"github.com/ethereum/go-ethereum/contracts/validator/contract"
|
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"math/rand"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -94,7 +95,7 @@ func TestRewardBalance(t *testing.T) {
|
||||||
// validatorAddr, _, baseValidator, err := contract.DeployXDCValidator(transactOpts, contractBackend, big.NewInt(50000), big.NewInt(99), big.NewInt(100), big.NewInt(100))
|
// validatorAddr, _, baseValidator, err := contract.DeployXDCValidator(transactOpts, contractBackend, big.NewInt(50000), big.NewInt(99), big.NewInt(100), big.NewInt(100))
|
||||||
validatorCap := new(big.Int)
|
validatorCap := new(big.Int)
|
||||||
validatorCap.SetString("50000000000000000000000", 10)
|
validatorCap.SetString("50000000000000000000000", 10)
|
||||||
validatorAddr, _, baseValidator, err := contract.DeployXDCValidator(
|
validatorAddr, _, baseValidator, err := contractValidator.DeployXDCValidator(
|
||||||
transactOpts,
|
transactOpts,
|
||||||
contractBackend,
|
contractBackend,
|
||||||
[]common.Address{addr},
|
[]common.Address{addr},
|
||||||
|
|
@ -144,7 +145,7 @@ func TestRewardBalance(t *testing.T) {
|
||||||
|
|
||||||
foundationAddr := common.HexToAddress(common.FoudationAddr)
|
foundationAddr := common.HexToAddress(common.FoudationAddr)
|
||||||
totalReward := new(big.Int).SetInt64(15 * 1000)
|
totalReward := new(big.Int).SetInt64(15 * 1000)
|
||||||
rewards, err := contracts.GetRewardBalancesRate(foundationAddr, acc3Addr, totalReward, baseValidator)
|
rewards, err := GetRewardBalancesRate(foundationAddr, acc3Addr, totalReward, baseValidator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("Fail to get reward balances rate.", err)
|
t.Error("Fail to get reward balances rate.", err)
|
||||||
}
|
}
|
||||||
|
|
@ -175,3 +176,76 @@ func TestRewardBalance(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common.Address, totalReward *big.Int, validator *contractValidator.XDCValidator) (map[common.Address]*big.Int, error) {
|
||||||
|
owner := GetCandidatesOwnerBySigner(validator, masterAddr)
|
||||||
|
balances := make(map[common.Address]*big.Int)
|
||||||
|
rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardMasterPercent))
|
||||||
|
rewardMaster = new(big.Int).Div(rewardMaster, new(big.Int).SetInt64(100))
|
||||||
|
balances[owner] = rewardMaster
|
||||||
|
// Get voters for masternode.
|
||||||
|
opts := new(bind.CallOpts)
|
||||||
|
voters, err := validator.GetVoters(opts, masterAddr)
|
||||||
|
if err != nil {
|
||||||
|
log.Crit("Fail to get voters", "error", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(voters) > 0 {
|
||||||
|
totalVoterReward := new(big.Int).Mul(totalReward, new(big.Int).SetUint64(common.RewardVoterPercent))
|
||||||
|
totalVoterReward = new(big.Int).Div(totalVoterReward, new(big.Int).SetUint64(100))
|
||||||
|
totalCap := new(big.Int)
|
||||||
|
// Get voters capacities.
|
||||||
|
voterCaps := make(map[common.Address]*big.Int)
|
||||||
|
for _, voteAddr := range voters {
|
||||||
|
var voterCap *big.Int
|
||||||
|
|
||||||
|
voterCap, err = validator.GetVoterCap(opts, masterAddr, voteAddr)
|
||||||
|
if err != nil {
|
||||||
|
log.Crit("Fail to get vote capacity", "error", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
totalCap.Add(totalCap, voterCap)
|
||||||
|
voterCaps[voteAddr] = voterCap
|
||||||
|
}
|
||||||
|
if totalCap.Cmp(new(big.Int).SetInt64(0)) > 0 {
|
||||||
|
for addr, voteCap := range voterCaps {
|
||||||
|
// Only valid voter has cap > 0.
|
||||||
|
if voteCap.Cmp(new(big.Int).SetInt64(0)) > 0 {
|
||||||
|
rcap := new(big.Int).Mul(totalVoterReward, voteCap)
|
||||||
|
rcap = new(big.Int).Div(rcap, totalCap)
|
||||||
|
if balances[addr] != nil {
|
||||||
|
balances[addr].Add(balances[addr], rcap)
|
||||||
|
} else {
|
||||||
|
balances[addr] = rcap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foudationReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardFoundationPercent))
|
||||||
|
foudationReward = new(big.Int).Div(foudationReward, new(big.Int).SetInt64(100))
|
||||||
|
balances[foudationWalletAddr] = foudationReward
|
||||||
|
|
||||||
|
jsonHolders, err := json.Marshal(balances)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Fail to parse json holders", "error", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
log.Info("Holders reward", "holders", string(jsonHolders), "master node", masterAddr.String())
|
||||||
|
|
||||||
|
return balances, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCandidatesOwnerBySigner(validator *contractValidator.XDCValidator, signerAddr common.Address) common.Address {
|
||||||
|
owner := signerAddr
|
||||||
|
opts := new(bind.CallOpts)
|
||||||
|
owner, err := validator.GetCandidateOwner(opts, signerAddr)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Fail get candidate owner", "error", err)
|
||||||
|
return owner
|
||||||
|
}
|
||||||
|
|
||||||
|
return owner
|
||||||
|
}
|
||||||
|
|
|
||||||
88
contracts/validatorReader.go
Normal file
88
contracts/validatorReader.go
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
package contracts
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
slotValidatorMapping = map[string]uint64{
|
||||||
|
"withdrawsState": 0,
|
||||||
|
"validatorsState": 1,
|
||||||
|
"voters": 2,
|
||||||
|
"candidates": 3,
|
||||||
|
"candidateCount": 4,
|
||||||
|
"minCandidateCap": 5,
|
||||||
|
"minVoterCap": 6,
|
||||||
|
"maxValidatorNumber": 7,
|
||||||
|
"candidateWithdrawDelay": 8,
|
||||||
|
"voterWithdrawDelay": 9,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetCandidates(statedb *state.StateDB) []common.Address {
|
||||||
|
slot := slotValidatorMapping["candidates"]
|
||||||
|
slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
|
||||||
|
arrLength := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), slotHash)
|
||||||
|
keys := []common.Hash{}
|
||||||
|
for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
|
||||||
|
key := getLocDynamicArrAtElement(slotHash, i, 1)
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
rets := []common.Address{}
|
||||||
|
for _, key := range keys {
|
||||||
|
ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), key)
|
||||||
|
rets = append(rets, common.HexToAddress(ret.Hex()))
|
||||||
|
}
|
||||||
|
return rets
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCandidateOwner(statedb *state.StateDB, candidate common.Address) common.Address {
|
||||||
|
slot := slotValidatorMapping["validatorsState"]
|
||||||
|
// validatorsState[_candidate].owner;
|
||||||
|
locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
|
||||||
|
locCandidateOwner := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(0)))
|
||||||
|
ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locCandidateOwner))
|
||||||
|
return common.HexToAddress(ret.Hex())
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCandidateCap(statedb *state.StateDB, parsed abi.ABI, candidate common.Address) string {
|
||||||
|
slot := slotValidatorMapping["validatorsState"]
|
||||||
|
// validatorsState[_candidate].cap;
|
||||||
|
locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
|
||||||
|
locCandidateCap := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(1)))
|
||||||
|
ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locCandidateCap))
|
||||||
|
return ret.Hex()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetVoters(statedb *state.StateDB, candidate common.Address) []common.Address {
|
||||||
|
//mapping(address => address[]) voters;
|
||||||
|
slot := slotValidatorMapping["voters"]
|
||||||
|
locVoters := getLocMappingAtKey(candidate.Hash(), slot)
|
||||||
|
arrLength := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locVoters))
|
||||||
|
keys := []common.Hash{}
|
||||||
|
for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
|
||||||
|
key := getLocDynamicArrAtElement(common.BigToHash(locVoters), i, 1)
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
rets := []common.Address{}
|
||||||
|
for _, key := range keys {
|
||||||
|
ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), key)
|
||||||
|
rets = append(rets, common.HexToAddress(ret.Hex()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return rets
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetVoterCap(state *state.StateDB, candidate, voter common.Address) *big.Int {
|
||||||
|
slot := slotValidatorMapping["validatorsState"]
|
||||||
|
locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
|
||||||
|
locCandidateVoters := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(2)))
|
||||||
|
retByte := crypto.Keccak256(voter.Hash().Bytes(), common.BigToHash(locCandidateVoters).Bytes())
|
||||||
|
ret := state.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BytesToHash(retByte))
|
||||||
|
return ret.Big()
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue