github.com/iotexproject/iotex-core@v1.14.1-rc1/action/protocol/staking/ethabi/stake_base.go (about) 1 package ethabi 2 3 import ( 4 "encoding/hex" 5 "errors" 6 "math/big" 7 8 "github.com/ethereum/go-ethereum/accounts/abi" 9 "github.com/ethereum/go-ethereum/common" 10 "github.com/iotexproject/iotex-proto/golang/iotextypes" 11 12 "github.com/iotexproject/iotex-core/action/protocol" 13 "github.com/iotexproject/iotex-core/pkg/util/addrutil" 14 ) 15 16 var ( 17 errInvalidCallData = errors.New("invalid call binary data") 18 errInvalidCallSig = errors.New("invalid call sig") 19 errConvertBigNumber = errors.New("convert big number error") 20 errDecodeFailure = errors.New("decode data error") 21 ) 22 23 type ( 24 // BucketEth struct for eth 25 BucketEth struct { 26 Index uint64 27 CandidateAddress common.Address 28 StakedAmount *big.Int 29 StakedDuration uint32 30 CreateTime int64 31 StakeStartTime int64 32 UnstakeStartTime int64 33 AutoStake bool 34 Owner common.Address 35 ContractAddress common.Address 36 StakedDurationBlockNumber uint64 37 CreateBlockHeight uint64 38 StakeStartBlockHeight uint64 39 UnstakeStartBlockHeight uint64 40 } 41 42 // BucketTypeEth struct for eth 43 BucketTypeEth struct { 44 StakedAmount *big.Int 45 StakedDuration uint32 46 } 47 48 // CandidateEth struct for eth 49 CandidateEth struct { 50 OwnerAddress common.Address 51 OperatorAddress common.Address 52 RewardAddress common.Address 53 Name string 54 TotalWeightedVotes *big.Int 55 SelfStakeBucketIdx uint64 56 SelfStakingTokens *big.Int 57 } 58 ) 59 60 func encodeVoteBucketListToEth(outputs abi.Arguments, buckets *iotextypes.VoteBucketList) (string, error) { 61 args := make([]BucketEth, len(buckets.Buckets)) 62 for i, bucket := range buckets.Buckets { 63 args[i] = BucketEth{} 64 args[i].Index = bucket.Index 65 addr, err := addrutil.IoAddrToEvmAddr(bucket.CandidateAddress) 66 if err != nil { 67 return "", err 68 } 69 args[i].CandidateAddress = addr 70 if amount, ok := new(big.Int).SetString(bucket.StakedAmount, 10); ok { 71 args[i].StakedAmount = amount 72 } else { 73 return "", errConvertBigNumber 74 } 75 76 args[i].AutoStake = bucket.AutoStake 77 addr, err = addrutil.IoAddrToEvmAddr(bucket.Owner) 78 if err != nil { 79 return "", err 80 } 81 args[i].Owner = addr 82 83 if bucket.ContractAddress == "" { 84 // native bucket contract address is 0x0000000000000000000000000000000000000000 85 args[i].ContractAddress = common.Address{} 86 args[i].StakedDuration = bucket.StakedDuration 87 args[i].CreateTime = bucket.CreateTime.Seconds 88 args[i].StakeStartTime = bucket.StakeStartTime.Seconds 89 args[i].UnstakeStartTime = bucket.UnstakeStartTime.Seconds 90 } else { 91 addr, err = addrutil.IoAddrToEvmAddr(bucket.ContractAddress) 92 if err != nil { 93 return "", err 94 } 95 args[i].ContractAddress = addr 96 args[i].StakedDurationBlockNumber = bucket.StakedDurationBlockNumber 97 args[i].CreateBlockHeight = bucket.CreateBlockHeight 98 args[i].StakeStartBlockHeight = bucket.StakeStartBlockHeight 99 args[i].UnstakeStartBlockHeight = bucket.UnstakeStartBlockHeight 100 } 101 } 102 103 data, err := outputs.Pack(args) 104 if err != nil { 105 return "", nil 106 } 107 return hex.EncodeToString(data), nil 108 } 109 110 func encodeCandidateToEth(candidate *iotextypes.CandidateV2) (*CandidateEth, error) { 111 result := &CandidateEth{} 112 addr, err := addrutil.IoAddrToEvmAddr(candidate.OwnerAddress) 113 if err != nil { 114 return nil, err 115 } 116 result.OwnerAddress = addr 117 addr, err = addrutil.IoAddrToEvmAddr(candidate.OperatorAddress) 118 if err != nil { 119 return nil, err 120 } 121 result.OperatorAddress = addr 122 addr, err = addrutil.IoAddrToEvmAddr(candidate.RewardAddress) 123 if err != nil { 124 return nil, err 125 } 126 result.RewardAddress = addr 127 result.Name = candidate.Name 128 if amount, ok := new(big.Int).SetString(candidate.TotalWeightedVotes, 10); ok { 129 result.TotalWeightedVotes = amount 130 } else { 131 return nil, errConvertBigNumber 132 } 133 result.SelfStakeBucketIdx = candidate.SelfStakeBucketIdx 134 if amount, ok := new(big.Int).SetString(candidate.SelfStakingTokens, 10); ok { 135 result.SelfStakingTokens = amount 136 } else { 137 return nil, errConvertBigNumber 138 } 139 return result, nil 140 } 141 142 func encodeBucketTypeListToEth(outputs abi.Arguments, bucketTypes *iotextypes.ContractStakingBucketTypeList) (string, error) { 143 args := make([]BucketTypeEth, len(bucketTypes.BucketTypes)) 144 for i, bt := range bucketTypes.BucketTypes { 145 args[i] = BucketTypeEth{} 146 if amount, ok := new(big.Int).SetString(bt.StakedAmount, 10); ok { 147 args[i].StakedAmount = amount 148 } else { 149 return "", errConvertBigNumber 150 } 151 args[i].StakedDuration = bt.StakedDuration 152 } 153 154 data, err := outputs.Pack(args) 155 if err != nil { 156 return "", err 157 } 158 return hex.EncodeToString(data), nil 159 } 160 161 // BuildReadStateRequest decode eth_call data to StateContext 162 func BuildReadStateRequest(data []byte) (protocol.StateContext, error) { 163 if len(data) < 4 { 164 return nil, errInvalidCallData 165 } 166 167 switch methodSig := hex.EncodeToString(data[:4]); methodSig { 168 case hex.EncodeToString(_bucketsMethod.ID): 169 return newBucketsStateContext(data[4:]) 170 case hex.EncodeToString(_bucketsByCandidateMethod.ID): 171 return newBucketsByCandidateStateContext(data[4:]) 172 case hex.EncodeToString(_bucketsByIndexesMethod.ID): 173 return newBucketsByIndexesStateContext(data[4:]) 174 case hex.EncodeToString(_bucketsByVoterMethod.ID): 175 return newBucketsByVoterStateContext(data[4:]) 176 case hex.EncodeToString(_bucketsCountMethod.ID): 177 return newBucketsCountStateContext() 178 case hex.EncodeToString(_candidatesMethod.ID): 179 return newCandidatesStateContext(data[4:]) 180 case hex.EncodeToString(_candidateByNameMethod.ID): 181 return newCandidateByNameStateContext(data[4:]) 182 case hex.EncodeToString(_candidateByAddressMethod.ID): 183 return newCandidateByAddressStateContext(data[4:]) 184 case hex.EncodeToString(_totalStakingAmountMethod.ID): 185 return newTotalStakingAmountContext() 186 case hex.EncodeToString(_compositeBucketsMethod.ID): 187 return newCompositeBucketsStateContext(data[4:]) 188 case hex.EncodeToString(_compositeBucketsByCandidateMethod.ID): 189 return newCompositeBucketsByCandidateStateContext(data[4:]) 190 case hex.EncodeToString(_compositeBucketsByIndexesMethod.ID): 191 return newCompositeBucketsByIndexesStateContext(data[4:]) 192 case hex.EncodeToString(_compositeBucketsByVoterMethod.ID): 193 return newCompositeBucketsByVoterStateContext(data[4:]) 194 case hex.EncodeToString(_compositeBucketsCountMethod.ID): 195 return newCompositeBucketsCountStateContext() 196 case hex.EncodeToString(_compositeTotalStakingAmountMethod.ID): 197 return newCompositeTotalStakingAmountContext() 198 case hex.EncodeToString(_contractBucketTypesMethod.ID): 199 return newContractBucketTypesStateContext(data[4:]) 200 default: 201 return nil, errInvalidCallSig 202 } 203 }