digitaldonkey / ethereum-php

PHP interface to Ethereum JSON-RPC API. Fully typed Web3 for PHP 7.X
http://ethereum-php.org
MIT License
491 stars 176 forks source link

Decode transaction input field #33

Open sebnyc opened 6 years ago

sebnyc commented 6 years ago

I'm starting to use your library, it looks fantastic. I would like to decode the 'input' field of transactions, using the ABI of the involved contract (especially for ERC20 contracts). Is there a built-in method to do so ?

digitaldonkey commented 6 years ago

Please provide an example, I have no clue what you are talking about ;)

sebnyc commented 6 years ago

Let me explain: We have the Abi::encodeFunction that calculates this 'input' field of a transaction based on the method name and the array of parameters. The first 8 characters of the 'input' field are provided by calculating the signature of the method thanks to the ABI, and the next characters represent each encoded parameter.

What I'm trying to do is the inverse of that : given an 'input' field of a given transaction, retrieve the method and the parameters. Having the Abi object, it would consist in: Step 1 : find in the Abi the method that has a signature matching with the first 8 characters Step 2 : given this method, and its parameter description in the Abi, decode each parameter.

We have this Abi::decodeMethod but it looks like it's just decoding an output, not the method and parameters.

Example : trx 0x9d6e0b717c36f3cb9b4478daed168b02024d8b41f6b0f105a2e904e1996ce796 input field of this transaction: 0xa9059cbb0000000000000000000000005f316ffa3e753b3472860220f957adc4e49401c500000000000000000000000000000000000000000000000058b8e7af087b2400

Decoding would be : Step 1 : 0xa9059cbb matches "transfer" function signature in the ABI Step 2 : given that "transfer" function has 2 parameters (address _to, uint256 _value) we can decode the parameters : _to = 0000000000000000000000005f316ffa3e753b3472860220f957adc4e49401c5 _value = 00000000000000000000000000000000000000000000000058b8e7af087b2400

So I guess this method is not part of the library ? Would you consider a pull request if I write it (or maybe we would actually need 2 methods, one for each step) ?

digitaldonkey commented 6 years ago

I assume you have the ABI for each input you want to decode available. Without it It will not work, as the Method ID is (part of) a keccac hash which you can't reverse engineer.

If you use truffle to compile your contracts you get a list of available function hashes from truffle compile. Step one would be a $contract->getAllFunctionHashes() ? Step two should be available out of the box.

I'm still not sure If I fully understand your use case. I'm always happy for pull requests, but I can't make any statements on that without actually seeing the code.

sebnyc commented 6 years ago

Sorry my example was about ERC20 tokens and contracts, but I realize I didn't mention it. Let's say I would like to decode transactions about ERC20 tokens, and understand who sends tokens to whom. To do so, I have to decode the 'input' field of these transactions. As the ERC20 contract ABI is public, I can use it to find the method that was used and its parameters.

$abi would be initialized with the public ERC20 ABI Step1 would be something like $abi->findMethod(string $input) that would return the method Step2 would be something like $abi->decodeParameters(string $input, string $method) that would return the array of parameters.

Does it make sense ?

digitaldonkey commented 6 years ago

Yes. I would suggest Step one like

Step1 Get the method:

// We actually would use only substr($input->hexVal(), 0, 10),
// but providing the RAW data object would increase consistency. 
// @param $input EthD  - TX call params. 
// @return string Method name given in the ABI with $item->name
$abi->getMethodByHash(EthD $input) : string

Step2 is all ready in place:

// $item->name
$abi->decodeMethod(string $method, EthD $rawReturn)
sebnyc commented 6 years ago

I don't think decodeMethod function is what we need for step 2. This function works with the 'output' part of the ABI function description, whereas we need a function working with the 'input' part of this description. The algorithm would probably be very similar, but not exactly the same.

str commented 2 years ago

Any updates or alternatives?

frmiqueias commented 2 years ago

I'm having the same difficulty @sebnyc did you get a solution?