linux – How to upgrade Bitcoin Core from 0.18 to 0.20 on Ubuntu 18.04?

This is how I usually do it. Check the wget links in https://bitcoincore.org/bin

# Download Bitcoin Core packages for Ubuntu

wget https://bitcoincore.org/bin/bitcoin-core-0.20.0/bitcoin-0.20.0-x86_64-linux-gnu.tar.gz

# check the checksum and fingerprint //optional
wget https://bitcoincore.org/bin/bitcoin-core-0.20.0/SHA256SUMS.asc
wget https://bitcoin.org/laanwj-releases.asc
sha256sum --check SHA256SUMS.asc --ignore-missing
    >expected: xxx.tar.gz: OK
gpg --import ./laanwj-releases.asc
gpg --refresh-keys
gpg --verify SHA256SUMS.asc
    >expected: Good signature from "Wladimir J. van der Laan ..."

# extract, install and check versions of the binaries
tar -xvf bitcoin-0.20.0-x86_64-linux-gnu.tar.gz
sudo install -m 0755 -o root -t /usr/local/bin bitcoin-0.20.0/bin/*
bitcoind --version
    >expected: Bitcoin Core version x0.20.0

bitcoin core – Speed of decoding Bech32 addresses

I am trying to understand if Bech32 can be a bottleneck in some specific cases (only Bech32, not Bitcoin itself).
What is the hypothetical speed decoding the address back to the streamable format in the client?
How many transactions per second you can do in Bech32 when you have not in scope the Bitcoin client itself?

I found out that vanity Bech32 can be tested with this tool: https://github.com/lispczz/bech32-vanity-address-generator

Any advice, how I can do the raw estimation? Do you have some formula in mind?

bitcoin core – How to build a portable bitcoind binary for macOS?

Bitcoin Core ships a portable bitcoind with the Linux and Windows releases, but doesn’t ship one with macOS. And I couldn’t find instructions on how to build one.

Can someone provide step-by-step instructions on how to build a portable bitcoind binary for macOS?

The host platform can be Ubuntu or macOS. I have access to both.

(Just to clarify, the goal is to have a self-contained bitcoind binary that runs on different macOS machines without having to install additional dependencies)

API ASP.Web Core – Como alterar base de dados de acordo com a url solicitada

Até certo momento estavamos usando uma única base de dados para o sistema.

Mas conforme o andamento do projetos, foi necessário criar um ambiente de teste e um de produção.
Para isso, dupliquei o projeto da api na solução e separei em homologação (porta 8443) e produção (porta 443).

Porem, por conta da quantidade de setores e a necessidade de cada um validar os seus dados migrados, surgiu a necessidade de criar outros ambientes de homologação da aplicação e com bases diferente.

Mas para mim, parece que duplicar a api para cada é errado.
Dito isso, como alterar essa string em tempo de execução de acordo com a url? Considerando boas práticas.

Resumindo:
No momento tenho:
domain.com/api/Contratos/adicionacontrato

Meu resultado esperado é:
domain.com/producao/api/Contratos/adicionacontrato
domain.com/homologacao/api/Contratos/adicionacontrato

bitcoin core – Private Key has no fund

It sounds like the problem may be that the new wallet derived a different type of address from your private key.

Normal wallet function will present you with a new address each time you receive coins. Each of those addresses will have an associated private key, that needs to be used to spend the funds. Note that the same private key is not used to derive multiple addresses in a wallet, there is a 1:1 relationship for private keys and addresses.

So when you want to import that private key to a new wallet, you need to make sure the new wallet derives the correct address from it (ie, the same one your original wallet did, when you originally received the payment), otherwise the new wallet is showing a different address then it will not show your funds, since it is looking in the wrong place.

This question has a bit of info about different address types.

As a first step, compare the first characters of the address that holds the funds, and the address that the new wallet generated. If they are not the same (eg the original is 3... and the new wallet is bc1...), then you will need to either instruct the new wallet to generate the correct type of address, or if this is not possible, you will need to find a different wallet that is capable of doing so.

Note: if your bitcoin-core wallet is fully synced, you can run the command bitcoin-cli listunspent, to get a list of UTXOs that the wallet is keeping track of. You can look through the list to confirm the balance of specific addresses using this command, to ensure you are attempting to export the correct private key.

bitcoin core – What if two people want to spend same input at the same time

Lets say me and my friend both have access to same private key which can sign some new transaction. What would happen if me and my friend broadcast transaction with same input at the same time to a different nodes ?

Also what would happend if i broadcast it 1 minute after him and pay much larger fee and his transaction is still unconfirmed? Would miner take my transaction than because it includes higher fee or would the stick with his transction because he broadcasted it first.

Thanks

SHA-256 implementation in JS (core codes)

As told by experts, I am re-posting the code review request with the code.

Brief Description:

  1. from outside sha256() will be called with parameter having UTF-16 character set.

  2. then after prepareData() and initializing variables, the hash() will be called with converted binary message string (having pad and 64 bits message length appended) as parameter inside sha256(). The number of calls is ((total message length) / 512). Each hash function includes 64 internal rounds.

  3. With that the initialized hash value 8 * (32 bits) = 256 bits initialized hash value will be updated to final value in the last loop. After adding those up to a string, we are getting the final hash value of 256 bits.

I just want to get my code reviewed, and any suggestion or help will be worth to welcome.

The following is my script.js file.

var H = ();
var W = ();

function sha256 (input) {
    var output = "";
    input = prepareInputBits (input);
    var n = Math.floor (input.length / 512);
    prepareData();

    for (i = 0; i < n; i++) { // (n * 512 bits) chunk
        hash (input.substr (i * 512, 512));
    }

    for (i = 0; i < H.length; i++) {
        output += H(i);
    }

    output = convertBase2To16 (output);

    return output;
}

function hash (input) { // 512 bits in
    var i;
    let sigma0 = "";
    let sigma1 = "";

    /*
    ** 64 rounds = (16 + 48) rounds
    ** for first 16 rounds, 512 bits = 16 * 32 bits = 16 words
    ** for next 48 rounds, calculate round word, W(i)
    */

    for (i = 0; i < 64; i++) {
        if (i < 16) {
            W(i) = input.substr(32 * i, 32);
        } else {
            sigma0 = bitsXor (bitsXor (rotateRight (W(i-15), 7), rotateRight (W(i-15), 18)), shiftRight (W(i-15), 3));
            sigma1 = bitsXor (bitsXor (rotateRight (W(i-2), 17), rotateRight (W(i-2), 19)), shiftRight (W(i-2), 10));
            W(i) = bitsAdd (W(i-16), W(i-7));
            W(i) = bitsAdd (W(i), bitsAdd (sigma0, sigma1));
        }
    }

    let t0 = null;
    let t1 = null;

    for (var round = 0; round < 64; round++) {
        t0 = bitsAdd (H(7), bitsAdd (bitsAdd (Ep1(H(4)), Ch(H(4), H(5), H(6))), bitsAdd (_K(round), W(round))));
        t1 = bitsAdd (Ep0(H(0)), Maj(H(0), H(1), H(2)));

        H(7) = H(6);
        H(6) = H(5);
        H(5) = H(4);
        H(4) = bitsAdd (H(3), t0);
        H(3) = H(2);
        H(2) = H(1);
        H(1) = H(0);
        H(0) = bitsAdd (t0, t1);
    }
}

function prepareInputBits (input) {
    // binary-message + padding (1000...) + message-length (64 bits) => 0 (modulo 512)
    var output = "";
    var i, x;

    // converting character ASCII or UTF to hex-number (16 bits each) string
    for (i = 0; i < input.length; i++) {
        x = convertBase10To2 (input.charCodeAt(i));
        output += padLeftZeroes (x, (16 - x.length));
    }

    // getting 64 bit message length
    let msgLen = convertBase10To2 (output.length);
    msgLen = padLeftZeroes (msgLen, 64 - msgLen.length);

    x = output.length % 512; // getting extra bits length
    let nP = 0; // number of zeroes in pad

    if (x == 0) {
        // add new block
        nP = 512 - 65; // 65 = 64 + 1
    } else if (x > 447) {
        // add new block
        nP = (512 - x) + (512 - 65);
    } else {
        // use last block
        nP = 512 - x - 65;
    }

    output = output + "1" + padLeftZeroes ("", nP) + msgLen;
    console.log(output);

    return output;
}

function prepareData() {
    var i;

    // initialize hash value with base hash constants
    H = ();
    for (i = 0; i < 8; i++) {
        H.push(_H(i));
    }

    // initialize word with 64 empty string
    W = ();
    for (i = 0; i < 64; i++) {
        W.push("");
    }
}

// *** basic hash functions ***
function Ch (E, F, G) {
    return bitsXor (bitsAnd (E, F), bitsAnd (bitsNot (E), G));
}

function Maj (A, B, C) {
    return bitsXor (bitsXor (bitsAnd (A, B), bitsAnd (B, C)), bitsAnd (C, A));
}

function Ep0 (A) {
    return bitsXor (bitsXor (rotateRight(A, 2), rotateRight(A, 13)), rotateRight(A, 22));
}

function Ep1 (E) {
    return bitsXor (bitsXor (rotateRight(E, 6), rotateRight(E, 11)), rotateRight(E, 25));
}

// *** basic binary functions ***
function padLeftZeroes (input, numberOfZeroes) {
    var initialZeroes = "";

    for (var i = 0; i < numberOfZeroes; i++) {
        initialZeroes += "0";
    }

    return (initialZeroes + input);
}

function convertBase10To2 (input) {
    var output = "";

    while (input != 0) {
        output = (input % 2) + output;
        input = Math.floor(input / 2);
    }

    return output;
}

function convertBase2To10 (base2s) {
    var  base10n = 0;

    for (var i = 0; i < base2s.length; i++) {
        base10n = 2 * base10n + ((base2s(i) == "1") ? 1 : 0);
    }

    return base10n;
}

function convertBase2To16 (input) {
    let listNibbles = ("0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111");
    let listDigits = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
    let output = "";
    var x = (input.length % 4);

    if (x != 0) {
        input = padLeftZeroes(input, 4 - x);
    }

    for (var i = 0; i < input.length; i += 4) {
        for (var j = 0; j < 16; j++) {
            if (input.substr(i, 4) == listNibbles(j)) {
                break;
            }
        }

        output += listDigits(j);
    }

    return output;
}

function convertToNibbles (input) {
    var output = "";

    for (var i = 0; i < input.length; i += 4) {
        output += getNibble (input.substr(i, 4));
    }

    return output;
}

function getNibble (base2s) {
    var base16s = "";
    const list = ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F");

    base16s = list(convertBase2To10 (base2s));
    return base16s;
}

// *** basic bits functions ***
function shiftRight (input, numberOfBits) {
    var output = "";

    output = input.substring(0, numberOfBits);
    output = padLeftZeroes(output, input.length - numberOfBits);

    return output;
}

function rotateLeft (input, numberOfBits) {
    var output = "";
    output = input.substring(numberOfBits, input.length) + input.substring(0, numberOfBits);
    return output;
}

function rotateRight (input, numberOfBits) {
    var output = "";
    output = input.substring(input.length - numberOfBits, input.length) + input.substring(0, input.length - numberOfBits);
    return output;
}

// *** basic gate functions ***
function bitNot (x) {
    return (x == '0') ? '1' : '0';
}

function bitOr (x, y) {
    return (x == '1' || y == '1') ? '1' : '0';
}

function bitXor (x, y) {
    return (x == y) ? '0' : '1';
}

function bitAnd (x, y) {
    return (x == '0' || y == '0') ? '0' : '1';
}

// *** bunch gates functions ***
function bitsOr (a, b) {
    var c = "";

    if (a.length != b.length) {
        a = padLeftZeroes (a, b.length - a.length);
        b = padLeftZeroes (b, a.length - b.length);
    }

    for (var i = 0; i < a.length; i++) {
        c += bitOr (a(i), b(i));
    }

    return c;
}

function bitsAnd (a, b) {
    var c = "";

    if (a.length != b.length) {
        a = padLeftZeroes(a, b.length - a.length);
        b = padLeftZeroes(b, a.length - b.length);
    }

    for (var i = 0; i < a.length; i++) {
        c += bitAnd (a(i), b(i));
    }

    return c;
}

function bitsNot (a) {
    var b = "";

    for (var i = 0; i < a.length; i++) {
        b += bitNot (a(i));
    }

    return b;
}

function bitsXor (a, b) {
    var c = "";

    if (a.length != b.length) {
        a = padLeftZeroes(a, b.length - a.length);
        b = padLeftZeroes(b, a.length - b.length);
    }

    for (var i = 0; i < a.length; i++) {
        c += bitXor (a(i), b(i));
    }

    return c;
}

// basic arithmetic functions
function bitAdd (c_in, x, y) {
    let xor = bitXor (x, y);
    let c_out = bitOr (bitAnd (x, y), bitAnd (c_in, xor));
    let s = bitXor (c_in, xor);
    return (c_out + s);
}

function bitsAdd (a, b) {
    var i = 0;
    var s = "";
    var c = '0';
    let x = "";

    if (a.length != b.length) {
        a = padLeftZeroes (a, b.length - a.length);
        b = padLeftZeroes (b, a.length - b.length);
    }

    for (i = a.length - 1; i >= 0; i--) {
        x = bitAdd (c, a(i), b(i));
        c = x(0);
        s = x(1) + s;
    }

    s = c + s;

    return trimNumber (s, a.length);
}

function trimNumber (input, bitsLength) {
    let x = input.length - bitsLength;
    return input.substr (x, bitsLength);
}

And the following is my data.js file content

const _K = (
    "01000010100010100010111110011000",
    "01110001001101110100010010010001",
    "10110101110000001111101111001111",
    "11101001101101011101101110100101",
    "00111001010101101100001001011011",
    "01011001111100010001000111110001",
    "10010010001111111000001010100100",
    "10101011000111000101111011010101",
    "11011000000001111010101010011000",
    "00010010100000110101101100000001",
    "00100100001100011000010110111110",
    "01010101000011000111110111000011",
    "01110010101111100101110101110100",
    "10000000110111101011000111111110",
    "10011011110111000000011010100111",
    "11000001100110111111000101110100",
    "11100100100110110110100111000001",
    "11101111101111100100011110000110",
    "00001111110000011001110111000110",
    "00100100000011001010000111001100",
    "00101101111010010010110001101111",
    "01001010011101001000010010101010",
    "01011100101100001010100111011100",
    "01110110111110011000100011011010",
    "10011000001111100101000101010010",
    "10101000001100011100011001101101",
    "10110000000000110010011111001000",
    "10111111010110010111111111000111",
    "11000110111000000000101111110011",
    "11010101101001111001000101000111",
    "00000110110010100110001101010001",
    "00010100001010010010100101100111",
    "00100111101101110000101010000101",
    "00101110000110110010000100111000",
    "01001101001011000110110111111100",
    "01010011001110000000110100010011",
    "01100101000010100111001101010100",
    "01110110011010100000101010111011",
    "10000001110000101100100100101110",
    "10010010011100100010110010000101",
    "10100010101111111110100010100001",
    "10101000000110100110011001001011",
    "11000010010010111000101101110000",
    "11000111011011000101000110100011",
    "11010001100100101110100000011001",
    "11010110100110010000011000100100",
    "11110100000011100011010110000101",
    "00010000011010101010000001110000",
    "00011001101001001100000100010110",
    "00011110001101110110110000001000",
    "00100111010010000111011101001100",
    "00110100101100001011110010110101",
    "00111001000111000000110010110011",
    "01001110110110001010101001001010",
    "01011011100111001100101001001111",
    "01101000001011100110111111110011",
    "01110100100011111000001011101110",
    "01111000101001010110001101101111",
    "10000100110010000111100000010100",
    "10001100110001110000001000001000",
    "10010000101111101111111111111010",
    "10100100010100000110110011101011",
    "10111110111110011010001111110111",
    "11000110011100010111100011110010"
);

var _H = (
    "01101010000010011110011001100111",
    "10111011011001111010111010000101",
    "00111100011011101111001101110010",
    "10100101010011111111010100111010",
    "01010001000011100101001001111111",
    "10011011000001010110100010001100",
    "00011111100000111101100110101011",
    "01011011111000001100110100011001"
);

function abc() {
    var list = (
        "428a2f98", "71374491", "b5c0fbcf", "e9b5dba5", "3956c25b", "59f111f1", "923f82a4", "ab1c5ed5",
        "d807aa98", "12835b01", "243185be", "550c7dc3", "72be5d74", "80deb1fe", "9bdc06a7", "c19bf174",
        "e49b69c1", "efbe4786", "0fc19dc6", "240ca1cc", "2de92c6f", "4a7484aa", "5cb0a9dc", "76f988da",
        "983e5152", "a831c66d", "b00327c8", "bf597fc7", "c6e00bf3", "d5a79147", "06ca6351", "14292967",
        "27b70a85", "2e1b2138", "4d2c6dfc", "53380d13", "650a7354", "766a0abb", "81c2c92e", "92722c85",
        "a2bfe8a1", "a81a664b", "c24b8b70", "c76c51a3", "d192e819", "d6990624", "f40e3585", "106aa070",
        "19a4c116", "1e376c08", "2748774c", "34b0bcb5", "391c0cb3", "4ed8aa4a", "5b9cca4f", "682e6ff3",
        "748f82ee", "78a5636f", "84c87814", "8cc70208", "90befffa", "a4506ceb", "bef9a3f7", "c67178f2"
    );

    list = ("6a09e667", "bb67ae85", "3c6ef372", "a54ff53a", "510e527f", "9b05688c", "1f83d9ab", "5be0cd19");

    const hex = {
        "0" : "0000", "1" : "0001", "2" : "0010", "3" : "0011",
        "4" : "0100", "5" : "0101", "6" : "0110", "7" : "0111",
        "8" : "1000", "9" : "1001", "a" : "1010", "b" : "1011",
        "c" : "1100", "d" : "1101", "e" : "1110", "f" : "1111"
    };

    for (var i = 0; i < list.length; i++) {
        var str = list(i);
        var output = "";

        for (var j = 0; j < str.length; j++) {
            output += hex(str(j));
        }

        console.log(output);
    }
}

client – Bitcoin Core GUI gettransaction implementation

The cli users have the option to “gettransaction txid true” in order to find valuable information about a transaction that could be theirs. This is a very powerful api call that effectively eliminates the need of an electrum server if someone wants to check his tx sent to coldstorage or a mobile wallet.

Do you think there would be any consensus in adding such a feature to the Bitcoin Core GUI? Something like Help -> Verify external txid. This would greatly increase the use of Bitcoin core for the ease of validating a transaction.

c# – Multiple HttpClients in .NET Core Console Application

I’m building a .NET Core class library wrapper for a REST API that, ideally, could be used in both console applications and ASP.NET Core web applications. So far, I’ve based development on supporting dependency injection for the latter by creating a typed client for each group of REST API methods, i.e. one client for each group of (Index, Create, Destroy, etc.). It may be important to note that in this case, each group has same base address, and in most cases, the same authorization header would be used.

The typed clients inherit from a base client that handles some of the configuration:

public abstract class BaseClient
{
    protected readonly HttpClient _client;

    public BaseClient(IConfigService config, HttpClient client)
    {
        _client = client;
        _client.BaseAddress = new Uri(config.BaseAddress);

       // More configuration
    }
}

So I end up with something like this:

public class ClientA : BaseClient, IClientA
{
    public ClientA(IConfigService config, HttpClient client) : base(config, client) { }

    // Some methods
}

public class ClientB : BaseClient, IClientB
{
    public ClientB(IConfigService config, HttpClient client) : base(config, client) { }

    // More methods
}

And so on. With this I’ve written an IServiceCollection extension that registers all of these services:

public static class WrapperServiceCollectionExtensions
{
    public static IServiceCollection AddWrapper(this IServiceCollection services, string username, string key)
    {
        services.AddSingleton<IConfigService>(new ConfigService(username, key));
        services.AddHttpClient<IClientA, ClientA>();
        services.AddHttpClient<IClientB, ClientB>();

        // More clients

        return services;
    }
}

As I understand it, using this DI pattern, a new HttpClient is instantiated for each typed client, so I see no issue with a typed client being individually responsible for its own configuration. But let’s say I want to create these clients in a console application. Finally, I get to my question: knowing that the clients all have the same base address and all will most likely be using the same credentials for authorization, what would be the recommended way of instantiating them in a console application? I’m inclined to create a new HttpClient for each typed client:

class Program
{
    private static HttpClient _clientA = new HttpClient();
    private static HttpClient _clientB = new HttpClient();

    static void Main(string() args)
    {
        var config = new ConfigService("user", "key");
        var a = new ClientA(config, _clientA);
        var b = new ClientB(config, _clientB);
    }
}

But is this really necessary if the configurations would be the same for both anyways? Should I only worry about one HttpClient unless I’m dealing with multiple configurations? Should I even have multiple typed clients if the configuration would be the same for each? To me, it feels a little hacky to let each typed client successively overwrite a single HttpClient‘s configuration in its constructor, but in terms of behavior, unless different credentials were used, I don’t think it would matter. Seriously stuck here.