Web3Service.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <?php
  2. namespace qiniu\services\blockchain;
  3. use qiniu\services\blockchain\bsc\Bep20;
  4. use qiniu\services\blockchain\bsc\Bep721;
  5. use qiniu\services\blockchain\bsc\Callback;
  6. use qiniu\services\blockchain\bsc\Credential;
  7. use qiniu\services\blockchain\bsc\Kit;
  8. use qiniu\services\blockchain\bsc\NodeClient;
  9. use qiniu\services\blockchain\Throwable\Web3Exception;
  10. use Web3p\EthereumUtil\Util;
  11. define('EVENTSIG_TRANSFER', '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef');
  12. class Web3Service
  13. {
  14. /** @var Bep20|Bep721 $token */
  15. private static $token;
  16. private static $decimal;
  17. private static $address;
  18. private static $kit;
  19. public function __construct($contact, $decimal, $type, $private_key)
  20. {
  21. $node = NodeClient::create('mainNet');
  22. $credential = Credential::fromKey($private_key);
  23. self::$kit = new Kit($node, $credential);
  24. self::$address = $credential->getAddress();
  25. self::$token = self::$kit->$type($contact);
  26. self::$decimal = $decimal;
  27. }
  28. /**
  29. * @param $token
  30. * @return Web3Service
  31. * @throws Web3Exception
  32. */
  33. public static function instance($token): Web3Service
  34. {
  35. if (!get_token_info($token, 'address')) {
  36. throw new Web3Exception('未定义Token');
  37. }
  38. return new self(get_token_info($token, 'address'), get_token_info($token, 'decimal'), get_token_info($token, 'type'), get_token_info($token, 'private_key'));
  39. }
  40. /**
  41. * 签名转地址
  42. * @param $str
  43. * @param $sign
  44. * @return string
  45. * @throws Web3Exception
  46. */
  47. public static function signToAddress($str, $sign)
  48. {
  49. $util = new Util();
  50. if (strlen($sign) != 132) {
  51. throw new Web3Exception('签名格式错误,类型:001');
  52. }
  53. if (!$util->isHex($sign)) {
  54. throw new Web3Exception('签名格式错误,类型:002');
  55. }
  56. $sign_str = $util->stripZero($sign);
  57. $r = substr($sign_str, 0, 64);
  58. $s = substr($sign_str, 64, 64);
  59. $v = substr($sign_str, 128, 2);
  60. $message = $util->hashPersonalMessage($str);
  61. $public_key = $util->recoverPublicKey($message, $r, $s, hexdec($v) - 27);
  62. return strtolower($util->publicKeyToAddress($public_key));
  63. }
  64. public static function getAddress()
  65. {
  66. return self::$address;
  67. }
  68. public static function getBalance($address)
  69. {
  70. return bcdiv(self::$token->balanceOf($address)->toString(), bcpow(10, self::$decimal), self::$decimal);
  71. }
  72. public static function getLastTransfer($num = 0)
  73. {
  74. return self::$token->getTransferEvents([], [], $num ? bcsub(self::$token->getBlockNumber(), $num) : 'latest');
  75. }
  76. public static function getBlockTransfer($block, $transferHash)
  77. {
  78. $res = self::$token->getTransferEvents([], [], $block, $block);
  79. $ress = [];
  80. foreach ($res as $v) {
  81. if ($v->transactionHash == $transferHash) {
  82. $ress[] = $v;
  83. }
  84. }
  85. return $ress;
  86. }
  87. public static function getTransferInfo($tx_hash)
  88. {
  89. return self::$token->getTransactionReceipt($tx_hash);
  90. }
  91. public static function transfer($to, $amount)
  92. {
  93. return self::$token->transfer($to, bcmul($amount, bcpow(10, self::$decimal)));
  94. }
  95. public static function getBNBTransferInfo($tx_hash)
  96. {
  97. return self::$token->getTransactionReceipt($tx_hash);
  98. }
  99. public static function estimateTransferGas($to, $amount)
  100. {
  101. $cb = new Callback();
  102. self::$token->estimateGas("transfer", self::$address, $to, bcmul($amount, bcpow(10, self::$decimal)), $cb);
  103. return $cb->result->toString();
  104. }
  105. public static function getData($name, ...$args)
  106. {
  107. $data = self::$token->getData($name, ...$args);
  108. $tx = [
  109. 'data' => '0x' . $data,
  110. 'to' => self::$token->getToAddress()
  111. ];
  112. return $tx;
  113. }
  114. public static function totalSupply()
  115. {
  116. $data = self::$token->totalSupply();
  117. $value = $data->toString();
  118. return bcdiv($value, bcpow(10, self::$decimal), self::$decimal);
  119. }
  120. }