1: <?php
2:
3: namespace Liberty;
4:
5: use Liberty\LECDSA;
6: use Liberty\SSV;
7: use Liberty\INI;
8:
9: use Defuse\Crypto\Key;
10: use Defuse\Crypto\Crypto;
11: use Defuse\Crypto\KeyProtectedByPassword;
12:
13: use Defuse\Crypto\Exception as Ex;
14: use Exception;
15:
16:
17: /**
18: * Liberty Wallet Class
19: *
20: * @category Cryptocurrency
21: * @package Liberty
22: * @license http://www.opensource.org/licenses/mit-license.php MIT License
23: * @version 1.0.0
24: * @since 2018-01-27
25: * @author Liberty Group <cryptolibertygroup@gmail.com>
26: */
27:
28:
29:
30:
31: class Wallet {
32:
33: /**
34: * File where wallet is archived.
35: * @var string
36: */
37: protected $wallet;
38:
39:
40: /**
41: * Wallet password.
42: * @var string
43: */
44: public $password;
45:
46:
47: /**
48: * A list of Private Keys
49: * @var array
50: */
51: public $addresses;
52:
53:
54:
55:
56:
57: /**
58: * Create a new Wallet object.
59: *
60: * @return string|bool An error string or true.
61: * @param string $fullPath The full path to the wallet file.
62: */
63: public function __construct($fullPath, $password)
64: {
65: if($fullPath == "") return false;
66: if($password == "") return false;
67:
68: $this->wallet = $fullPath;
69: $this->password = $password;
70:
71: if (file_exists($this->wallet)) {
72: $this->settingLoad();
73: }
74: }
75:
76:
77:
78:
79: // Public //
80:
81: /**
82: * Create a new random liberty EC address.
83: *
84: * @return array An array with raw, privk and pubk values.
85: */
86: public function addressNew()
87: {
88: $ec = new LECDSA();
89: $ec->generateRandomPrivateKey();
90: $addr = array();
91:
92: /*
93: echo "----------------------------------------------------" . "\n";
94: echo "Raw Priv Key: " . $ec->getPrivateKey() . "\n";
95: echo "Private Key (WIF): " . $ec->getWif() . "\n";
96: echo "Pub Addr Compressed: " . $ec->getUncompressedAddress() . "\n";
97: echo "----------------------------------------------------" . "\n";
98: */
99:
100: $addr["raw"] = $ec->getPrivateKey();
101: $addr["privk"] = $ec->getWif();
102: $addr["pubk"] = $ec->getUncompressedAddress();
103:
104: $this->addressImport($addr["privk"]);
105:
106: if($this->settingSave()) {
107: return $addr;
108: } else {
109: return false;
110: }
111: }
112:
113:
114:
115:
116: public function addressTx()
117: {
118:
119: }
120:
121:
122:
123:
124: public function addressList() {
125: $addr = array();
126: $ec = new LECDSA();
127:
128: for($a=0; $a<count($this->addresses); $a++) {
129: $ec->setPrivateKeyWithWif($this->addresses[$a]);
130: $addr[$a] = $ec->getUncompressedAddress();
131: }
132:
133: return $addr;
134: }
135:
136:
137:
138:
139: public function address($privk)
140: {
141: $ec = new LECDSA();
142: $ec->setPrivateKeyWithWif($privk);
143: return $ec->getUncompressedAddress();
144: }
145:
146:
147:
148:
149: public function addressImport($privk)
150: {
151: $a = count($this->addresses);
152: $this->addresses[$a] = $privk;
153: $this->settingSave();
154: return $this->address($privk);
155: }
156:
157:
158:
159:
160:
161: public function addressExport($pubk)
162: {
163: $ec = new LECDSA();
164:
165: for($a=0; $a<count($this->addresses); $a++) {
166: $ec->setPrivateKeyWithWif($this->addresses[$a]);
167: if($pubk == $ec->getUncompressedAddress()) {
168: return $ec->getWif();
169: }
170: }
171:
172: return "";
173: }
174:
175:
176:
177:
178:
179:
180:
181: public function isPasswordValid()
182: {
183: if($this->password == "") return false;
184: if(!file_exists($this->wallet)) return false;
185:
186: $passwordHash = self::getPasswordHash($this->password);
187:
188: $wallet = INI::read($this->wallet);
189: $protectedKeyAscii = $wallet["Password"]["pwd"];
190:
191: $protectedKey = KeyProtectedByPassword::loadFromAsciiSafeString($protectedKeyAscii);
192:
193: try {
194: $key = $protectedKey->unlockKey($passwordHash);
195: return true;
196: } catch (Ex\WrongKeyOrModifiedCiphertextException $ex) {
197: return false;
198: }
199: }
200:
201:
202:
203:
204:
205: public function settingLoad()
206: {
207: if($this->password == "") return false;
208: $passwordHash = self::getPasswordHash($this->password);
209:
210: $wallet = INI::read($this->wallet);
211:
212: $protectedKeyAscii = $wallet["Password"]["pwd"];
213:
214: $protectedKey = KeyProtectedByPassword::loadFromAsciiSafeString($protectedKeyAscii);
215:
216: try {
217: $key = $protectedKey->unlockKey($passwordHash);
218: } catch (Ex\WrongKeyOrModifiedCiphertextException $ex) {
219: return "Password is wrong!.";
220: }
221:
222: $a=0;
223: while( isset($wallet["Addresses"]["addr"][$a]) ) {
224: try {
225: $this->addresses[$a] = Crypto::decrypt($wallet["Addresses"]["addr"][$a], $key);
226: } catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) {
227: return "File is corrupted!.";
228: }
229:
230: $a++;
231: }
232:
233: return true;
234: }
235:
236:
237:
238: public function settingSave()
239: {
240: if($this->password == "") return false;
241: $passwordHash = self::getPasswordHash($this->password);
242: $protectedKeyAscii = "";
243:
244: if(!file_exists($this->wallet)) {
245: $protectedKey = KeyProtectedByPassword::createRandomPasswordProtectedKey($passwordHash);
246: $protectedKeyAscii = $protectedKey->saveToAsciiSafeString();
247:
248: } else {
249: $wallet = INI::read($this->wallet);
250: $protectedKeyAscii = $wallet["Password"]["pwd"];
251: }
252:
253: $protectedKey = KeyProtectedByPassword::loadFromAsciiSafeString($protectedKeyAscii);
254:
255: try {
256: $key = $protectedKey->unlockKey($passwordHash);
257: } catch (Ex\WrongKeyOrModifiedCiphertextException $ex) {
258: return "Password is wrong!.";
259: }
260:
261: // Password
262: $write["Password"]["pwd"] = $protectedKeyAscii;
263:
264: // Addresses
265: for($a=0; $a<count($this->addresses); $a++) {
266: $write["Addresses"]["addr"][$a] = Crypto::encrypt($this->addresses[$a], $key);
267: }
268:
269: // PubKeys
270: for($a=0; $a<count($this->addresses); $a++) {
271: $write["PubKeys"]["pubk"][$a] = $this->address($this->addresses[$a]);
272: }
273:
274: INI::write($this->wallet, $write);
275:
276: return true;
277: }
278:
279:
280:
281:
282: public static function getPasswordHash($password)
283: {
284: return hash("sha512", $password);
285: }
286:
287:
288:
289:
290: public static function hash512($password)
291: {
292: return hash( "sha512", hex2bin(hash("sha512", $password)) );
293: }
294:
295:
296:
297:
298: public static function addressFee($wallet) {
299: if($wallet == "") return 0;
300: if(!file_exists($wallet)) return 0;
301:
302: $ini = INI::read($wallet);
303:
304: if(isset($ini["PubKeys"]["pubk"][0])) {
305: return $ini["PubKeys"]["pubk"][0];
306: } else {
307: return 0;
308: }
309: }
310:
311:
312:
313:
314:
315:
316:
317:
318: }
319:
320:
321: ?>
322: