github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/call/find.go (about) 1 package call 2 3 import ( 4 "strings" 5 6 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/abi" 7 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/parser" 8 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" 9 ) 10 11 type findMode int 12 13 const ( 14 FindByName findMode = iota 15 FindBySelector 16 ) 17 18 // FindAbiFunction returns either the function to call or a list of suggestions (function 19 // signatures with the same name, but different argument count) 20 func FindAbiFunction(mode findMode, identifier string, arguments []*parser.ContractArgument, abiMap *abi.SelectorSyncMap) (fn *types.Function, suggestions []string, err error) { 21 functions := abiMap.Values() 22 for _, function := range functions { 23 if (mode == FindByName && function.Name != identifier) || 24 (mode == FindBySelector && function.Encoding != strings.ToLower(identifier)) { 25 continue 26 } 27 28 // now we will compare arguments 29 if arguments != nil { 30 // we start with argument count 31 if len(function.Inputs) != len(arguments) { 32 suggestions = append(suggestions, function.Signature) 33 continue 34 } 35 // now we check if the argument types are compatible 36 compatible := false 37 for index, input := range function.Inputs { 38 argument := arguments[index] 39 if input.InternalType == "string" && argument.String == nil { 40 break 41 } 42 if input.InternalType == "bool" && argument.Boolean == nil { 43 break 44 } 45 // address in parsed into argument.Hex.Address 46 if input.InternalType == "address" { 47 // if both ways of finding an address are empty, break 48 if argument.EnsAddr == nil && (argument.Hex == nil || argument.Hex.Address == nil) { 49 break 50 } 51 } 52 // bytes32, array and tuples of any kind are only support via 53 // hashes. Hashes are parsed into argument.Hex.String 54 if input.InternalType == "bytes32" || 55 strings.Contains(input.InternalType, "[") || 56 strings.Contains(input.InternalType, "(") { 57 if argument.Hex == nil { 58 break 59 } 60 if argument.Hex.String == nil { 61 break 62 } 63 } 64 65 // we use strings.Contains here, because all integers are parsed into argument.Number 66 if strings.Contains(input.InternalType, "int") && argument.Number == nil { 67 break 68 } 69 70 compatible = true 71 } 72 73 if !compatible { 74 suggestions = append(suggestions, function.Signature) 75 continue 76 } 77 } 78 79 return &function, nil, nil 80 } 81 82 return nil, suggestions, nil 83 }