mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 10:50:44 +00:00
updated smartcontract issue
This commit is contained in:
parent
1b13b3a305
commit
0b6a7ed1ad
10 changed files with 1431 additions and 912 deletions
|
|
@ -1,33 +0,0 @@
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
@ -1,282 +0,0 @@
|
||||||
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)
|
|
||||||
//}
|
|
||||||
656
contracts/validator/contract/XDCValidator.abi
Normal file
656
contracts/validator/contract/XDCValidator.abi
Normal file
|
|
@ -0,0 +1,656 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
]
|
||||||
1
contracts/validator/contract/XDCValidator.bin
Normal file
1
contracts/validator/contract/XDCValidator.bin
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,6 +1,52 @@
|
||||||
pragma solidity ^0.4.21;
|
pragma solidity ^0.4.21;
|
||||||
|
|
||||||
import "./libs/SafeMath.sol";
|
// This contract is under development.
|
||||||
|
// Refer to readme for further details.
|
||||||
|
|
||||||
|
|
||||||
|
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 {
|
contract XDCValidator {
|
||||||
using SafeMath for uint256;
|
using SafeMath for uint256;
|
||||||
|
|
@ -27,6 +73,14 @@ 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;
|
||||||
|
|
@ -43,10 +97,20 @@ contract XDCValidator {
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
_;
|
_;
|
||||||
|
|
@ -99,7 +163,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({
|
||||||
|
|
@ -108,11 +172,20 @@ 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({
|
||||||
|
|
@ -122,6 +195,11 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
@ -198,6 +276,59 @@ 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
|
|
@ -1,10 +1,26 @@
|
||||||
|
// Copyright (c) 2018 XDCchain
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
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 {
|
||||||
|
|
@ -29,12 +45,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("50000000000000000000000", 10)
|
minDeposit.SetString("10000000000000000000000000", 10)
|
||||||
minVoterCap := new(big.Int)
|
minVoterCap := new(big.Int)
|
||||||
minVoterCap.SetString("10000000000000000000", 10)
|
minVoterCap.SetString("25000000000000000000000", 10)
|
||||||
// Deposit 50K XDC
|
// Deposit 10Mil XDC
|
||||||
// Min Voter Cap 10 XDC
|
// Min Voter Cap 25K XDC
|
||||||
// 150 masternodes
|
// 21 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))
|
||||||
|
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
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