updated smartcontract issue

This commit is contained in:
parmarrushabh 2019-02-24 17:50:28 +05:30
parent 1b13b3a305
commit 0b6a7ed1ad
10 changed files with 1431 additions and 912 deletions

View file

@ -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
}

View file

@ -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
}

View file

@ -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)
}

View file

@ -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)
//}

View 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"
}
]

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,52 @@
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 {
using SafeMath for uint256;
@ -27,6 +73,14 @@ contract XDCValidator {
mapping(address => ValidatorState) validatorsState;
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;
uint256 public candidateCount = 0;
@ -43,10 +97,20 @@ contract XDCValidator {
}
modifier onlyValidVoterCap {
require(msg.value >= minVoterCap);
_;
}
modifier onlyKYCWhitelisted {
if(bytes(KYCString[msg.sender]).length != 0)
{_;}
else{
if (ownerToCandidate[msg.sender].length > 0)
{_;}
}
}
modifier onlyOwner(address _candidate) {
require(validatorsState[_candidate].owner == msg.sender);
_;
@ -99,7 +163,7 @@ contract XDCValidator {
candidateWithdrawDelay = _candidateWithdrawDelay;
voterWithdrawDelay = _voterWithdrawDelay;
candidateCount = _candidates.length;
owners.push(_firstOwner);
for (uint256 i = 0; i < _candidates.length; i++) {
candidates.push(_candidates[i]);
validatorsState[_candidates[i]] = ValidatorState({
@ -108,11 +172,20 @@ contract XDCValidator {
cap: _caps[i]
});
voters[_candidates[i]].push(_firstOwner);
ownerToCandidate[_firstOwner].push(_candidates[i]);
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);
candidates.push(_candidate);
validatorsState[_candidate] = ValidatorState({
@ -122,6 +195,11 @@ contract XDCValidator {
});
validatorsState[_candidate].voters[msg.sender] = validatorsState[_candidate].voters[msg.sender].add(msg.value);
candidateCount = candidateCount.add(1);
if (ownerToCandidate[msg.sender].length ==0){
owners.push(msg.sender);
}
ownerToCandidate[msg.sender].push(_candidate);
voters[_candidate].push(msg.sender);
emit Propose(msg.sender, _candidate, msg.value);
}
@ -198,6 +276,59 @@ contract XDCValidator {
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) {
uint256 cap = withdrawsState[msg.sender].caps[_blockNumber];
delete withdrawsState[msg.sender].caps[_blockNumber];

File diff suppressed because one or more lines are too long

View file

@ -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
import (
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/contracts/validator/contract"
"math/big"
)
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) {
minDeposit := new(big.Int)
minDeposit.SetString("50000000000000000000000", 10)
minDeposit.SetString("10000000000000000000000000", 10)
minVoterCap := new(big.Int)
minVoterCap.SetString("10000000000000000000", 10)
// Deposit 50K XDC
// Min Voter Cap 10 XDC
// 150 masternodes
minVoterCap.SetString("25000000000000000000000", 10)
// Deposit 10Mil XDC
// Min Voter Cap 25K XDC
// 21 masternodes
// Candidate Delay Withdraw 30 days = 1296000 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))
@ -48,4 +64,4 @@ func DeployValidator(transactOpts *bind.TransactOpts, contractBackend bind.Contr
}
return validatorAddr, validator, nil
}
}

View file

@ -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()
}