Openssl实现生成比特币地址的base58编码

比特币协议中比特币地址的生成算法如下:

比特币地址(Bitcoin Address)是ECDSA公钥(public key)的散列,它是这样计算出来的:

Version = 1 个字节 0 ; 在测试网络上, 这个值是 1 个字节 111
Key hash = Version 与 RIPEMD-160(SHA-256(public key)) 相接
Checksum = SHA-256(SHA-256(Key hash))的前4个字节
Bitcoin Address = Base58Encode(Key hash 与 Checksum 相接)

详细参考:《比特币协议说明》

下面介绍使用openssl库实现base58编码:

#include 
#include 
#include 
#include 
#include "ecdsa_test.h"


using namespace std;

#define DOMAIN_CHECK(c) ('0'<=(c)&&(c)<='9'||'a'<=(c)&&(c)<='f'||'A'<=(c)&&(c)<='F')


#define BASE58TABLE "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"


std::string base58encode(const std::string & hexstring)
{
    std::string result = "";
    BN_CTX * bnctx = BN_CTX_new();
    BIGNUM * bn = BN_new();
    BIGNUM * bn0= BN_new();
    BIGNUM * bn58=BN_new();
    BIGNUM * dv = BN_new();
    BIGNUM * rem= BN_new();

    BN_hex2bn(&bn, hexstring.c_str());
    //printf("bn:%s\n", BN_bn2dec(bn));
    BN_hex2bn(&bn58, "3a");//58
    BN_hex2bn(&bn0,"0");

    while(BN_cmp(bn, bn0)>0){
        BN_div(dv, rem, bn, bn58, bnctx);
        BN_copy(bn, dv);
        //printf("dv: %s\n", BN_bn2dec(dv));
        //printf("rem:%s\n", BN_bn2dec(rem));
        char base58char = BASE58TABLE[BN_get_word(rem)];
        result += base58char;
    }

    std::string::iterator pbegin = result.begin();
    std::string::iterator pend   = result.end();
    while(pbegin < pend) {
        char c = *pbegin;
        *(pbegin++) = *(--pend);
        *pend = c;
    }
    return result;
}

int main() {
    std::string hex_string = "00010966776006953D5567439E5E39F86A0D273BEED61967F6";
    cout << base58encode(hex_string).c_str() << endl;
    return 0;
}

你可能感兴趣的:(区块链和数字货币)