forked from inoutcode/bitcoin_book_2nd
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
1,066 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#include <bitcoin/bitcoin.hpp> | ||
|
||
int main() | ||
{ | ||
// base16格式的私钥 | ||
bc::ec_secret decoded; | ||
bc::decode_base16(decoded, | ||
"038109007313a5807b2eccc082c8c3fbb988a973cacf1a7df9ce725c31b14776"); | ||
|
||
bc::wallet::ec_private secret( | ||
decoded, bc::wallet::ec_private::mainnet_p2kh); | ||
|
||
// 生成公钥 | ||
bc::wallet::ec_public public_key(secret); | ||
std::cout << "Public key: " << public_key.encoded() << std::endl; | ||
|
||
// 生成比特币地址 | ||
// 一般可以使用: | ||
// bc::wallet::payment_address payaddr = | ||
// public_key.to_payment_address( | ||
// bc::wallet::ec_public::mainnet_p2kh); | ||
// const std::string address = payaddr.encoded(); | ||
|
||
// 计算用于P2PKH地址的公钥哈希值 . | ||
bc::data_chunk public_key_data; | ||
public_key.to_data(public_key_data); | ||
const auto hash = bc::bitcoin_short_hash(public_key_data); | ||
|
||
bc::data_chunk unencoded_address; | ||
// 预留25字节空间 | ||
// [ version:1 ] | ||
// [ hash:20 ] | ||
// [ checksum:4 ] | ||
unencoded_address.reserve(25); | ||
// 版本号字节, 0 代表普通的 BTC 地址 (P2PKH). | ||
unencoded_address.push_back(0); | ||
// 哈希值 | ||
bc::extend_data(unencoded_address, hash); | ||
// 计算哈希值的校验和并放入前4个字节 | ||
bc::append_checksum(unencoded_address); | ||
// 最后使用base58编码 | ||
assert(unencoded_address.size() == 25); | ||
const std::string address = bc::encode_base58(unencoded_address); | ||
|
||
std::cout << "Address: " << address << std::endl; | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import ecdsa | ||
import os | ||
|
||
# secp256k1, http://www.oid-info.com/get/1.3.132.0.10 | ||
_p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F | ||
_r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 | ||
_b = 0x0000000000000000000000000000000000000000000000000000000000000007 | ||
_a = 0x0000000000000000000000000000000000000000000000000000000000000000 | ||
_Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 | ||
_Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 | ||
curve_secp256k1 = ecdsa.ellipticcurve.CurveFp(_p, _a, _b) | ||
generator_secp256k1 = ecdsa.ellipticcurve.Point(curve_secp256k1, _Gx, _Gy, _r) | ||
oid_secp256k1 = (1, 3, 132, 0, 10) | ||
SECP256k1 = ecdsa.curves.Curve("SECP256k1", curve_secp256k1, | ||
generator_secp256k1, oid_secp256k1) | ||
ec_order = _r | ||
|
||
curve = curve_secp256k1 | ||
generator = generator_secp256k1 | ||
|
||
|
||
def random_secret(): | ||
convert_to_int = lambda array: int("".join(array).encode("hex"), 16) | ||
|
||
# 从OS的密码学安全的随机数发生器中收集256位随机数据 | ||
byte_array = os.urandom(32) | ||
|
||
return convert_to_int(byte_array) | ||
|
||
|
||
def get_point_pubkey(point): | ||
if (point.y() % 2) == 1: | ||
key = '03' + '%064x' % point.x() | ||
else: | ||
key = '02' + '%064x' % point.x() | ||
return key.decode('hex') | ||
|
||
|
||
def get_point_pubkey_uncompressed(point): | ||
key = ('04' + | ||
'%064x' % point.x() + | ||
'%064x' % point.y()) | ||
return key.decode('hex') | ||
|
||
|
||
# 生成私钥 | ||
secret = random_secret() | ||
print("Secret: ", secret) | ||
|
||
# 生成公钥 | ||
point = secret * generator | ||
print("EC point:", point) | ||
|
||
print("BTC public key:", get_point_pubkey(point).encode("hex")) | ||
|
||
# 给定点(x,y),我们可以使用以下方法创建对象 | ||
point1 = ecdsa.ellipticcurve.Point(curve, point.x(), point.y(), ec_order) | ||
assert(point1 == point) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
from __future__ import print_function | ||
import bitcoin | ||
|
||
# 随机生成一个私钥 | ||
valid_private_key = False | ||
while not valid_private_key: | ||
private_key = bitcoin.random_key() | ||
decoded_private_key = bitcoin.decode_privkey(private_key, 'hex') | ||
valid_private_key = 0 < decoded_private_key < bitcoin.N | ||
|
||
print("Private Key (hex) is: ", private_key) | ||
print("Private Key (decimal) is: ", decoded_private_key) | ||
|
||
# 将私钥转换为WIF格式 | ||
wif_encoded_private_key = bitcoin.encode_privkey(decoded_private_key, 'wif') | ||
print("Private Key (WIF) is: ", wif_encoded_private_key) | ||
|
||
# 添加"01"后缀,表示压缩的私钥 | ||
compressed_private_key = private_key + '01' | ||
print("Private Key Compressed (hex) is: ", compressed_private_key) | ||
|
||
# 生成 WIF-compressed | ||
wif_compressed_private_key = bitcoin.encode_privkey( | ||
bitcoin.decode_privkey(compressed_private_key, 'hex'), 'wif_compressed') | ||
print("Private Key (WIF-Compressed) is: ", wif_compressed_private_key) | ||
|
||
# 乘以EC生成点G,生成公钥 | ||
public_key = bitcoin.fast_multiply(bitcoin.G, decoded_private_key) | ||
print("Public Key (x,y) coordinates is:", public_key) | ||
|
||
# 编码成十六进制,以04开头 | ||
hex_encoded_public_key = bitcoin.encode_pubkey(public_key, 'hex') | ||
print("Public Key (hex) is:", hex_encoded_public_key) | ||
|
||
# 压缩公钥,根据y是偶数还是奇数来调整前缀 | ||
(public_key_x, public_key_y) = public_key | ||
compressed_prefix = '02' if (public_key_y % 2) == 0 else '03' | ||
hex_compressed_public_key = compressed_prefix + (bitcoin.encode(public_key_x, 16).zfill(64)) | ||
print("Compressed Public Key (hex) is:", hex_compressed_public_key) | ||
|
||
# 从公钥生成比特币地址 | ||
print("Bitcoin Address (b58check) is:", bitcoin.pubkey_to_address(public_key)) | ||
|
||
# 从压缩的公钥生成压缩的比特币地址 | ||
print("Compressed Bitcoin Address (b58check) is:", | ||
bitcoin.pubkey_to_address(hex_compressed_public_key)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#include <random> | ||
#include <bitcoin/bitcoin.hpp> | ||
|
||
// 要搜索的字符串 | ||
const std::string search = "1kid"; | ||
|
||
// 随机生成密钥 | ||
bc::ec_secret random_secret(std::default_random_engine& engine); | ||
// 从EC密钥中生成比特币地址 | ||
std::string bitcoin_address(const bc::ec_secret& secret); | ||
// 与要搜索的字符串进行比较(大小写敏感) | ||
bool match_found(const std::string& address); | ||
|
||
int main() | ||
{ | ||
// Linux上的 random_device 使用 "/dev/urandom" | ||
// 注意: 根据具体实现,随机源可能不是足够安全的! | ||
// 不要在生产环境中使用本例生成的虚荣地址 | ||
std::random_device random; | ||
std::default_random_engine engine(random()); | ||
|
||
// 连续循环... | ||
while (true) | ||
{ | ||
// 生成随机私钥. | ||
bc::ec_secret secret = random_secret(engine); | ||
// 生成地址 | ||
std::string address = bitcoin_address(secret); | ||
// 是否与目标字符串匹配 (1kid) | ||
if (match_found(address)) | ||
{ | ||
// 成功 | ||
std::cout << "Found vanity address! " << address << std::endl; | ||
std::cout << "Secret: " << bc::encode_base16(secret) << std::endl; | ||
return 0; | ||
} | ||
} | ||
// 不可能运行到这里 | ||
return 0; | ||
} | ||
|
||
bc::ec_secret random_secret(std::default_random_engine& engine) | ||
{ | ||
// 生成新的密钥... | ||
bc::ec_secret secret; | ||
// 遍历每个字节设置随机值... | ||
for (uint8_t& byte: secret) | ||
byte = engine() % std::numeric_limits<uint8_t>::max(); | ||
// 返回结果. | ||
return secret; | ||
} | ||
|
||
std::string bitcoin_address(const bc::ec_secret& secret) | ||
{ | ||
// 将密钥转换为付款地址 | ||
bc::wallet::ec_private private_key(secret); | ||
bc::wallet::payment_address payaddr(private_key); | ||
// 返回加密的形式. | ||
return payaddr.encoded(); | ||
} | ||
|
||
bool match_found(const std::string& address) | ||
{ | ||
auto addr_it = address.begin(); | ||
// 比较字符串前缀 | ||
for (auto it = search.begin(); it != search.end(); ++it, ++addr_it) | ||
if (*it != std::tolower(*addr_it)) | ||
return false; | ||
// 匹配 | ||
return true; | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.