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 !
golang
, its 60 lines of code. It takes raw transaction fromstdin
and dumps all the values to stdout. You can compile it as executable and invoke from your PHP withexec()
, or you can compile it as a php extension if you know how to write an extension.