composer require digitaldonkey/ethereum-php
PRIVATE_KEY=0x.. CHAIN_ID=1 php -S 0.0.0.0:8080 signer.php
{ | |
"minimum-stability":"dev", | |
"autoload": { | |
"psr-4": { | |
"Ethereum\\": "src/" | |
} | |
}, | |
"repositories": [ | |
{ | |
"type": "git", | |
"url": "https://github.com/digitaldonkey/ethereum-php.git" | |
} | |
], | |
"require": { | |
"digitaldonkey/ethereum-php": "dev-master" | |
} | |
} |
<?php | |
require __DIR__ . '/vendor/autoload.php'; | |
use Ethereum\EthereumStatic; | |
use Elliptic\EC; | |
$secret_key = getenv("PRIVATE_KEY"); | |
$chain_id = getenv("CHAIN_ID"); | |
$uri = $_SERVER["REQUEST_URI"]; | |
header("Content-Type: application/json"); | |
preg_match("|^/api/v1/ethsign/(0[xX][0-9a-fA-F]{40})$|", $uri, $matches); | |
if(!$matches) { | |
header("HTTP/1.1 404 Not Found"); | |
echo json_encode(array("status"=>"not_implemented", "status_code"=>404, "x"=>$uri)); | |
exit(); | |
} | |
$address = strtoupper($matches[1]); | |
$data = sprintf("%s:%d", $address, $chain_id); | |
$msg = sprintf("\x19Ethereum Signed Message:\n%s%s", strlen($data), $data); | |
$hash = EthereumStatic::sha3($msg); | |
$signer = (new EC('secp256k1'))->keyFromPrivate($secret_key); | |
$signature = $signer->sign($hash, "hex", array("canonical"=>true)); | |
echo json_encode( | |
array( | |
"signature"=>sprintf( | |
"0x%s%s%02x", | |
$signature->r->toString("hex"), | |
$signature->s->toString("hex"), | |
$signature->recoveryParam + 27 | |
), | |
"address"=>$address, | |
"hash"=>$hash, | |
) | |
); | |
?> |