<?php use BitWasp\BitcoinLib\BitcoinLib; require_once __DIR__ . '/../vendor/autoload.php'; $magic_byte = '00'; $keypair = BitcoinLib::get_new_key_set($magic_byte); echo "Key pair: \n"; print_r($keypair); echo "\n"; $compress = BitcoinLib::compress_public_key($keypair['pubKey']); echo "Compressed public key: {$compress} \n"; $decompress = BitcoinLib::decompress_public_key($compress); echo "Decompressed key info: \n"; print_r($decompress); echo "\n"; $address = BitcoinLib::public_key_to_address($compress, $magic_byte); echo "decoding {$address}\n"; echo BitcoinLib::base58_decode($address); echo "\n\n"; $sc = '5357'; $ad = BitcoinLib::public_key_to_address($sc, '05'); echo $ad . "\n";
public function testBase58FunctionsForConsistency() { $cnt = (getenv('BITCOINLIB_EXTENSIVE_TESTING') ?: 1) * 50; for ($i = 0; $i < $cnt; $i++) { // Generate a random length hex string. $hex = (string) bin2hex(mcrypt_create_iv(20, \MCRYPT_DEV_URANDOM)); $encode = BitcoinLib::base58_encode($hex); $decode = BitcoinLib::base58_decode($encode); $this->assertTrue($hex == $decode); } }
/** * Create * * This function creates a raw transaction from an array of inputs, * and an array of outputs. It takes essentially the same data is * bitcoind's createrawtransaction function. * * Inputs: Each input is a child array of [txid, vout, and optionally a sequence number.] * Outputs: Each output is a key in the array: address => $value. * * @param array $inputs * @param array $outputs [address => value, ] or [[address, value], ] * or [['address' => address, 'value' => value], ] * or [['scriptPubKey' => scriptPubKey, 'value' => value], ] * @param string $magic_byte * @param string $magic_p2sh_byte * @return string|FALSE */ public static function create($inputs, $outputs, $magic_byte = null, $magic_p2sh_byte = null) { $magic_byte = BitcoinLib::magicByte($magic_byte); $magic_p2sh_byte = BitcoinLib::magicP2SHByte($magic_p2sh_byte); $tx_array = array('version' => '1'); // Inputs is the set of [txid/vout/scriptPubKey] $tx_array['vin'] = array(); foreach ($inputs as $i => $input) { if (!isset($input['txid']) || strlen($input['txid']) !== 64 || !isset($input['vout']) || !is_numeric($input['vout'])) { throw new \InvalidArgumentException("Invalid input [{$i}]"); } $tx_array['vin'][] = ['txid' => $input['txid'], 'vout' => $input['vout'], 'sequence' => isset($input['sequence']) ? $input['sequence'] : 4294967295, 'scriptSig' => ['hex' => '']]; } // Outputs is the set of [address/amount] $tx_array['vout'] = array(); foreach ($outputs as $k => $v) { $address = null; $scriptPubKey = null; if (is_numeric($k)) { if (!is_array($v)) { throw new \InvalidArgumentException("outputs should be [address => value, ] or [[address, value], ]" . "or [['address' => address, 'value' => value], ] or [['scriptPubKey' => scriptPubKey, 'value' => value], ]"); } if (isset($v['scriptPubKey']) && isset($v['value'])) { $scriptPubKey = $v['scriptPubKey']; $value = $v['value']; } else { if (isset($v['address']) && isset($v['value'])) { $address = $v['address']; $value = $v['value']; } else { if (count($v) == 2 && isset($v[0]) && isset($v[1])) { $address = $v[0]; $value = $v[1]; } else { throw new \InvalidArgumentException("outputs should be [address => value, ] or [[address, value], ]" . "or [['address' => address, 'value' => value], ] or [['scriptPubKey' => scriptPubKey, 'value' => value], ]"); } } } } else { $address = $k; $value = $v; } if (!is_int($value)) { throw new \InvalidArgumentException("Values should be in Satoshis [{$value}]"); } if (!$scriptPubKey) { if (!BitcoinLib::validate_address($address, $magic_byte, $magic_p2sh_byte)) { throw new \InvalidArgumentException("Invalid address [{$address}]"); } $decode_address = BitcoinLib::base58_decode($address); $version = substr($decode_address, 0, 2); $hash = substr($decode_address, 2, 40); if ($version == $magic_p2sh_byte) { // OP_HASH160 <scriptHash> OP_EQUAL $scriptPubKey = "a914{$hash}87"; } else { // OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG $scriptPubKey = "76a914{$hash}88ac"; } } $tx_array['vout'][] = ['value' => $value, 'scriptPubKey' => ['hex' => $scriptPubKey]]; } $tx_array['locktime'] = 0; return self::encode($tx_array); }
public static function import($ext_key) { $hex = BitcoinLib::base58_decode($ext_key); $key = []; $key['magic_bytes'] = substr($hex, 0, 8); $magic_byte_info = self::describe_magic_bytes($key['magic_bytes']); // Die if key type isn't supported by this library. if ($magic_byte_info == false) { throw new \InvalidArgumentException("Unsupported magic byte"); } $key['type'] = $magic_byte_info['type']; $key['testnet'] = $magic_byte_info['testnet']; $key['network'] = $magic_byte_info['network']; $key['version'] = $magic_byte_info['version']; $key['depth'] = gmp_strval(gmp_init(substr($hex, 8, 2), 16), 10); $key['fingerprint'] = substr($hex, 10, 8); $key['i'] = substr($hex, 18, 8); $key['address_number'] = self::get_address_number($key['i']); $key['chain_code'] = substr($hex, 26, 64); $key['is_compressed'] = true; if ($key['type'] == 'public') { $key_start_position = 90; $offset = 66; } else { $key_start_position = 92; $offset = 64; } $key['key'] = substr($hex, $key_start_position, $offset); if (!in_array($key['type'], ['public', 'private'])) { throw new \InvalidArgumentException("Invalid type"); } // Validate obtained key if ($key['type'] == 'public' && !BitcoinLib::validate_public_key($key['key'])) { throw new \InvalidArgumentException("Invalid public key"); } if ($key['type'] == 'private' && !self::check_valid_hmac_key($key['key'])) { throw new \InvalidArgumentException("Invalid private key"); } return $key; }