Skip to content

Commit

Permalink
第四章 完成
Browse files Browse the repository at this point in the history
  • Loading branch information
inoutcode committed Jun 7, 2018
1 parent 74fcecc commit 6d33554
Show file tree
Hide file tree
Showing 18 changed files with 1,066 additions and 4 deletions.
47 changes: 47 additions & 0 deletions code/addr.cpp
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;
}
58 changes: 58 additions & 0 deletions code/ec-math.py
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)
46 changes: 46 additions & 0 deletions code/key-to-address-ecc-example.py
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))
71 changes: 71 additions & 0 deletions code/vanity-miner.cpp
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;
}
Binary file added images/mbc2_0401.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/mbc2_0402.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/mbc2_0403.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/mbc2_0404.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/mbc2_0405.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/mbc2_0406.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/mbc2_0407.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/mbc2_0408.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/mbc2_0409.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/mbc2_0410.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/mbc2_0411.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/mbc2_0412.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions 目录.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ include::前言.asciidoc[]

include::术语.asciidoc[]

include::第一章.asciidoc[] 概述
include::第一章.asciidoc[]

include::第二章.asciidoc[] 比特币如何运转
include::第二章.asciidoc[]

include::第三章.asciidoc[] Bitcoin Core参考实现
include::第三章.asciidoc[]

include::ch04.asciidoc[]
include::第四章.asciidoc[]

include::ch05.asciidoc[]

Expand Down
Loading

0 comments on commit 6d33554

Please sign in to comment.