Skip to content

Commit 335f5bf

Browse files
Merge pull request #7 from com-chain/webhook
Webhook
2 parents 84ecb5c + c3560fd commit 335f5bf

File tree

6 files changed

+279
-9
lines changed

6 files changed

+279
-9
lines changed

Buffer.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
///// Cherry picked from https://github.com/Bit-Wasp/buffertools-php
3+
4+
5+
class Buffer
6+
{
7+
protected $size;
8+
protected $buffer; //string
9+
10+
public function __construct(string $byteString = '', int $byteSize = null)
11+
{
12+
if ($byteSize !== null) {
13+
// Check the integer doesn't overflow its supposed size
14+
if (strlen($byteString) > $byteSize) {
15+
throw new \Exception('Byte string exceeds maximum size');
16+
}
17+
} else {
18+
$byteSize = strlen($byteString);
19+
}
20+
$this->size = $byteSize;
21+
$this->buffer = $byteString;
22+
}
23+
24+
public static function hex(string $hexString = '', int $byteSize = null)
25+
{
26+
if (strlen($hexString) > 0 && !ctype_xdigit($hexString)) {
27+
throw new \InvalidArgumentException('Buffer::hex: non-hex character passed');
28+
}
29+
$binary = pack("H*", $hexString);
30+
return new self($binary, $byteSize);
31+
}
32+
33+
public static function int($integer, $byteSize = null)
34+
{
35+
$hex_dec = dechex($integer);
36+
return Buffer::hex($hex_dec, $byteSize);
37+
}
38+
39+
40+
41+
42+
public function getSize()
43+
{
44+
return $this->size;
45+
}
46+
47+
48+
public function getBinary()
49+
{
50+
if ($this->size !== null) {
51+
if (strlen($this->buffer) < $this->size) {
52+
return str_pad($this->buffer, $this->size, chr(0), STR_PAD_LEFT);
53+
} elseif (strlen($this->buffer) > $this->size) {
54+
return substr($this->buffer, 0, $this->size);
55+
}
56+
}
57+
return $this->buffer;
58+
}
59+
60+
public function getHex()
61+
{
62+
return unpack("H*", $this->getBinary())[1];
63+
}
64+
65+
66+
public function equals(Buffer $other)
67+
{
68+
return ($other->getSize() === $this->getSize()
69+
&& $other->getBinary() === $this->getBinary());
70+
}
71+
}

TestingWebhook/testWebHook.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
class MyLiteDB extends SQLite3 {
4+
function __construct() {
5+
$this->open('./webhookMessage.db');
6+
7+
$sql = "CREATE TABLE IF NOT EXISTS WebHookMessage (message TEXT NOT NULL, date TEXT NOT NULL)";
8+
$this->query($sql);
9+
}
10+
11+
function __destruct() {
12+
$this->close();
13+
}
14+
15+
public function clearMessage() {
16+
$sql ="DELETE FROM WebHookMessage";
17+
$this->query($sql);
18+
}
19+
20+
public function insertMessage($message) {
21+
$sql ="INSERT INTO WebHookMessage(message, date) values (\"$code\", DATETIME('now') )";
22+
$this->query($sql);
23+
}
24+
25+
26+
public function getMessages() {
27+
$sql ="SELECT message, date FROM WebHookMessage ORDER BY date";
28+
$ret = $this->query($sql);
29+
$result = array();
30+
while($row = $ret->fetchArray(SQLITE3_ASSOC) ){
31+
$sub = array("message"=>$row['message'], "date"=>$row['date']);
32+
array_push($result,$sub);
33+
}
34+
35+
return $result;
36+
}
37+
}
38+
39+
$db = new MyLiteDB();
40+
41+
if (isset($_GET['cleanMessage'])) {
42+
43+
$db->clearMessage();
44+
}
45+
46+
if (isset($_POST['resources'])) {
47+
$db->insertMessage(json_encode($_POST['resources']));
48+
}
49+
50+
$address = "0x9e898bc7c13ba309a412904f07aff65a13e15d32";
51+
$shopId = 1;
52+
$serverName = "Lemanopolis";
53+
$amount =0.01;
54+
$tx_id = 'TEST_001';
55+
56+
echo '
57+
<html>
58+
<body>
59+
<div>
60+
To Pay: <a target="_blank" href="https://v2.cchosting.org/index.html?address='.$address.'&amount='.$amount.'&shopId='.$shopId.'&txId='.urlencode($tx_id).'&serverName='.$serverName.'"> Click</a>
61+
</div>
62+
<div>
63+
List of Messages: <a href="./testWebHook.php?cleanMessage=1"> Clear Messages</a>
64+
<table>';
65+
66+
$messages = $db->getMessages();
67+
foreach ($messages as $value){
68+
echo '<tr><td>'.$value['message'].'</td><td>'.$value['date'].'</td></tr>';
69+
}
70+
71+
72+
echo '
73+
</tr>
74+
</table>
75+
</div>
76+
</body>
77+
</html>';
78+
79+
80+
81+
?>

Webhook.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
$NANT_TRANSFERT = "0xa5f7c148";
44
$CM_TRANSFERT = "0x60ca9c4c";
5-
$private_key_path ='../ComChain/comchainwebhook_rsa';
5+
$private_key_path ='../ComChainKey/comchainwebhook_rsa';
66
$public_key_url ='https://com-chain.org/comchainwebhook_rsa.pub';
77

88

@@ -74,7 +74,7 @@ function sendWebhook($url, $message) {
7474
'COMCHAIN-CERT-URL:'.$public_key_url));
7575
curl_setopt($ch, CURLOPT_POST, 1);
7676
curl_setopt($ch, CURLOPT_HEADER, 1);
77-
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_message);
77+
curl_setopt($ch, CURLOPT_POSTFIELDS, $message);
7878
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
7979

8080
$passed=true;

api.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -259,13 +259,13 @@ function sendRawTransaction($rawtx,$gethRPC){
259259
// if so get the dest
260260
$dest = '0x'.$rawtx.substr(110,40);
261261
// get the sender
262-
// TODO $sender = TransactionEcRecover($rawtx)[0];
262+
$sender = TransactionEcRecover($rawtx)[0];
263263

264264
// get the amount
265265
$amount = hexdec($rawtx.substr(150,64));
266-
// get the balances for dest
266+
// get the balances
267267
$to_bal = getBalance($dest, $contract);
268-
// TODO $from_bal = getBalance($sender, $contract);
268+
$from_bal = getBalance($sender, $contract);
269269
$wh_status = 1;
270270
}
271271

@@ -275,11 +275,11 @@ function sendRawTransaction($rawtx,$gethRPC){
275275
// get the balances check if changes compatible the the amount
276276
$to_bal_after = getBalance($dest, $contract);
277277
$from_bal_after = getBalance($sender, $contract);
278-
if ($to_bal_after - $to_bal >= $amount) { // TODO} && $from_bal - $from_bal_after >= $amount) {
278+
if (($to_bal_after - $to_bal >= $amount) && ($from_bal - $from_bal_after >= $amount)) {
279279
// if so : send the webhook
280280
$message = createWebhookMessage($data['data'], $_REQUEST['serverName'],
281281
$_REQUEST['shopId'], $_REQUEST['txId'],
282-
"", $rawtx); // TODO ""=> $sender
282+
$sender, $rawtx);
283283
$res = sendWebhook($shop_url, $message);
284284
if ($res) {
285285
$wh_status = 3;

ecrecover_helper.php

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,39 @@
66
require_once './Keccak.php';
77
use kornrunner\Keccak;
88

9+
require_once './Buffer.php';
10+
11+
function encodeLength(int $l, int $offset)
12+
{
13+
if ($l < 56) {
14+
return Buffer::int($l + $offset)->getHex();
15+
}
16+
if ($l < 256 ** 8) {
17+
/** @var string $bl */
18+
$bl = Buffer::int($l)->getBinary();
19+
return (Buffer::int(strlen($bl) + $offset + 55)->getHex()) . (Buffer::int($l)->getHex());
20+
}
21+
throw new \Exception('Failed to encode length');
22+
}
23+
924

1025
function TransactionEcRecover($rawTx) {
1126
// get the signature, last 134 chars
1227
$len = strlen($rawTx);
1328
$len_data = $len - 134;
14-
$data = substr($rawTx, 0, $len_data);
1529
$signature = substr($rawTx, $len_data);
1630
$v = substr($signature,0,2);
1731
$r = substr($signature,4,64);
1832
$s = substr($signature,70,64);
1933
$signed = '0x'.$r.$s.$v;
20-
return ecRecoverPublic($data, $signed);
34+
35+
// get the rlp encoded data (change the length)
36+
$subs = substr($rawTx, 6, $len_data-6); // 2 for the 0x + 4 for the 2 first bytes giving the length with the signature
37+
$data_len = strlen($subs)/2;
38+
// add the new length
39+
$data = encodeLength($data_len,192).$subs;
40+
$hash = keccak256WithPrefix(hex2bin($data));
41+
return ecRecoverPublic($hash, $signed);
2142
}
2243

2344

requestMessages.php

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
require_once './Keccak.php';
3+
require_once './ecrecover_helper.php';
4+
use kornrunner\Keccak;
5+
6+
header('Access-Control-Allow-Origin: *');
7+
/*
8+
9+
UseCases:
10+
Add a reference:
11+
12+
POST with:
13+
data = {'add_req'='0x123...', 'add_to'='0x123...', 'ref_to'='0x123...', 'ref_req'='0x123...'}
14+
sign = 0x123..
15+
16+
Read a reference :
17+
GET with:
18+
add_req = 0x123..
19+
add_to = 0x123..
20+
*/
21+
22+
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
23+
// POST case
24+
25+
// Check signature
26+
$input_data = $_POST['data'];
27+
$input_obj = json_decode($_POST['data']);
28+
29+
$input_sign = $_POST['sign'];
30+
$ec_recover_result = personal_ecRecover($input_data, $input_sign);
31+
if ($ec_recover_result !== $input_obj->{'add_req'}){
32+
// wrong signature
33+
exit("Bye!");
34+
}
35+
36+
// insert data
37+
$add_from = $ec_recover_result;
38+
$add_to = preg_replace("/[^a-zA-Z0-9]+/", "", $input_obj->{'add_cli'});
39+
$ref_from = preg_replace("/[^a-zA-Z0-9]+/", "", $input_obj->{'ref_req'});
40+
$ref_to = preg_replace("/[^a-zA-Z0-9]+/", "", $input_obj->{'ref_cli'});
41+
42+
43+
$session = getDBSession();
44+
$query = "INSERT INTO request_reference (add_from, add_to, ref_from, ref_to) VALUES (?,?,?,?)";
45+
$options = array('arguments' => array($add_from, $add_to, $ref_from, $ref_to));
46+
47+
$session->execute(new Cassandra\SimpleStatement($query), $options);
48+
echo '{"result":"OK"}';
49+
50+
51+
} else {
52+
// GET case
53+
54+
// Check inputs
55+
$addr_from = strtolower(preg_replace("/[^a-zA-Z0-9]+/", "", $_GET['add_req']));
56+
if (strlen($addr_from) != 42) {
57+
exit("Bye!");
58+
}
59+
$addr_cli = strtolower(preg_replace("/[^a-zA-Z0-9]+/", "", $_GET['add_cli']));
60+
if (strlen($addr_cli) != 42) {
61+
exit("Bye!");
62+
}
63+
64+
// get the data from the DB
65+
$session = getDBSession();
66+
67+
$query = "SELECT ref_from, ref_to FROM request_reference WHERE add_from = '$addr_from' and add_to = '$addr_cli'";
68+
69+
70+
// the address is a primary key it should be only 0 or 1 row
71+
$counter=0;
72+
foreach ($session->execute(new Cassandra\SimpleStatement($query)) as $row) {
73+
$string[$counter] = json_encode($row);
74+
$counter++;
75+
}
76+
77+
// Return empty object if address pait is not found
78+
isset($string) or exit("[]");
79+
80+
// return the keys
81+
echo $string[0];
82+
}
83+
84+
85+
86+
87+
/*
88+
FUNCTIONS
89+
*/
90+
91+
function getDBSession() {
92+
$cluster = Cassandra::cluster('127.0.0.1') ->withCredentials("webhook_rw", "Private_access_transactions")->build();
93+
$keyspace = 'comchain';
94+
return $cluster->connect($keyspace);
95+
}
96+
97+
?>

0 commit comments

Comments
 (0)