Beispiel #1
0
address_prefix address_prefix::parse(const char * str)
{
    char str_copy[19];
    char * str_copy_p = str_copy;
    const char * tokens[5] = {str_copy,"0","0","0",NULL};
    const char ** current_token = tokens;

    for(; *str && str_copy_p < str_copy + sizeof(str_copy) - 1; ++str, ++str_copy_p)
    {
        char c = *str;
        bool new_token = false;

        if(c == '.')
        {
            if(current_token == &tokens[3]) throw std::bad_cast();

            ++current_token;
            new_token = true;
        }
        else if(c == '/')
        {
            if( (current_token == &tokens[0] &&
                str_copy_p == &str_copy[0]) ||
                current_token == &tokens[4] ) throw std::bad_cast();

            current_token = &tokens[4];
            new_token = true;
        }

        if(new_token)
        {
            if(*(str+1)=='\0') throw std::bad_cast();
            *current_token = str_copy_p + 1;
            c = '\0';
        }

        if((c != '\0' && c < '0') || c > '9') throw std::bad_cast();

        *str_copy_p = c;
    }

    // str is too big, probably caused by leading zeros.
    if(*str && str_copy_p == str_copy + sizeof(str_copy) - 1) throw std::bad_cast();

    *str_copy_p = '\0';

    unsigned long a = atoi(tokens[0]);
    unsigned long b = atoi(tokens[1]);
    unsigned long c = atoi(tokens[2]);
    unsigned long d = atoi(tokens[3]);
    if( a > 255 || b > 255 || c > 255 || d > 255) throw std::bad_cast();

    unsigned long prefix = (a << 24) | (b << 16) | (c << 8) | d;
    int maskbits = tokens[4] ? atoi(tokens[4]) : 32 ;
    if(maskbits > 32 || maskbits == 0) throw std::bad_cast();

    return address_prefix(address(prefix), address_mask(maskbits));
}
Beispiel #2
0
address_prefix address_prefix::common_prefix(const address_prefix & first, const address_prefix & second)
{
    int n = std::min(first.m_mask.bits(), second.m_mask.bits());
    int common_mask_bits = n;
    for(int i = 1; i <= n; i++)
    {
        address_mask mask_i(i);
        if((first.m_addr_prefix & mask_i) != (second.m_addr_prefix & mask_i))
        {
            common_mask_bits = i - 1;
            break;
        }
    }
    address_mask new_mask(common_mask_bits);
    return address_prefix(first.m_addr_prefix & new_mask, new_mask);
}
std::string Blockchain::calculate_address(
    const proto::Bip44Account& account,
    const BIP44Chain chain,
    const std::uint32_t index) const
{
    const auto& path = account.path();
    auto fingerprint = path.root();
    auto serialized = api_.Seeds().AccountChildKey(path, chain, index);

    if (false == bool(serialized)) {
        otErr << OT_METHOD << __FUNCTION__ << ": Unable to derive key."
              << std::endl;

        return {};
    }

    const auto key{opentxs::crypto::key::Asymmetric::Factory(*serialized)};
    const opentxs::crypto::key::Secp256k1* ecKey{
        dynamic_cast<const opentxs::crypto::key::Secp256k1*>(&key.get())};

    if (false == bool(key.get())) {
        otErr << OT_METHOD << __FUNCTION__ << ": Unable to instantiate key."
              << std::endl;

        return {};
    }

    if (nullptr == ecKey) {
        otErr << OT_METHOD << __FUNCTION__ << ": Incorrect key type."
              << std::endl;

        return {};
    }

    auto pubkey = Data::Factory();

    if (false == ecKey->GetPublicKey(pubkey)) {
        otErr << OT_METHOD << __FUNCTION__ << ": Unable to extract public key."
              << std::endl;

        return {};
    }

    if (COMPRESSED_PUBKEY_SIZE != pubkey->size()) {
        otErr << OT_METHOD << __FUNCTION__ << ": Incorrect pubkey size ("
              << pubkey->size() << ")." << std::endl;

        return {};
    }

    auto sha256 = Data::Factory();
    auto ripemd160 = Data::Factory();
    auto pubkeyHash = Data::Factory();

    if (!api_.Crypto().Hash().Digest(proto::HASHTYPE_SHA256, pubkey, sha256)) {
        otErr << OT_METHOD << __FUNCTION__ << ": Unable to calculate sha256."
              << std::endl;

        return {};
    }

    if (!api_.Crypto().Hash().Digest(
            proto::HASHTYPE_RIMEMD160, sha256, pubkeyHash)) {
        otErr << OT_METHOD << __FUNCTION__ << ": Unable to calculate rimemd160."
              << std::endl;

        return {};
    }

    const auto prefix = address_prefix(account.type());
    auto preimage = Data::Factory(&prefix, sizeof(prefix));

    OT_ASSERT(1 == preimage->size());

    preimage += pubkeyHash;

    OT_ASSERT(21 == preimage->size());

    return api_.Crypto().Encode().IdentifierEncode(preimage);
}