123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- <?php
- namespace App\Servers\Icon;
- use kornrunner\Keccak;
- /**
- * Class Utils
- * @package common\components\eth
- */
- class Utils
- {
- public static function fixHex($hex)
- {
- $hex = strtolower($hex);
- $hex = substr($hex, 0, 2) === '0x' ? $hex : ('0x' . $hex);
- if (strcmp($hex, '0x') === 0) {
- $hex = '0x0';
- }
- return $hex;
- }
- /**
- * @param string $url
- * @param mixed $rawData
- * @param int $timeout
- * @return bool|string
- */
- public static function post($url, $rawData, $timeout = 3)
- {
- $options = [
- CURLOPT_URL => $url,
- CURLOPT_POST => true,
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_FOLLOWLOCATION => true,
- CURLOPT_AUTOREFERER => true,
- CURLOPT_HEADER => false,
- CURLOPT_TIMEOUT => 5,
- CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_0,
- CURLOPT_HTTPHEADER => [
- 'Content-Type: application/json',
- 'Accept: application/json',
- ],
- CURLOPT_TIMEOUT => $timeout,
- CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
- CURLOPT_SSL_VERIFYHOST => false,
- CURLOPT_SSL_VERIFYPEER => false,
- CURLOPT_POSTFIELDS => $rawData,
- ];
- $ch = curl_init();
- curl_setopt_array($ch, $options);
- $rawResp = curl_exec($ch);
- // $e=curl_error($ch);
- if ($rawResp === false) {
- return false;
- }
- curl_close($ch);
- return $rawResp;
- }
- /**
- * Convert to wei
- * @param string $fund eg: 1eth, 0.1gwei
- * @return bool|string
- */
- public static function toWei($fund)
- {
- $pattern = '/^([\d]+(?:\.\d+)?)([a-zA-Z]+)/i';
- if (!preg_match($pattern, $fund, $matches)) {
- return false;
- }
- $fund = $matches[1];
- $unit = strtolower($matches[2]);
- return self::convertUnit($fund, $unit, 'wei');
- }
- /**
- * Convert to eth
- * @param string $fund eg: 567wei, 123gwei
- * @return bool|string
- */
- public static function toEther($fund)
- {
- $pattern = '/^([\d]+(?:\.\d+)?)([a-zA-Z]+)/i';
- if (!preg_match($pattern, $fund, $matches)) {
- return false;
- }
- $fund = $matches[1];
- $unit = strtolower($matches[2]);
- return self::convertUnit($fund, $unit, 'eth');
- }
- public static function fund2int($fund, $decimal = 18)
- {
- $rate = "1" . str_repeat('0', $decimal);
- return bcmul($fund, $rate);
- }
- public static function int2fund($int, $decimal = 18)
- {
- $rate = "1" . str_repeat('0', $decimal);
- $result = bcdiv($int, $rate, 5);
- if (strpos($result, '.') !== false) {
- list($int, $dec) = explode('.', $result);
- $dec = rtrim($dec, '0');
- if ($dec !== '') {
- $result = $int . '.' . $dec;
- } else {
- $result = $int;
- }
- }
- return $result;
- }
- /**
- * Ethereum units count against each other
- * @param string $number
- * @param string $from
- * @param string $to
- * @return bool|string
- */
- public static function convertUnit($number, $from, $to)
- {
- $units = [
- 'wei' => 0,
- 'kwei' => 3,
- 'mwei' => 6,
- 'gwei' => 9,
- 'microether' => 12,
- 'milliether' => 15,
- 'ether' => 18,
- 'eth' => 18,
- ];
- if (!isset($units[$from]) || !isset($units[$to])) {
- return false;
- }
- $maxDecimal = max($units); // max scale
- if ($units[$from] > $units[$to]) {
- $operator = "1" . str_repeat("0", $units[$from] - $units[$to]);
- $result = bcmul($number, $operator, $maxDecimal);
- } elseif ($units[$from] == $units[$to]) {
- $result = $number;
- } else {
- $operator = "1" . str_repeat("0", $units[$to] - $units[$from]);
- $result = bcdiv($number, $operator, $maxDecimal);
- }
- // The number of excess decimal digits after removing the result
- if (strpos($result, '.') !== false) {
- list($int, $dec) = explode('.', $result);
- $dec = rtrim($dec, '0');
- if ($dec !== '') {
- $result = $int . '.' . $dec;
- } else {
- $result = $int;
- }
- }
- return $result;
- }
- /**
- * @param $method
- * @param array $args
- * @return false|string
- */
- public static function decodeSolMethod($method, $args = [])
- {
- $pattern = '/^[a-z0-9]+\(([^\)]+)\)$/i';
- if (!preg_match($pattern, $method, $matched)) {
- return false;
- }
- try {
- $sign = substr(Keccak::hash($method, 256), 0, 8);
- $params = explode(',', $matched[1]); // 分析参数
- foreach ($params as $key => $param) {
- $arg = $args[$key];
- if (strpos($param, 'uint') !== false || strpos($param, 'int') !== false) {
- $paramSign = substr(self::dec2hex($arg), 2);
- } elseif (strpos($param, 'address') !== false) {
- $paramSign = substr(self::fixHex($arg), 2);
- } else {
- return false;
- }
- $sign .= str_pad($paramSign, 64, '0', STR_PAD_LEFT);
- }
- return self::fixHex($sign);
- } catch (\Exception $e) {
- return false;
- }
- }
- public static function dec2hex($number)
- {
- $hexvalues = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];
- $hexval = '';
- while ($number != '0') {
- $hexval = $hexvalues[bcmod($number, '16')] . $hexval;
- $number = bcdiv($number, '16', 0);
- }
- return self::fixHex($hexval);
- }
- public static function hex2dec($number)
- {
- if (strpos($number, '0x') !== false) {
- $number = substr($number, 2);
- }
- $number = strtoupper($number);
- $decvalues = [
- '0' => '0', '1' => '1', '2' => '2',
- '3' => '3', '4' => '4', '5' => '5',
- '6' => '6', '7' => '7', '8' => '8',
- '9' => '9', 'A' => '10', 'B' => '11',
- 'C' => '12', 'D' => '13', 'E' => '14',
- 'F' => '15'
- ];
- $decval = '0';
- $number = strrev($number);
- for ($i = 0; $i < strlen($number); $i++) {
- $decval = bcadd(bcmul(bcpow('16', $i, 0), $decvalues[$number[$i]]), $decval);
- }
- return $decval;
- }
- public static function prettyNum($number)
- {
- if ($number > 10000) {
- $number = bcdiv($number, "10000", 2) . '万';
- }
- return $number;
- }
- }
|