Untitled
unknown
plain_text
3 years ago
3.8 kB
7
Indexable
Never
func CallBalanceOfMulticall(ctx context.Context, cl *ethclient.Client, Tokens *[]string, Account string, BlockNo *big.Int) ([]*big.Int, error) { // Get RPC var clientValue = reflect.ValueOf(cl).Elem() fieldStruct := clientValue.FieldByName("c") clientPointer := reflect.NewAt(fieldStruct.Type(), unsafe.Pointer(fieldStruct.UnsafeAddr())).Elem() rpcClient, _ := clientPointer.Interface().(*rpc.Client) _Balances := make([]*big.Int, len(*Tokens)) data := "0x610020565b600060405190508061001557606090505b818101604052919050565b6000805a6101ab604051600482823980518060e01c905061004081610004565b95508086019450808387395050506060600484019350835160e01c600485019450845160f81c6001860195506100766060610004565b43815260014303406020820152604081016000885b8881101561018b57805160f81c8060201b831792505060008260201c141561014157600181019050805160601c601482019150815160e01c6004830192508281840193505a60008084846000888ff160018a14156100ff575a82036100f06004610004565b8160e01b815260048e019d5050505b6101096001610004565b8160f81b81526101196004610004565b3d60e01b81526101283d610004565b3d6000823e60058f019e503d8f019e5050505050505050505b60018260201c141561017757600181019050805160601c601482019150803161016a6020610004565b81815260208a0199505050505b63ffffffff8216915060018201915061008b565b508082526101996004610004565b5a880360e01b81526004870196508684f3" data_input_len := 9 var _calls string = "" // Prep Data _ContractInputData := "70a08231" + common.HexToHash(Account).String()[2:] // CallData calldata_size := addZerosPadding(IntToHex(len(_ContractInputData)/2), 8-len(IntToHex(len(_ContractInputData)/2))) // 8 char calldata size for _, Token := range *Tokens { _Contract_Addr := addZerosPadding(common.HexToAddress(Token).String()[2:], 40-len(common.HexToAddress(Token).String()[2:])) _SubStr := "00" + _Contract_Addr + calldata_size + _ContractInputData //log.Println("Token: ", Token, " _SubStr: ", _SubStr) data_input_len += (len(_SubStr) / 2) _calls += _SubStr } data_input_len_hex := addZerosPadding(IntToHex(data_input_len), 8-len(IntToHex(data_input_len))) data += data_input_len_hex + "0000ffff" + "01" + _calls //log.Info("Data: ", data) //log.Infof("data_input_len: %d data_input_len_hex: %s _str: %s", data_input_len, data_input_len_hex, _calls) EthCallObj := EthCallObj{ From: Account, Gas: "0xffffff", GasPrice: "", Value: "", Data: data, } var EthCallResult string err := rpcClient.CallContext(context.Background(), &EthCallResult, "eth_call", EthCallObj, "0x"+BigIntToHex(BlockNo), nil) if err != nil { log.Error("[CallBalanceOfMulticall] Unable to perform Multicall, err: ", err.Error()) return _Balances, err } // Now parse the result //log.Println("EthCallResult: ", EthCallResult) if len(EthCallResult) > 0 { j := 0 i := 202 // Results are of the following structure // 2 char Successfu (01 or 00) // 00000020 --> 8 byte for len of return data, convert to int then * by 2 for char len // 8 char Gas (i.e. 00010116) // i.e. 010000002000000000000000000000000000000000000000000000000000000000000000000000320a for i < len(EthCallResult) { _len_ret, _ := strconv.ParseInt(EthCallResult[i+2:i+10], 16, 64) _return_size := int(_len_ret * 2) if EthCallResult[i:i+2] == "01" { if _return_size != 0 { _balance, s := big.NewInt(0).SetString(EthCallResult[i+10:i+10+_return_size], 16) if s { _Balances[j] = _balance } else { _Balances[j] = big.NewInt(0) } } else { _Balances[j] = big.NewInt(0) } } else { _Balances[j] = big.NewInt(0) } i += 10 + _return_size + 8 j += 1 } } else { log.Error("[CallBalanceOfMulticall] Empty Output") return nil, nil } return _Balances, nil }