mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
186 lines
6.9 KiB
PHP
186 lines
6.9 KiB
PHP
<?php
|
|
|
|
namespace Model\Transactions;
|
|
|
|
//use App\Model\Transactions\TransactionBase;
|
|
|
|
use Cake\ORM\TableRegistry;
|
|
|
|
class TransactionCreation extends TransactionBase {
|
|
|
|
private $protoTransactionCreation;
|
|
private $transactionCreationsTable;
|
|
private $receiver_pubkey_hex;
|
|
|
|
public function __construct($protoTransactionCreation) {
|
|
$this->protoTransactionCreation = $protoTransactionCreation;
|
|
$this->transactionCreationsTable = TableRegistry::getTableLocator()->get('transaction_creations');
|
|
$this->receiver_pubkey_hex = bin2hex($this->getReceiverPublic());
|
|
}
|
|
|
|
public function getProto() {
|
|
return $this->protoTransactionCreation;
|
|
}
|
|
|
|
static public function build($amount, $memo, $receiver_public_hex, $ident_hash)
|
|
{
|
|
$receiver = new \Model\Messages\Gradido\ReceiverAmount();
|
|
$receiver->setAmount($amount);
|
|
//$this->receiver_pubkey_hex = $receiver_public_hex;
|
|
if(strlen($receiver_public_hex) != 64) {
|
|
return ['state' => 'error', 'msg' => 'invalid pubkey'];
|
|
}
|
|
$pubKeyBin = hex2bin($receiver_public_hex);
|
|
$receiver->setEd25519ReceiverPubkey($pubKeyBin);
|
|
//var_dump($requestData);
|
|
|
|
$creationDate = new \Model\Messages\Gradido\TimestampSeconds();
|
|
$creationDate->setSeconds(time());
|
|
|
|
$transactionBody = new \Model\Messages\Gradido\TransactionBody();
|
|
$transactionBody->setMemo($memo);
|
|
$transactionBody->setCreated($creationDate);
|
|
|
|
$transaction = new \Model\Messages\Gradido\TransactionCreation();
|
|
$transaction->setReceiverAmount($receiver);
|
|
$transaction->setIdentHash($ident_hash);
|
|
$transactionBody->setCreation($transaction);
|
|
return ['state' => 'success', 'transactionBody' => $transactionBody];
|
|
}
|
|
|
|
static protected function DRHashRotateLeft( $hash, $rotateBy )
|
|
{
|
|
return ($hash<<$rotateBy)|($hash>>(32-$rotateBy));
|
|
}
|
|
|
|
static public function DRMakeStringHash($str)
|
|
{
|
|
$ret = 0;
|
|
|
|
if( $str )
|
|
{
|
|
for ($i=0; $i < strlen($str); $i++)
|
|
{
|
|
$ret = TransactionCreation::DRHashRotateLeft($ret, 7) + ord($str{$i});
|
|
}
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
public function getAmount() {
|
|
return $this->protoTransactionCreation->getReceiverAmount()->getAmount();
|
|
}
|
|
|
|
public function getReceiverPublic() {
|
|
return $this->protoTransactionCreation->getReceiverAmount()->getEd25519ReceiverPubkey();
|
|
}
|
|
|
|
public function getIdentHash() {
|
|
return $this->protoTransactionCreation->getIdentHash();
|
|
}
|
|
|
|
|
|
public function validate($sigPairs) {
|
|
// check if receiver public is not in signature list
|
|
$receiverPublic = $this->getReceiverPublic();
|
|
foreach($sigPairs as $sigPair) {
|
|
$pubkey = $sigPair->getPubKey();
|
|
if($pubkey == $receiverPublic) {
|
|
$this->addError('TransactionCreation::validate', 'receiver aren\'t allowed to sign creation Transaction');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// check if creation threshold for this month isn't reached
|
|
|
|
//$identHashBin = sprintf("%0d", $this->getIdentHash());
|
|
// padding with zero in case hash is smaller than 32 bytes, static length binary field in db
|
|
// ident hash isn't collision ressistent, it is for speed up search
|
|
$identHashBin = pack('a32', $this->getIdentHash());
|
|
|
|
$existingCreations = $this->transactionCreationsTable
|
|
->find('all')
|
|
->select(['amount', 'state_user_id'])
|
|
->contain(['StateUsers' => ['fields' => ['StateUsers.public_key']]]);
|
|
// uncomment because ident hash didn't work at the moment
|
|
//->where(['ident_hash' => $identHashBin]);
|
|
//$existingCreations->select(['amount_sum' => $existingCreations->func()->sum('amount')]);
|
|
$existingCreations->select(['amount', 'state_user_id']);
|
|
$existingCreations->matching('Transactions', function ($q) {
|
|
return $q->where(['EXTRACT(YEAR_MONTH FROM Transactions.received) LIKE EXTRACT(YEAR_MONTH FROM NOW())']);
|
|
});
|
|
//debug($existingCreations);
|
|
$newSum = $this->getAmount();
|
|
//var_dump($existingCreations->toArray());
|
|
foreach($existingCreations as $creation) {
|
|
$keyHex = bin2hex(stream_get_contents($creation->state_user->public_key));
|
|
//echo "\ncompare \n$keyHex\nwith: \n". $this->receiver_pubkey_hex."\n";
|
|
if($keyHex == $this->receiver_pubkey_hex) {
|
|
$newSum += $creation->amount;
|
|
}
|
|
}
|
|
if($newSum > 10000000) {
|
|
$this->addError('TransactionCreation::validate', 'Creation more than 1000 gr per Month not allowed');
|
|
return false;
|
|
}
|
|
//die("\n");
|
|
return true;
|
|
}
|
|
|
|
public function save($transaction_id, $firstPublic)
|
|
{
|
|
|
|
$transactionCreationEntity = $this->transactionCreationsTable->newEntity();
|
|
$transactionCreationEntity->transaction_id = $transaction_id;
|
|
|
|
// state user id
|
|
//$state_user_id = $this->getStateUserId($firstPublic);
|
|
$receiverUser = $this->getStateUserId($this->getReceiverPublic());
|
|
if(!$receiverUser) {
|
|
$this->addError('TransactionCreation::save', 'couldn\'t get state user id');
|
|
return false;
|
|
}
|
|
$transactionCreationEntity->state_user_id = $receiverUser;
|
|
$transactionCreationEntity->amount = $this->getAmount();
|
|
$transactionCreationEntity->ident_hash = $this->getIdentHash();
|
|
|
|
if(!$this->transactionCreationsTable->save($transactionCreationEntity)) {
|
|
$this->addError('TransactionCreation::save', 'error saving transactionCreation with errors: ' . json_encode($transactionCreationEntity->getErrors()));
|
|
return false;
|
|
}
|
|
|
|
// update state balance
|
|
if(false === $this->updateStateBalance($receiverUser, $this->getAmount())) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static public function fromEntity($transactionCreationEntity)
|
|
{
|
|
$protoCreation = new \Model\Messages\Gradido\TransactionCreation();
|
|
|
|
//var_dump($transactionCreationEntity);
|
|
$stateUsersTable = TableRegistry::getTableLocator()->get('state_users');
|
|
//return new TransactionCreation($protoCreation);
|
|
$userId = $transactionCreationEntity->state_user_id;
|
|
|
|
|
|
$stateUser = $stateUsersTable->get($userId);
|
|
|
|
|
|
$receiverAmount = new \Model\Messages\Gradido\ReceiverAmount();
|
|
$receiverAmount->setEd25519ReceiverPubkey(stream_get_contents($stateUser->public_key));
|
|
|
|
$receiverAmount->setAmount($transactionCreationEntity->amount);
|
|
|
|
$protoCreation->setReceiverAmount($receiverAmount);
|
|
|
|
//echo "receiver amount: check<br>";
|
|
$identHashBytes = stream_get_contents($transactionCreationEntity->ident_hash);
|
|
$protoCreation->setIdentHash(intval($identHashBytes));
|
|
return new TransactionCreation($protoCreation);
|
|
}
|
|
}
|