1: <?php
2:
3: namespace Liberty;
4:
5: use Liberty\SSV;
6: use Liberty\LECDSA;
7: use Liberty\Blockchain;
8: use Exception;
9:
10:
11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
21:
22:
23: class Transaction extends SSV {
24:
25: public $path;
26: public $ec;
27: public $bc;
28: public $sender;
29: public $receiver;
30: public $amount;
31: public $fee;
32: public $time;
33:
34:
35:
36: public function __construct($path)
37: {
38: if($path == "") {
39: throw new Exception("Must set the path to transactions file.");
40: return false;
41: }
42:
43: $this->path = $path;
44: $this->ssv = $path . "/tx-1.ssv";
45: $this->ec = new LECDSA();
46: }
47:
48:
49:
50:
51: public function message()
52: {
53: $sign = $this->sender . " ";
54: $sign .= $this->receiver . " ";
55: $sign .= $this->amount . " ";
56: $sign .= $this->fee . " ";
57: $sign .= $this->time;
58: return $sign;
59: }
60:
61:
62:
63:
64: public function receiver($message)
65: {
66: $msg = explode(" ", $message);
67:
68: if( self::verify($msg[0], $msg[1], $msg[2], $msg[3], $msg[4], $msg[5]) ) {
69:
70: $res = fopen($this->ssv, "a");
71: fputs($res, $message . "\n");
72: fclose($res);
73:
74: return $message;
75:
76: } else {
77: throw new Exception("Transaction has errors.");
78: return false;
79: }
80: }
81:
82:
83:
84: public function rtransaction($privk, $receiver, $amount, $fee=0)
85: {
86: if($privk == "") {
87: throw new Exception("Transaction need a private key.");
88: return false;
89: }
90:
91: if($receiver == "") {
92: throw new Exception("Transaction have not a receiver address.");
93: return false;
94: }
95:
96: if($amount == 0) {
97: throw new Exception("Transaction have no spend.");
98: return false;
99: }
100:
101: $this->ec->setPrivateKeyWithWif($privk);
102:
103: $this->sender = $this->ec->getUncompressedAddress();
104: $this->receiver = $receiver;
105: $this->amount = $amount;
106:
107: if($fee == 0) {
108: $this->fee = self::fee($amount);
109: } else {
110: $this->fee = $fee;
111: }
112:
113: $this->time = time();
114:
115: $transaction = $this->message() . " " . $this->signature();
116:
117: return $transaction;
118: }
119:
120:
121:
122:
123: public function signature()
124: {
125: 126: 127: 128: 129: 130: 131:
132:
133:
134: $signature = $this->ec->signMessage($this->message(), true);
135: return $signature;
136: }
137:
138:
139:
140:
141: public function transaction($privk, $receiver, $amount, $fee=0)
142: {
143: if($privk == "") {
144: throw new Exception("Transaction need a private key.");
145: return false;
146: }
147:
148: if($receiver == "") {
149: throw new Exception("Transaction have not a receiver address.");
150: return false;
151: }
152:
153: if($amount == 0) {
154: throw new Exception("Transaction have no spend.");
155: return false;
156: }
157:
158: $this->bc = new Blockchain($this->path);
159:
160: $this->ec->setPrivateKeyWithWif($privk);
161:
162: $this->sender = $this->ec->getUncompressedAddress();
163: $this->receiver = $receiver;
164: $this->amount = $amount;
165:
166: if($fee == 0) {
167: $this->fee = self::fee($amount);
168: } else {
169: $this->fee = $fee;
170: }
171:
172: $this->time = time();
173:
174: if( $this->bc->balance($this->sender) < ($this->amount + $this->fee) ) {
175: throw new Exception("Account has not enough funds.");
176: return false;
177: }
178:
179: $transaction = $this->message() . " " . $this->signature();
180:
181: $res = fopen($this->ssv, "a");
182: fputs($res, $transaction . "\n");
183: fclose($res);
184:
185: return $transaction;
186: }
187:
188:
189:
190:
191: public static function fee($amount)
192: {
193: if($amount > 9) {
194: $fee = $amount * 0.001;
195: }
196:
197: if($amount < 10) {
198: $fee = 0.01;
199: }
200:
201: $fee = round($fee, 2);
202:
203: return $fee;
204: }
205:
206:
207:
208:
209: public static function verify($sender, $receiver, $amount, $fee, $time, $signature)
210: {
211: $ec = new LECDSA();
212:
213: $msg = $sender . " ";
214: $msg .= $receiver . " ";
215: $msg .= $amount . " ";
216: $msg .= $fee . " ";
217: $msg .= $time;
218:
219: return $ec->checkSignatureForMessage($sender, $signature, $msg);
220: }
221:
222:
223:
224: }
225:
226: ?>