我们回顾比特币地址产生的完整过程,从私钥、到公钥(椭圆曲线上某个点)、再到双重哈希地址,到最终的 Base58Check编码。例4-3的C++代码完整详细的展示了从私钥到Base58Check编码后的比特币地址的步骤。代码中使用“3.3 其他客户端、资料库、工具包 ”一节中介绍的libbitcoin库中的助手函数。

    例4-3.从私钥中创建Base58Check编码的比特币地址

    addr.cpp文件中的代码如下:

    #include <bitcoin/bitcoin.hpp>
    
    int main()
    {
        // Private secret key string as base16
        bc::ec_secret decoded;
        bc::decode_base16(decoded,
            "038109007313a5807b2eccc082c8c3fbb988a973cacf1a7df9ce725c31b14776");
    
        bc::wallet::ec_private secret(
            decoded, bc::wallet::ec_private::mainnet_p2kh);
    
        // Get public key.
        bc::wallet::ec_public public_key(secret);
        std::cout << "Public key: " << public_key.encoded() << std::endl;
    
        // Create Bitcoin address.
        // Normally you can use:
        //    bc::wallet::payment_address payaddr =
        //        public_key.to_payment_address(
        //            bc::wallet::ec_public::mainnet_p2kh);
        //  const std::string address = payaddr.encoded();
    
        // Compute hash of public key for P2PKH address.
        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;
        // Reserve 25 bytes
        //   [ version:1  ]
        //   [ hash:20    ]
        //   [ checksum:4 ]
        unencoded_address.reserve(25);
        // Version byte, 0 is normal BTC address (P2PKH).
        unencoded_address.push_back(0);
        // Hash data
        bc::extend_data(unencoded_address, hash);
        // Checksum is computed by hashing data, and adding 4 bytes from hash.
        bc::append_checksum(unencoded_address);
        // Finally we must encode the result in Bitcoin's base58 encoding.
        assert(unencoded_address.size() == 25);
        const std::string address = bc::encode_base58(unencoded_address);
    
        std::cout << "Address: " << address << std::endl;
        return 0;
    }

    上述代码使用预定义的私钥在每次运行时产生相同的比特币地址,如下例所示

    例4-4 编译并运行addr代码

     Compile the addr.cpp code
    $ g++ -o addr addr.cpp $(pkg-config --cflags --libs libbitcoin)
    Run the addr executable
    $ ./addr
    Public key: 0202a406624211f2abbdc68da3df929f938c3399dd79fac1b51b0e4ad1d26a47aa
    Address: 1PRTTaJesdNovgne6Ehcdu1fpEdX7913CK

    提示 例4-4中的代码从压缩公钥(参见上面的“压缩公钥”一节)生成了一个比特币地址(1PRTT…)。如果使用了未压缩公钥,就会生成另外一个地址(14K1y…)。