github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/articulate/trace.go (about) 1 package articulate 2 3 import ( 4 "errors" 5 6 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/abi" 7 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/rpc" 8 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" 9 goEthAbi "github.com/ethereum/go-ethereum/accounts/abi" 10 ) 11 12 func (abiCache *AbiCache) ArticulateTrace(trace *types.Trace) (err error) { 13 found, err := articulateTrace(trace, &abiCache.AbiMap) 14 if err != nil { 15 return err 16 17 } else if found != nil { 18 trace.ArticulatedTrace = found 19 return nil 20 21 } else { 22 address := trace.Action.To 23 if !abiCache.loadedMap.GetValue(address) && !abiCache.skipMap.GetValue(address) { 24 if err = abi.LoadAbi(abiCache.Conn, address, &abiCache.AbiMap); err != nil { 25 abiCache.skipMap.SetValue(address, true) 26 if !errors.Is(err, rpc.ErrNotAContract) { 27 // Not being a contract is not an error because we want to articulate the input in case it's a message 28 return err 29 } 30 } else { 31 abiCache.loadedMap.SetValue(address, true) 32 } 33 } 34 35 if !abiCache.skipMap.GetValue(address) { 36 if trace.ArticulatedTrace, err = articulateTrace(trace, &abiCache.AbiMap); err != nil { 37 return err 38 } 39 } 40 41 return nil 42 } 43 } 44 45 func articulateTrace(trace *types.Trace, abiMap *abi.SelectorSyncMap) (articulated *types.Function, err error) { 46 input := trace.Action.Input 47 if len(input) < 10 { 48 return 49 } 50 51 encoding := input[:10] 52 articulated = abiMap.GetValue(encoding) 53 54 if trace.Result == nil || articulated == nil { 55 return 56 } 57 58 var abiMethod *goEthAbi.Method 59 60 if len(trace.Action.Input) >= 10 { 61 abiMethod, err = articulated.GetAbiMethod() 62 if err != nil { 63 return nil, err 64 } 65 err = articulateArguments( 66 abiMethod.Inputs, 67 trace.Action.Input[10:], 68 nil, 69 articulated.Inputs, 70 ) 71 if err != nil { 72 return 73 } 74 } 75 76 abiMethod, err = articulated.GetAbiMethod() 77 if err != nil { 78 return nil, err 79 } 80 if len(trace.Result.Output) >= 2 { 81 err = articulateArguments( 82 abiMethod.Outputs, 83 trace.Result.Output[2:], 84 nil, 85 articulated.Outputs, 86 ) 87 } 88 89 return 90 }