2

I'm trying this code example : https://thomasclowes.com/verifying-an-ethereum-signature-on-the-server-php-2/

Expected $recoveredSenderAddress = 0xd5bfc359c3a377bb8afd41db8ffc8d1349718233

Actual $recoveredSenderAddress = 0x65f0041f24b95b4d73cb128491b592f08a432c37

Tested transaction is => https://ropsten.etherscan.io/tx/0xc14a23d652315c871474142745bc23268e0fac2ee9f0d56a108e208571c03a86

// $transactionRaw = 'f86a06843b9aca00835d161494e2f9d68bb0d2adcb0d926e93896366d0f2a4573886313030303030801ba0a267b2cd995a8475b967f688d96af1442af777c545cac8d35d08225e31167b32a066308ac688f621ad3f284a63153af7d7c711409926ac0c7e0231fdf0f005b74f'; public function recoveredSenderAddress($transactionRaw) { $rlp = new RLP; // Lib Web3p\RLP\RLP (Recursive Length Prefix) $decodedArray = $rlp->decode('0x'.$transactionRaw); $rHex = $decodedArray[7]->toString('hex'); $sHex = $decodedArray[8]->toString('hex'); $vValue = $decodedArray[6][0]; //"v" => 27 //"r" => "a267b2cd995a8475b967f688d96af1442af777c545cac8d35d08225e31167b32" //"s" => "66308ac688f621ad3f284a63153af7d7c711409926ac0c7e0231fdf0f005b74f" $messageHex = $transactionRaw; $messageByteArray = unpack('C*', hex2bin($messageHex)); $messageGmp = gmp_init("0x" . $messageHex); $r = $rHex; //hex string without 0x $s = $sHex; //hex string without 0x $v = $vValue; //27 or 28 //with hex2bin it gives the same byte array as the javascript $rByteArray = unpack('C*', hex2bin($r)); $sByteArray = unpack('C*', hex2bin($s)); $rGmp = gmp_init("0x" . $r); $sGmp = gmp_init("0x" . $s); $signature = array_merge($rByteArray, $sByteArray); $recovery = $v - 27; if ($recovery !== 0 && $recovery !== 1) { throw new Exception('Invalid signature v value'); } $publicKey = Signature::recoverPublicKey($rGmp, $sGmp, $messageGmp, $recovery); $recoveredSenderAddress = "0x".substr(hash('sha3-256',hex2bin($publicKey['x'].$publicKey['y'])), 24); return $recoveredSenderAddress; } 

What am I doing wrong ? Thx !

5
  • I can send you a snippet to decode a transaction in golang, its 60 lines of code. It takes raw transaction from stdin and dumps all the values to stdout. You can compile it as executable and invoke from your PHP with exec() , or you can compile it as a php extension if you know how to write an extension. Commented Sep 22, 2018 at 11:45
  • 1
    I've to note that ethereum uses keccak256 instead of the oficial sha3, see this question stackoverflow.com/questions/44742153/keccak-256-in-php. Commented Sep 24, 2018 at 15:52
  • @Nulik Thank you but I would like to do it in php. There are implementations that work in JS also like ethereumjs-tx for example but my goal is to understand the problem in this script Commented Sep 24, 2018 at 22:40
  • @Ismael thank you for your help. After some tests, and comparing step by step with the JS version that works, even before the use of sha3, the $publicKey in my script is not good. Actual 49b3c834a579e4e8d03c4fe3faed5ae6f5cc8766c1de0f5091f51a5885f35356fd1000711dbfc31fb9ec01c0dadca1d9a2b89d3b92f69b63d0c7971410d0a687 Expected 52721ad1fcf8d852853c395e614101a11e29eb3c9e583f147b0d9cde79986b3c451abe7cc8f7aeccc16f168dbd9c48777369f395158c5d02aaea229eca5f649f Commented Sep 24, 2018 at 22:44
  • @vincentLg Your issue is because you verify the raw transaction, and you have to verify the hash of the transaction without signature (ie without r, s and v). Take a look at github.com/web3p/ethereum-tx/blob/master/src/…. Sorry I'd try to write an example but I'm not very good at php. Commented Oct 13, 2018 at 19:55

1 Answer 1

0

You may use a library for that https://github.com/digitaldonkey/ecverify

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.