hexdec($addressversion)) { return false; } $check = substr($addr, 0, strlen($addr) - 8); $check = pack("H*", $check); $check = strtoupper(hash("sha256", hash("sha256", $check, true))); $check = substr($check, 0, 8); return $check == substr($addr, strlen($addr) - 8); } /** * Convert the input to its 160-bit Bitcoin hash * * @param string $data * @return string * @access private */ private function hash160($data) { $data = pack("H*", $data); return strtoupper(hash("ripemd160", hash("sha256", $data, true))); } /** * Convert a Bitcoin public key to a 160-bit Bitcoin hash * * @param string $pubkey * @return string * @access public */ public static function pubKeyToAddress($pubkey) { return self::hash160ToAddress(self::hash160($pubkey)); } /** * Remove leading "0x" from a hex value if present. * * @param string $string * @return string * @access public */ public static function remove0x($string) { if (substr($string, 0, 2) == "0x" || substr($string, 0, 2) == "0X") { $string = substr($string, 2); } return $string; } } /** * Exception class for BitcoinClient * * @author Mike Gogulski * http://www.gogulski.com/ http://www.nostate.com/ */ class BitcoinClientException extends ErrorException { // Redefine the exception so message isn't optional public function __construct($message, $code = 0, $severity = E_USER_NOTICE, Exception $previous = null) { parent::__construct($message, $code, $severity, $previous); } public function __toString() { return __CLASS__ . ": [{$this->code}]: {$this->message}\n"; } } require_once(INCLUDE_DIR . "/jsonRPCClient.php"); /** * Bitcoin client class for access to a Bitcoin server via JSON-RPC-HTTP[S] * * Implements the methods documented at https://www.bitcoin.org/wiki/doku.php?id=api * * @version 0.3.19 * @author Mike Gogulski * http://www.gogulski.com/ http://www.nostate.com/ */ class BitcoinClient extends jsonRPCClient { /** * Create a jsonrpc_client object to talk to the bitcoin server and return it, * or false on failure. * * @param string $scheme * "http" or "https" * @param string $username * User name to use in connection the Bitcoin server's JSON-RPC interface * @param string $password * Server password * @param string $address * Server hostname or IP address * @param mixed $port * Server port (string or integer) * @param string $certificate_path * Path on the local filesystem to server's PEM certificate (ignored if $scheme != "https") * @param integer $debug_level * 0 (default) = no debugging; * 1 = echo JSON-RPC messages received to stdout; * 2 = log transmitted messages also * @return jsonrpc_client * @access public * @throws BitcoinClientException */ public function __construct($scheme, $username, $password, $address = "localhost", $port = 8332, $certificate_path = '', $debug_level = 0) { $scheme = strtolower($scheme); if ($scheme != "http" && $scheme != "https") throw new BitcoinClientException("Scheme must be http or https"); if (empty($username)) throw new BitcoinClientException("Username must be non-blank"); if (empty($password)) throw new BitcoinClientException("Password must be non-blank"); $port = (string) $port; if (!$port || empty($port) || !is_numeric($port) || $port < 1 || $port > 65535 || floatval($port) != intval($port)) throw new BitcoinClientException("Port must be an integer and between 1 and 65535"); if (!empty($certificate_path) && !is_readable($certificate_path)) throw new BitcoinClientException("Certificate file " . $certificate_path . " is not readable"); $uri = $scheme . "://" . $username . ":" . $password . "@" . $address . "/"; parent::__construct($uri); } /** * Test if the connection to the Bitcoin JSON-RPC server is working * * The check is done by calling the server's getinfo() method and checking * for a fault. * * @return mixed boolean TRUE if successful, or a fault string otherwise * @access public * @throws none */ public function can_connect() { try { $r = $this->getinfo(); } catch (Exception $e) { return $e->getMessage(); } return true; } }