mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-24 15:44:32 +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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
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
|
||||
}
|
||||
|
||||
// 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)
|
||||
func (_MultiSigWallet *MultiSigWalletSession) Required() (*big.Int, error) {
|
||||
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)
|
||||
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/contracts/blocksigner/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/state"
|
||||
"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.
|
||||
err = pool.AddLocal(txSigned)
|
||||
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.
|
||||
|
|
@ -114,6 +114,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
|||
err = pool.AddLocal(txSigned)
|
||||
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)
|
||||
return err
|
||||
}
|
||||
|
||||
// Put randomize key into chainDb.
|
||||
|
|
@ -125,6 +126,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
|||
randomizeKeyValue, err := chainDb.Get(randomizeKeyName)
|
||||
if err != nil {
|
||||
log.Error("Fail to get randomize key from state db.", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
return err
|
||||
}
|
||||
|
||||
// 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.
|
||||
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)
|
||||
if err != nil {
|
||||
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)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return addrs, nil
|
||||
}
|
||||
|
||||
|
|
@ -289,6 +296,7 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
|
|||
intNumber, err := strconv.Atoi(decryptSecret)
|
||||
if err != nil {
|
||||
log.Error("Can not convert string to integer", "error", err)
|
||||
return -1, err
|
||||
}
|
||||
random = int64(intNumber)
|
||||
}
|
||||
|
|
@ -299,23 +307,44 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
|
|||
}
|
||||
|
||||
// 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.
|
||||
number := header.Number.Uint64()
|
||||
prevCheckpoint := number - (rCheckpoint * 2)
|
||||
startBlockNumber := prevCheckpoint + 1
|
||||
endBlockNumber := startBlockNumber + rCheckpoint - 1
|
||||
signers := make(map[common.Address]*rewardLog)
|
||||
prevHeaderCheckpoint := chain.GetHeaderByNumber(prevCheckpoint)
|
||||
masternodes := XDPoS.GetMasternodesFromCheckpointHeader(prevHeaderCheckpoint)
|
||||
mapBlkHash := map[uint64]common.Hash{}
|
||||
|
||||
if len(masternodes) > 0 {
|
||||
for i := startBlockNumber; i <= endBlockNumber; i++ {
|
||||
block := chain.GetHeaderByNumber(i)
|
||||
addrs, err := GetSignersFromContract(blockSignerAddr, client, block.Hash())
|
||||
if err != nil {
|
||||
log.Error("Fail to get signers from smartcontract.", "error", err, "blockNumber", i)
|
||||
return nil, err
|
||||
data := make(map[common.Hash][]common.Address)
|
||||
for i := prevCheckpoint + (rCheckpoint * 2) - 1; i >= startBlockNumber; i-- {
|
||||
header = chain.GetHeader(header.ParentHash, i)
|
||||
mapBlkHash[i] = header.Hash()
|
||||
signData, ok := c.BlockSigners.Get(header.Hash())
|
||||
if !ok {
|
||||
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.
|
||||
if len(addrs) > 0 {
|
||||
addrSigners := make(map[common.Address]bool)
|
||||
|
|
@ -374,46 +403,27 @@ func CalculateRewardForSigner(chainReward *big.Int, signers map[common.Address]*
|
|||
}
|
||||
|
||||
// Get candidate owner by address.
|
||||
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
|
||||
}
|
||||
|
||||
func GetCandidatesOwnerBySigner(state *state.StateDB, signerAddr common.Address) common.Address {
|
||||
owner := GetCandidateOwner(state, signerAddr)
|
||||
return owner
|
||||
}
|
||||
|
||||
// Calculate reward for holders.
|
||||
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(foudationWalletAddr, signer, calcReward, validator)
|
||||
func CalculateRewardForHolders(foundationWalletAddr common.Address, state *state.StateDB, signer common.Address, calcReward *big.Int, blockNumber uint64) (error, map[common.Address]*big.Int) {
|
||||
rewards, err := GetRewardBalancesRate(foundationWalletAddr, state, signer, calcReward, blockNumber)
|
||||
if err != nil {
|
||||
return err, nil
|
||||
}
|
||||
if len(rewards) > 0 {
|
||||
for holder, reward := range rewards {
|
||||
state.AddBalance(holder, reward)
|
||||
}
|
||||
}
|
||||
return nil, rewards
|
||||
}
|
||||
|
||||
// Get reward balance rates for master node, founder and holders.
|
||||
func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common.Address, totalReward *big.Int, validator *contractValidator.XDCValidator) (map[common.Address]*big.Int, error) {
|
||||
owner := GetCandidatesOwnerBySigner(validator, masterAddr)
|
||||
func GetRewardBalancesRate(foundationWalletAddr common.Address, state *state.StateDB, masterAddr common.Address, totalReward *big.Int, blockNumber uint64) (map[common.Address]*big.Int, error) {
|
||||
owner := GetCandidatesOwnerBySigner(state, 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.Error("Fail to get voters", "error", err)
|
||||
return nil, err
|
||||
}
|
||||
voters := GetVoters(state, masterAddr)
|
||||
|
||||
if len(voters) > 0 {
|
||||
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.
|
||||
voterCaps := make(map[common.Address]*big.Int)
|
||||
for _, voteAddr := range voters {
|
||||
voterCap, err := validator.GetVoterCap(opts, masterAddr, voteAddr)
|
||||
if err != nil {
|
||||
log.Error("Fail to get vote capacity", "error", err)
|
||||
return nil, err
|
||||
if _, ok := voterCaps[voteAddr]; ok && common.TIP2019Block.Uint64() <= blockNumber {
|
||||
continue
|
||||
}
|
||||
|
||||
voterCap := GetVoterCap(state, masterAddr, voteAddr)
|
||||
totalCap.Add(totalCap, 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))
|
||||
foudationReward = new(big.Int).Div(foudationReward, new(big.Int).SetInt64(100))
|
||||
balances[foudationWalletAddr] = foudationReward
|
||||
foundationReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardFoundationPercent))
|
||||
foundationReward = new(big.Int).Div(foundationReward, new(big.Int).SetInt64(100))
|
||||
balances[foundationWalletAddr] = foundationReward
|
||||
|
||||
jsonHolders, err := json.Marshal(balances)
|
||||
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;
|
||||
|
||||
// This contract is under development.
|
||||
// Refer to readme for further details.
|
||||
import "./libs/SafeMath.sol";
|
||||
|
||||
|
||||
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 XDCalidator {
|
||||
using SafeMath for uint256;
|
||||
|
||||
event Vote(address _voter, address _candidate, uint256 _cap);
|
||||
|
|
@ -73,14 +27,6 @@ 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;
|
||||
|
|
@ -91,26 +37,16 @@ contract XDCValidator {
|
|||
uint256 public voterWithdrawDelay;
|
||||
|
||||
modifier onlyValidCandidateCap {
|
||||
// anyone can deposit X XDC to become a candidate
|
||||
// anyone can deposit X XDCto become a candidate
|
||||
require(msg.value >= minCandidateCap);
|
||||
_;
|
||||
}
|
||||
|
||||
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);
|
||||
_;
|
||||
|
|
@ -147,7 +83,7 @@ contract XDCValidator {
|
|||
_;
|
||||
}
|
||||
|
||||
function XDCValidator (
|
||||
function XDCalidator (
|
||||
address[] _candidates,
|
||||
uint256[] _caps,
|
||||
address _firstOwner,
|
||||
|
|
@ -163,7 +99,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({
|
||||
|
|
@ -172,20 +108,11 @@ contract XDCValidator {
|
|||
cap: _caps[i]
|
||||
});
|
||||
voters[_candidates[i]].push(_firstOwner);
|
||||
ownerToCandidate[_firstOwner].push(_candidates[i]);
|
||||
validatorsState[_candidates[i]].voters[_firstOwner] = minCandidateCap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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) {
|
||||
function propose(address _candidate) external payable onlyValidCandidateCap onlyNotCandidate(_candidate) {
|
||||
uint256 cap = validatorsState[_candidate].cap.add(msg.value);
|
||||
candidates.push(_candidate);
|
||||
validatorsState[_candidate] = ValidatorState({
|
||||
|
|
@ -195,11 +122,6 @@ 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);
|
||||
}
|
||||
|
|
@ -276,59 +198,6 @@ 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
|
|
@ -16,11 +16,10 @@
|
|||
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 {
|
||||
|
|
@ -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) {
|
||||
minDeposit := new(big.Int)
|
||||
minDeposit.SetString("10000000000000000000000000", 10)
|
||||
minDeposit.SetString("50000000000000000000000", 10)
|
||||
minVoterCap := new(big.Int)
|
||||
minVoterCap.SetString("25000000000000000000000", 10)
|
||||
// Deposit 10Mil XDC
|
||||
// Min Voter Cap 25K XDC
|
||||
// 21 masternodes
|
||||
minVoterCap.SetString("10000000000000000000", 10)
|
||||
// Deposit 50K XDC
|
||||
// Min Voter Cap 10 XDC
|
||||
// 150 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))
|
||||
|
|
|
|||
|
|
@ -17,18 +17,19 @@ package validator
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/contracts"
|
||||
"github.com/ethereum/go-ethereum/contracts/validator/contract"
|
||||
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"math/rand"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
|
||||
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))
|
||||
validatorCap := new(big.Int)
|
||||
validatorCap.SetString("50000000000000000000000", 10)
|
||||
validatorAddr, _, baseValidator, err := contract.DeployXDCValidator(
|
||||
validatorAddr, _, baseValidator, err := contractValidator.DeployXDCValidator(
|
||||
transactOpts,
|
||||
contractBackend,
|
||||
[]common.Address{addr},
|
||||
|
|
@ -144,7 +145,7 @@ func TestRewardBalance(t *testing.T) {
|
|||
|
||||
foundationAddr := common.HexToAddress(common.FoudationAddr)
|
||||
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 {
|
||||
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