text:
Musig signature validation mismatch
I'm trying to understand the primitives of Taproot and Musig2 so I can implement them into my application. I'm using the rust-bitcoin library and have written a script to create a Taproot address from an aggregated Musig2 public key (i've funded it with sats on mutinynet), create a tx spending from it & sign it, verify the signature, and then spend the tx. However, I'm getting the error mandatory-script-verify-flag-failed (Invalid Schnorr signature) when I try to spend the tx. The odd thing is that the in-script sig validation throws no issues.
Here is the relevant code:
use bitcoin::hex::DisplayHex;

use bitcoin::consensus::Encodable;

use bitcoin::hashes::Hash;
use bitcoin::key::{Keypair, UntweakedPublicKey};
use bitcoin::locktime::absolute;

use bitcoin::secp256k1::{rand, Message, Secp256k1, SecretKey, Verification};
use bitcoin::sighash::{Prevouts, SighashCache, TapSighashType};
use bitcoin::{
    transaction, Address, Amount, Network, OutPoint, PublicKey, ScriptBuf, Sequence, Transaction,
    TxIn, TxOut, Txid, Witness, XOnlyPublicKey,
};
use musig2::secp::Point;
use musig2::{
    aggregate_partial_signatures, sign_partial, verify_single, AggNonce, BinaryEncoding,
    KeyAggContext, PubNonce, SecNonce,
};
use rand::thread_rng;

use std::str::FromStr;

const DUMMY_UTXO_AMOUNT: u64 = 100000;
const SPEND_AMOUNT: u64 = 90000;
const SK: &str = "e504905952697837ac0f0dc9e46deb0340ae6468b185ba79e4fa96ebda3964c2";
const SK2: &str = "6bb7bc5dd0c9db0ca8bdba4616ee92afceb432551e0f23b32ea7bcada18da696";
const SK3: &str = "57d44ecb8812680e871732233ed8e4d4e11a25f22aef6c81dbe35a424ad8db41";
const TXID: &str = "726499fb478422087e7a89a04f25de5ed98e87c9881e4a264e8f31143cdee17b";
const VOUT: u32 = 1;

fn main() {
    let keypair_array = vec![
        Keypair::from_secret_key(&Secp256k1::new(), &SecretKey::from_str(SK).unwrap()),
        Keypair::from_secret_key(&Secp256k1::new(), &SecretKey::from_str(SK2).unwrap()),
        Keypair::from_secret_key(&Secp256k1::new(), &SecretKey::from_str(SK3).unwrap()),
    ];

    let start = std::time::Instant::now();
    let tx = construct_refund_transaction(
        TXID,
        VOUT,
        DUMMY_UTXO_AMOUNT,
        SPEND_AMOUNT,
        "tb1p6e4q26tvyc7dmxfnk5zzhkux9d6pqpn0k5qxlw4gvc90unc0m3rq93a0tl",
        keypair_array,
    );
    let duration = start.elapsed();

    println!("Time taken to construct refund transaction: {:?}", duration);

    match tx {
        Ok(hex) => {
            post_tx(hex);
        }
        Err(e) => {
            println!("Error constructing transaction: {:?}", e);
        }
    }
}

pub fn construct_refund_transaction(
    from_txid: &str,
    from_vout: u32,
    from_amount: u64,
    spend_amount: u64,
    to_address: &str,
    keypair_array: Vec<Keypair>,
) -> Result<String, Box<dyn std::error::Error>> {
    // Step 1: Convert public keys to points for MuSig2
    let points_vec: Vec<Point> = keypair_array
        .iter()
        .map(|keypair| Point::from_hex(&keypair.public_key().to_string()).unwrap())
        .collect();

    // Step 2: Create a KeyAggContext for MuSig2
    let context = KeyAggContext::new(points_vec).unwrap();

    // Step 3: Get the aggregated public key
    let agg_pubkey: [u8; 33] = context.aggregated_pubkey();
    // println!("Aggregate pubkey: {:?}", hex::encode(agg_pubkey));

    // Step 4: Create a P2TR address from the aggregated public key
    let pubkey = PublicKey::from_slice(&agg_pubkey).unwrap();
    let xonly_pubkey = XOnlyPublicKey::from(pubkey);
    let secp = Secp256k1::new();
    // let address = Address::p2tr(&secp, xonly_pubkey, None, Network::Signet);
    // println!("P2TR address: {}", address);

    // Step 5: Get the unspent transaction output (UTXO)
    let (out_point, utxo) = unspent_transaction_output(
        &secp,
        xonly_pubkey,
        Txid::from_str(from_txid).unwrap(),
        from_vout,
        from_amount,
    );

    // Step 6: Get the receiver's address
    let address = receivers_address(to_address);

    // Step 7: Create the transaction input
    let input = TxIn {
        previous_output: out_point,
        script_sig: ScriptBuf::default(), // Empty for P2TR
        sequence: Sequence::ENABLE_RBF_NO_LOCKTIME,
        witness: Witness::default(), // Will be filled after signing
    };

    // Step 8: Create the transaction output
    let spend = TxOut {
        value: Amount::from_sat(spend_amount),
        script_pubkey: address.script_pubkey(),
    };

    // Step 9: Construct the unsigned transaction
    let mut unsigned_tx = Transaction {
        version: transaction::Version::TWO,
        lock_time: absolute::LockTime::ZERO,
        input: vec![input],
        output: vec![spend],
    };
    let input_index = 0;

    // Step 10: Prepare for signing
    let sighash_type = TapSighashType::Default;
    let prevouts = vec![utxo];
    let prevouts = Prevouts::All(&prevouts);

    // Step 11: Calculate the sighash
    let mut sighasher = SighashCache::new(&mut unsigned_tx);
    let sighash = sighasher
        .taproot_key_spend_signature_hash(input_index, &prevouts, sighash_type)
        .expect("failed to construct sighash");

    // Step 12: Prepare the message to be signed
    let msg = Message::from_digest(sighash.to_byte_array());

    // Step 13: Generate random nonces for MuSig2
    let mut rng = thread_rng();
    let n = keypair_array.len();
    let secret_nonces: Vec<SecNonce> = (0..n).map(|_| SecNonce::random(&mut rng)).collect();
    let public_nonces: Vec<PubNonce> = secret_nonces.iter().map(|sn| sn.public_nonce()).collect();

    // Step 14: Aggregate nonces
    let agg_nonce = AggNonce::sum(&public_nonces);

    // Step 15: Generate partial signatures
    let mut partial_sigs = Vec::new();
    for (i, keypair) in keypair_array.iter().enumerate() {
        let seckey =
            musig2::secp::Scalar::from_slice(&keypair.secret_key().secret_bytes()).unwrap();
        let partial_sig: musig2::PartialSignature = sign_partial(
            &context,
            seckey,
            secret_nonces[i].clone(),
            &agg_nonce,
            msg.as_ref(),
        )
        .unwrap();
        partial_sigs.push(partial_sig);
        // println!("Partial signature {}: {:?}", i, partial_sig);
    }

    // Step 16: Aggregate partial signatures
    let aggregated_signature: musig2::CompactSignature =
        aggregate_partial_signatures(&context, &agg_nonce, partial_sigs, msg.as_ref()).unwrap();
    // println!("Aggregated signature: {:?}", aggregated_signature);

    // Step 17: Verify the aggregated signature
    let verification_result = verify_single(
        Point::from_slice(&agg_pubkey).unwrap(),
        aggregated_signature,
        msg.as_ref(),
    );

    match verification_result {
        Ok(()) => println!("Signature is valid"),
        Err(e) => println!("Signature verification failed: {:?}", e),
    }

    // Step 18: Add the signature to the transaction witness
    sighasher
        .witness_mut(input_index)
        .unwrap()
        .push(&aggregated_signature.to_bytes());

    // Step 19: Finalize the signed transaction
    let tx = sighasher.into_transaction();

    // Step 20: Serialize and print the signed transaction
    let mut serialized = Vec::new();
    tx.consensus_encode(&mut serialized).unwrap();
    let hex = serialized.as_hex();
    // println!("Transaction hex: {}", hex);

    Ok(hex.to_string())
}

// Helper function to parse and validate the receiver's address
fn receivers_address(address: &str) -> Address {
    address
        .parse::<Address<_>>()
        .expect("a valid address")
        .require_network(Network::Signet)
        .expect("valid address for signet")
}

// Helper function to create an unspent transaction output (UTXO)
fn unspent_transaction_output<C: Verification>(
    secp: &Secp256k1<C>,
    internal_key: UntweakedPublicKey,
    txid: Txid,
    vout: u32,
    amount: u64,
) -> (OutPoint, TxOut) {
    let script_pubkey = ScriptBuf::new_p2tr(secp, internal_key, None);
    let out_point = OutPoint { txid, vout };
    let utxo = TxOut {
        value: Amount::from_sat(amount),
        script_pubkey,
    };
    (out_point, utxo)
}

fn post_tx(hex: String) {
    let client = reqwest::blocking::Client::new();
    let res = client.post("https://mutinynet.com/api/tx").body(hex).send();

    match res {
        Ok(res) => {
            if res.status().is_success() {
                println!("Response: {:?}", res.text());
            } else {
                let error_text = res.text().unwrap_or_default();
                if let Some(message) = error_text.split("message\":\"").nth(1) {
                    if let Some(error_message) = message.split("\"").next() {
                        println!("Error: {}", error_message);
                    } else {
                        println!("Error: {}", error_text);
                    }
                } else {
                    println!("Error: {}", error_text);
                }
            }
        }
        Err(e) => {
            println!("Error sending request: {:?}", e);
        }
    }
}

Am I doing anything blatantly wrong?
(these are dummy SKs I generated for the purpose of this test)

You are creating a taproot address where the musig2 aggregate public key is the internal key. This means that the actual public key that appears in a transaction is not the aggregate pubkey - it's the aggregate pubkey plus a tweak. However, the signature you are creating only corresponds to the aggregate pubkey. Since it does not include the tweak, the signature is invalid for the taproot output pubkey.
Applying tweaks is specified in BIP 327, so your musig2 library should have functions for passing in the tweak. Computing the tweak is described in BIP 341, but rust-bitcoin should also have functionality for computing th tweak.


text:
Bitcoin Core 28 Tests (testmempoolaccept rejected but submitpackage accepted)
At the end of the third test (Package RBF) in the Test Guide, the testmempoolaccept command  return one of the transactions with the status: "allowed": false, "reject-reason": "bip125-replacement-disallowed".
But right after, the submitpackage command successfully replaces the old transaction despite the reject status.
This is not clear to me. Can someone explain better what is happening here ? If the transaction is considered "not allowed" in testmempoolaccept, why was it successfully submitted ?

In this scenario, the transaction is being conflicted by another transaction which is insufficient to replace it by itself, but enough to replace it when submitted with the child.
testmempoolaccept tests each transaction individually, even though multiple are provided at the same time. Thus the parent and its child are not evaluated together as a single package, and because neither will be accepted individually, a failure is returned.
However, submitpackage is explicitly an RPC to evaluate transactions submitted together as a package. Thus it does evaluate the parent and its child as a package, and because the package is enough to replace the original transaction, both txs are accepted successfully.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Avalon nano 3 Pool config
Can I enter different pools for each separate pool spot(ex. Pool1, Pool2, Pool3)in the config?

You should provide a bit more context to your question. What do you want to accomplish exactly? What did you already check before asking here?

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
How does AttachChain function works in the Bitcoin Core?
Here in the function AttachChain there is block of code:
    // Unless allowed, ensure wallet files are not reused across chains:
    if (!gArgs.GetBoolArg("-walletcrosschain", DEFAULT_WALLETCROSSCHAIN)) {
        WalletBatch batch(walletInstance->GetDatabase());
        CBlockLocator locator;
        if (batch.ReadBestBlock(locator) && locator.vHave.size() > 0 && chain.getHeight()) {
            // Wallet is assumed to be from another chain, if genesis block in the active
            // chain differs from the genesis block known to the wallet.
            if (chain.getBlockHash(0) != locator.vHave.back()) {
                error = Untranslated("Wallet files should not be reused across chains. Restart bitcoind with -walletcrosschain to override.");
                return false;
            }
        }
    }

I've seen the CBlockLocator contructor and with no argument, it does nothing so the vHave member of locator is always empty. So next if statement will never execute because:
batch.ReadBestBlock(locator) && locator.vHave.size() > 0 && chain.getHeight()

Is alway false. I think I'm missing something here, because if I'm correct the if statement is like if(0) and so it's not useful.

ReadBestBlock doesn't look at the locator it is given, rather it reads a specific record from the wallet database and loads the data into the provided locator. locator is used as an output parameter.
ReadBestBlock returns true when it successfully finds a record and reads it, and it returns false if there is an error. So this code checks that the reading of the best block record was successful and that the read locator has data.


text:
What does bitcoin maximalist mean?
I've heard much about bitcoin maximalism. As I've googled it, a bitcoin maximalist is a person who believe that the only real cryptocurrency would really be needed in the future is the bitcoin. Is this correct? Can someone explain it in simple language to me and also the root causes of this belief? Why would some people believe that bitcoin is the only cryptocurrency ever man would need?
Thanks in advance.

I think your question might be opinion-based and therefore off-topic on this site, but I'll still try to give a helpful answer.
Bitcoin maximalists believe that bitcoin is the only cryptocurrency worth holding, studying and/or building upon. That belief comes from any of these and/or related claims (with varying degrees of verifiability):

Bitcoin is the only cryptocurrency that is truly decentralized. (Its creator is unknown and has not been involved with the project for many years, and there is no central authority saying what the protocol changes should be.)
Bitcoin is the only cryptocurrency that is distributed fairly. (There was no pre-sale for insiders, no pre-mine, everyone had the opportunity to mine right from the start.)
Any claimed improvements brought by other cryptocurrencies can be implemented in bitcoin as well if they are shown to be useful.
Bitcoin has the most proof of work going into it, making it the "most secure" chain.

It is generally a catch-all trope used by people (such as Vitalik mentioned in the answer above) use to insult supporters of Bitcoin in attempt to get them to buy into a coin for which they have much larger supply of than everyone else (Ethereum in that case). You don't have to be "Bitcoin only" to be considered a maximalist, in some sense it can be seen as an economic attack on rational people to make them feel guilty. Ultimately there is no more transparent and widely looked at asset than Bitcoin making all other cryptocurrencies a scam by comparison even if they aren't a scam per-say in their mechanics.


text:
How can a collision attack reveal the private key?
From "Mastering Bitcoin: Programming the Open Blockchain 3d edition, Ch4" :

All addresses based on hash functions are theoretically vulnerable to an attacker independently finding the same input that produced the hash function output (com‐ mitment). In the case of Bitcoin, if they find the input the same way the original user did, they’ll know the user’s private key and be able to spend that user’s bitcoins.

Bitcoin uses elliptic curve arithmetics for private and public keys, the only thing which is hashed is a public key, so the best thing we can reveal is a public key, isn't it?
(I'm not considering P2SH)
Or we can somehow get a private key with successful collision attack?

If the attacker just tries random public keys and guesses the correct one, they obviously won't be able to spend the funds. What they can do is try random private keys and derive the public keys from those, then if they're successful they'll have the private key as well. In any case, Bitcoin keys and addresses are large enough that brute-forcing them should be infeasible.
Side note, what's being descibed here is called a preimage attack, which is not the same as a collision attack.


text:
Where are transaction signatures beside the scriptSig?
To spend a UTXO, we need to sign it (have the scriptSig). Then we can spend that UTXO to any address we want, which it wasn't included in the signature we produced for unlocking the UTXO. So we should provide another signature to express our intention that we want to spend to this specific output[s]. Is this right?
When I try to observe a transaction using bitcoin-cli I don't see any signature for the whole transaction.
# bitcoin-cli -regtest  gettransaction 58abd7cda78c3140383bbf950420171b6e630f784d33392b968d9db7ea7d6c25
{
  "amount": 0.00000000,
  "fee": -0.00002820,
  "confirmations": 0,
  "trusted": true,
  "txid": "58abd7cda78c3140383bbf950420171b6e630f784d33392b968d9db7ea7d6c25",
  "wtxid": "40ef85dd2f2f54254f13c179b8fa18a247d493fd3f583ce4c0932754dfad89ed",
  "walletconflicts": [
  ],
  "time": 1683793800,
  "timereceived": 1683793800,
  "bip125-replaceable": "yes",
  "details": [
    {
      "address": "bcrt1qt3lltc5dx4gwmlcd0uqxkl85xrv7msfkmjyjts",
      "category": "send",
      "amount": -12.34500000,
      "label": "",
      "vout": 1,
      "fee": -0.00002820,
      "abandoned": false
    },
    {
      "address": "bcrt1qt3lltc5dx4gwmlcd0uqxkl85xrv7msfkmjyjts",
      "parent_descs": [
        "wpkh(tpubD6NzVbkrYhZ4YcCHtvXU4pzZAcAH2eet5KJvzXoxvjGGdBzAepGK3keAQS8pv1pQYyM4VdudgnmaDr4YXXemgdtKh4Yh5cbG3uCHV8q7Aub/84'/1'/0'/0/*)#h8mhq3zh"
      ],
      "category": "receive",
      "amount": 12.34500000,
      "label": "",
      "vout": 1
    }
  ],
  "hex": "020000000001016c34e216d1f6821d91bc42e377290a7d30968da52c88678ecc2b47757ee8333d0000000000fdffffff025ced70e000000000160014bde66028298d70a6ec1bbb8e9c0a87f40db4c8d9a0f99449000000001600145c7ff5e28d3550edff0d7f006b7cf430d9edc136024730440220045193a2e68e19f815741f1b6338fc8c52d6808b5b63e387f1ef411e509bf78002207ab592b6d5bd9b47a6c0b4cdad119b05a43cb8274ecb5bffd16de881ecaa005d0121024bad563526f76fdbb915e7af18aed4ff8c48cf853440c2fda07076078d1c1346cb000000"
}

# bitcoin-cli -regtest getblock 757783d237294945126b5966a46ddaf44e3ce04b0cd5bba726dc441dbadbb5be 2
{
  "hash": "757783d237294945126b5966a46ddaf44e3ce04b0cd5bba726dc441dbadbb5be",
  "confirmations": 1,
  "height": 204,
  "version": 805306368,
  "versionHex": "30000000",
  "merkleroot": "b2de6af12b36d32bad5f358cabab6d5dee5d976568a5039f5fd7273ee0905afa",
  "time": 1683795140,
  "mediantime": 1683793734,
  "nonce": 0,
  "bits": "207fffff",
  "difficulty": 4.656542373906925e-10,
  "chainwork": "000000000000000000000000000000000000000000000000000000000000019a",
  "nTx": 2,
  "previousblockhash": "2b6ce151ace43623880979d4b137e14865e07d59195b242fa273b13dd6b59c13",
  "strippedsize": 327,
  "size": 472,
  "weight": 1453,
  "tx": [
    {
      "txid": "860c1c07d52b2709e717780f1c91845ca338199da9eead89069ff458dc59e509",
      "hash": "957b22a4ce7df3e0b05bdf216f9ca14bd8f1bcae3ebc68870ef92035af941fe4",
      "version": 2,
      "size": 169,
      "vsize": 142,
      "weight": 568,
      "locktime": 0,
      "vin": [
        {
          "coinbase": "02cc0000",
          "txinwitness": [
            "0000000000000000000000000000000000000000000000000000000000000000"
          ],
          "sequence": 4294967295
        }
      ],
      "vout": [
        {
          "value": 25.00002820,
          "n": 0,
          "scriptPubKey": {
            "asm": "0 798fcf4772e285431c55ce67f2e0333f11d03f8b",
            "desc": "addr(bcrt1q0x8u73mju2z5x8z4eenl9cpn8ugaq0utj7n0jd)#nxvln3g4",
            "hex": "0014798fcf4772e285431c55ce67f2e0333f11d03f8b",
            "address": "bcrt1q0x8u73mju2z5x8z4eenl9cpn8ugaq0utj7n0jd",
            "type": "witness_v0_keyhash"
          }
        },
        {
          "value": 0.00000000,
          "n": 1,

      "weight": 561,
      "locktime": 203,
      "vin": [
        {
          "txid": "3d33e87e75472bcc8e67882ca58d96307d0a2977e342bc911d82f6d116e2346c",
          "vout": 0,
          "scriptSig": {
            "asm": "",
            "hex": ""
          },
          "txinwitness": [
            "30440220045193a2e68e19f815741f1b6338fc8c52d6808b5b63e387f1ef411e509bf78002207ab592b6d5bd9b47a6c0b4cdad119b05a43cb8274ecb5bffd16de881ecaa005d01",
            "024bad563526f76fdbb915e7af18aed4ff8c48cf853440c2fda07076078d1c1346"
          ],
          "sequence": 4294967293
        }
      ],
      "vout": [
        {
          "value": 37.65497180,
          "n": 0,
          "scriptPubKey": {
            "asm": "0 bde66028298d70a6ec1bbb8e9c0a87f40db4c8d9",
            "desc": "addr(bcrt1qhhnxq2pf34c2dmqmhw8fcz587sxmfjxef2k5ag)#x0qwx2ck",
            "hex": "0014bde66028298d70a6ec1bbb8e9c0a87f40db4c8d9",
            "address": "bcrt1qhhnxq2pf34c2dmqmhw8fcz587sxmfjxef2k5ag",
            "type": "witness_v0_keyhash"
          }
        },
        {
          "value": 12.34500000,
          "n": 1,
          "scriptPubKey": {
            "asm": "0 5c7ff5e28d3550edff0d7f006b7cf430d9edc136",
            "desc": "addr(bcrt1qt3lltc5dx4gwmlcd0uqxkl85xrv7msfkmjyjts)#f706enkn",
            "hex": "00145c7ff5e28d3550edff0d7f006b7cf430d9edc136",
            "address": "bcrt1qt3lltc5dx4gwmlcd0uqxkl85xrv7msfkmjyjts",
            "type": "witness_v0_keyhash"
          }
        }
      ],
      "fee": 0.00002820,
      "hex": "020000000001016c34e216d1f6821d91bc42e377290a7d30968da52c88678ecc2b47757ee8333d0000000000fdffffff025ced70e000000000160014bde66028298d70a6ec1bbb8e9c0a87f40db4c8d9a0f99449000000001600145c7ff5e28d3550edff0d7f006b7cf430d9edc136024730440220045193a2e68e19f815741f1b6338fc8c52d6808b5b63e387f1ef411e509bf78002207ab592b6d5bd9b47a6c0b4cdad119b05a43cb8274ecb5bffd16de881ecaa005d0121024bad563526f76fdbb915e7af18aed4ff8c48cf853440c2fda07076078d1c1346cb000000"
    }
  ]
}

Modern transaction, since SegWit, include signatures in a new field: the witness. The witness replaces the scriptSig. You can see in your example how txinwitness contains a public key and a signature for the single input of your transaction.
Related: "What is the Witness and what data does it contain?".

What about legacy transactions?

@AmirrezaRiahi In pre-segwit transaction inputs, the signature data is in the scriptSig. In segwit transaction inputs, the signature data is in the witness.

@PieterWuille Thanks for clarification

The scriptSig is a per input entity, right? not for a whole transaction. My question is about the signature of the whole transaction.

There is no such thing as a signature for the whole transaction. Signatutes are always per input.

@PieterWuille So how the input is protected against being used to another output? One can put a signed input and create another transaction and use that input in it.

@AmirrezaRiahi Every signature (typically) signs all inputs (including itself) and all outputs. It just doesn't sign the signatures in those inputs.


text:
SegWit Soft Fork
my question is in relation to SegWit backwards compatibility.
Based on the way SegWit script is constructed, just 0 and a public key, makes it spendable by anyone. The only thing that stops it are miners and nodes that reject such transactions.
So the question is, how is it backwards compatible and not a hard fork if nodes from before SegWit can’t spend it?
Thanks!

You might want to read: What is a soft fork? What is a hard fork? What are their differences?

This might also be interesting: https://bitcoin.stackexchange.com/q/52152/5406

Backwards compatibility of Bitcoin forks depends solely on whether unupgraded nodes reject blocks that are valid under the new rules. If they do, it's a hard fork, if not, it's a soft fork.
SegWit is a soft fork because SegWit outputs are spendable by anyone under pre-SegWit rules, which means there cannot be a transaction that's accepted by SegWit nodes but rejected by pre-SegWit nodes.


text:
send btc from P2SH(multisig and timelock script),got "Non-canonical DER signature"
I created a 2/3 multisig script with timelock,the admin can withdraw BTC after timelock.
But the bitcoin node return an error:code:-26,message:mandatory-script-verify-flag-failed (Non-canonical DER signature).
func createMultisigLocktimeRedeemScript(pk1, pk2, pk3, pkAdmin []byte, locktime uint32) ([]byte, error) {
builder := txscript.NewScriptBuilder()

builder.AddOp(txscript.OP_IF)
// multisig
{
    // add the minimum number of needed signatures
    builder.AddOp(txscript.OP_2)
    builder.AddData(pk1)
    builder.AddData(pk2)
    builder.AddData(pk3)
    // add the total number of public keys in the multi-sig screipt
    builder.AddOp(txscript.OP_3)
    // add the check-multi-sig op-code
    builder.AddOp(txscript.OP_CHECKMULTISIG)
}

builder.AddOp(txscript.OP_ELSE)
// locktime
{
    var bz = make([]byte, 4)
    binary.LittleEndian.PutUint32(bz, locktime) //
    builder.AddData(bz)
    builder.AddOp(txscript.OP_CHECKLOCKTIMEVERIFY)
    builder.AddOp(txscript.OP_DROP)
}
builder.AddOp(txscript.OP_ENDIF)

// admin
{
    builder.AddData(pkAdmin)
    builder.AddOp(txscript.OP_CHECKSIG)
}

// redeem script is the script program in the format of []byte
redeemScript, err := builder.Script()
if err != nil {
    return nil, err
}
redeemStr, err := txscript.DisasmString(redeemScript)
if err != nil {
    return nil, err
}
fmt.Println("script:", redeemStr)

{
    redeemHash := btcutil.Hash160(redeemScript)
    scriptAddr, err := btcutil.NewAddressScriptHashFromHash(redeemHash, &chaincfg.TestNet3Params) //P2SH
    if err != nil {
        return nil, err
    }
    fmt.Printf("network %s script address: %s\n", "testnet3", scriptAddr.EncodeAddress())
}
return redeemScript, nil

}
func multisigLockTimeTx(sk1, sk2, sk3, skAdmin string, locktime uint32) error {
wif1, err := btcutil.DecodeWIF(sk1)
if err != nil {
    return err
}
pk1 := wif1.PrivKey.PubKey().SerializeCompressed()

wif2, err := btcutil.DecodeWIF(sk2)
if err != nil {
    return err
}
pk2 := wif2.PrivKey.PubKey().SerializeCompressed()

wif3, err := btcutil.DecodeWIF(sk3)
if err != nil {
    return err
}
pk3 := wif3.PrivKey.PubKey().SerializeCompressed()

wifAdmin, err := btcutil.DecodeWIF(skAdmin)
if err != nil {
    return err
}
pkAdmin := wifAdmin.PrivKey.PubKey().SerializeCompressed()

redeemScript, err := createMultisigLocktimeRedeemScript(pk1, pk2, pk3, pkAdmin, locktime)
if err != nil {
    return err
}

// build tx
redeemTx := wire.NewMsgTx(wire.TxVersion)

// you should provide your UTXO hash
utxoHash, err := chainhash.NewHashFromStr("deabddd6f7ebed78fe91b71a34ec7167360a49016be039fd2b053ac02388e449")
if err != nil {
    return nil
}
// and add the index of the UTXO
outPoint := wire.NewOutPoint(utxoHash, 0)
txIn := wire.NewTxIn(outPoint, nil, nil)

redeemTx.AddTxIn(txIn)

// adding the output to tx
decodedAddr, err := btcutil.DecodeAddress("tb1ph8jzyv68rwx436wtnr760tsg3ut07ml8zueuqcwww04fdmrp8ntqaqjmsp", &chaincfg.TestNet3Params)
if err != nil {
    return err
}
destinationAddrByte, err := txscript.PayToAddrScript(decodedAddr)
if err != nil {
    return err
}
// adding the destination address and the amount to the transaction
redeemTxOut := wire.NewTxOut(5000, destinationAddrByte)
redeemTx.AddTxOut(redeemTxOut)

sig1, err := txscript.RawTxInSignature(redeemTx, 0, redeemScript, txscript.SigHashAll, wif1.PrivKey)
if err != nil {
    return err
}
_ = sig1
sig2, err := txscript.RawTxInSignature(redeemTx, 0, redeemScript, txscript.SigHashAll, wif2.PrivKey)
if err != nil {
    return err
}
_ = sig2

sig3, err := txscript.RawTxInSignature(redeemTx, 0, redeemScript, txscript.SigHashAll, wif3.PrivKey)
if err != nil {
    fmt.Println("got error in constructing sig3")
    return err
}
_ = sig3

sigAdmin, err := txscript.RawTxInSignature(redeemTx, 0, redeemScript, txscript.SigHashAll, wifAdmin.PrivKey)
if err != nil {
    fmt.Println("got error in constructing sigAdmin")
    return err
}
_ = sigAdmin

fmt.Println("sig1:", hex.EncodeToString(sig1))
fmt.Println("sig2:", hex.EncodeToString(sig2))
fmt.Println("sig3:", hex.EncodeToString(sig3))
fmt.Println("sigAdmin:", hex.EncodeToString(sigAdmin))

if !isValidSignatur(sig1) {
    fmt.Println("signature invalid")
}
if !isValidSignatur(sig2) {
    fmt.Println("signature invalid")
}
if !isValidSignatur(sig3) {
    fmt.Println("signature invalid")
}
if !isValidSignatur(sigAdmin) {
    fmt.Println("signature invalid")
}

signature := txscript.NewScriptBuilder()
// multisig
{
    signature.AddOp(txscript.OP_0)
    signature.AddData(sig2)
    signature.AddData(sig3)
    signature.AddOp(txscript.OP_TRUE)
    signature.AddData(redeemScript)
}
{ // admin
    //signature.AddData(sigAdmin)
    //signature.AddOp(txscript.OP_FALSE)
    //signature.AddData(redeemScript)
}
signatureScript, err := signature.Script()
if err != nil {
    // Handle the error.
    return err
}

signatureScriptStr, err := txscript.DisasmString(signatureScript)
if err != nil {
    return err
}
fmt.Println("signatureScript:", signatureScriptStr)

redeemTx.TxIn[0].SignatureScript = signatureScript
var signedTx bytes.Buffer
if err := redeemTx.Serialize(&signedTx); err != nil {
    return err
}
fmt.Println("TxHash:", redeemTx.TxHash().String())

hexSignedTx := hex.EncodeToString(signedTx.Bytes())
fmt.Println("signedTx:", hexSignedTx)

var multi_expporer_api = []string{"https://blockstream.info/testnet/api/"}
cli := bitcoinlib.NewSmartClient(multi_expporer_api)
txid, err := cli.PostTransaction(context.Background(), hexSignedTx)
if err != nil {
    return err
}
fmt.Println("txid:", txid)
return nil

}
script:
OP_IF
  2
  03f5d066de8a9d8476f8eab2f507f2858ef0914ccf96bf3752f3f4652553c52b6d
  023fe85a4a866ef5f4af2d1904e1ac3bec518542b13837ae1159d707650796bbe5
  022205cdcd869d9dbec279dadceeef7777e39d1915e2f36ec0f6e3fa50bb024c5c
  3
  OP_CHECKMULTISIG
OP_ELSE
  900c1a67
  OP_CHECKLOCKTIMEVERIFY
  OP_DROP
OP_ENDIF
035d911aded72d77f12e5d200d37f968438c6c7d532b2dbf50a80516ab1014e52b
OP_CHECKSIG

network testnet3 script address: 2MsWVE37DGR7adHWiZpUh7va71qkX26Vbp8
sig1: 3044022017a98dfea76746e9b7f0f785c7d92625289b0b0b5b95b47072511c24f5f3769302201033ff85eec8ce951100c3f6459a439bdb13e24acd7d59609bc2b76a7b24503c01
sig2: 3045022100fc71b478e03ce44c8148bfd19a69175ce744d15f822851ca18d4c95cca08dcec02202dd451b493e8ffe64fb672a9740b49af95cb731a60fc386612983304f656681901
sig3: 3045022100f815e290b3c83160f49b56b9c18b0834f25f1752883ae83399cdfc34646a0cdb022051a687e58f88ebac3dd0430be22d9b0e1270bcd25e19732baf612ecd113da86801
sigAdmin: 3045022100a85f88f394cabcf2659fa62f98ca56b26be5f7c4f9645c2922f6e52d01ef527d02207075c8af70d358f04b6fb1dfc0c19faaa274577ccc68f411370fbbae60aee79101
signatureScript: 0 3045022100fc71b478e03ce44c8148bfd19a69175ce744d15f822851ca18d4c95cca08dcec02202dd451b493e8ffe64fb672a9740b49af95cb731a60fc386612983304f656681901 3045022100f815e290b3c83160f49b56b9c18b0834f25f1752883ae83399cdfc34646a0cdb022051a687e58f88ebac3dd0430be22d9b0e1270bcd25e19732baf612ecd113da86801 1 63522103f5d066de8a9d8476f8eab2f507f2858ef0914ccf96bf3752f3f4652553c52b6d21023fe85a4a866ef5f4af2d1904e1ac3bec518542b13837ae1159d707650796bbe521022205cdcd869d9dbec279dadceeef7777e39d1915e2f36ec0f6e3fa50bb024c5c53ae6704900c1a67b1756821035d911aded72d77f12e5d200d37f968438c6c7d532b2dbf50a80516ab1014e52bac
TxHash: 03386f8a777ae44b2ee6ab4d494b46a55655fa7825c04dd9b7cf993086976669
signedTx: 010000000149e48823c03a052bfd39e06b01490a366771ec341ab791fe78edebf7d6ddabde00000000fd2c0100483045022100fc71b478e03ce44c8148bfd19a69175ce744d15f822851ca18d4c95cca08dcec02202dd451b493e8ffe64fb672a9740b49af95cb731a60fc386612983304f656681901483045022100f815e290b3c83160f49b56b9c18b0834f25f1752883ae83399cdfc34646a0cdb022051a687e58f88ebac3dd0430be22d9b0e1270bcd25e19732baf612ecd113da86801514c9663522103f5d066de8a9d8476f8eab2f507f2858ef0914ccf96bf3752f3f4652553c52b6d21023fe85a4a866ef5f4af2d1904e1ac3bec518542b13837ae1159d707650796bbe521022205cdcd869d9dbec279dadceeef7777e39d1915e2f36ec0f6e3fa50bb024c5c53ae6704900c1a67b1756821035d911aded72d77f12e5d200d37f968438c6c7d532b2dbf50a80516ab1014e52bacffffffff018813000000000000225120b9e42233471b8d58e9cb98fda7ae088f16ff6fe71733c061ce73ea96ec613cd600000000

Your script has a fatal flaw: it uses OP_CHECKMULTISIG instead of OP_CHECKMULTISIGVERIFY, which causes the output of that opcode (in this case 01) to be interpreted as a signature by the last OP_CHECKSIG. This renders the multisig branch of your input completely unusable, though the locktime branch will still work.
As a reminder, for a script to pass it needs to execute without errors and leave a single true value on the stack (technically any value that evaluates to true with CastToBool, and technically the requirement that there's only one value is only a policy rule for pre-taproot inputs). It's for this reason that the last opcode in your script is OP_CHECKSIG and not OP_CHECKSIGVERIFY so that its output can serve as this value, but the outputs of previous checking opcodes need to be verified some other way, either as part of the opcode itself (these opcodes end with -VERIFY) or explicitly using OP_VERIFY.
There are a few other issues:

The semantics of your script are different than you describe. It's not (2-of-3 multisig OR (timelock + admin)) but ((2-of-3 multisig OR timelock) + admin), assuming the last key is the admin, i.e. the admin is always required to sign. You probably want to move the last OP_CHECKSIG into the locktime branch, then using OP_CHECKMULTISIG in the multisig branch would be correct.
Your signed transaction only includes the two signatures for the multisig and not the admin signature. This is probably due to the aforementioned misunderstanding of the script's semantics.

Redeem Script:
OP_IF OP_2 <PK1> <PK2> <PK3> OP_3 OP_CHECKMULTISIG OP_ELSE <LOCKTIME> OP_CHECKLOCKTIMEVERIFY OP_DROP <AdminPK> OP_CHECKSIG OP_ENDIF
unlocking script: case 1:0 SIG1 SIG2 TRUE case 2:SIG_ADMIN FALSE
Is it right?

Yes, that looks about right.


text:
How "addDummySigs" in golang when send satoshi from p2tr multisig script?
I have a 2-of-3 multisig taproot script,create like bitcoinjs-lib:https://github.com/bitcoinjs/bitcoinjs-lib/blob/8d9775c20da03ab40ccbb1971251e71d117bcd8b/test/integration/taproot.spec.ts#L531-L593:
builder := txscript.NewScriptBuilder()
for i, pk := range leafPubkeys {
    if i == 0 {
        builder.AddData(pk)
        builder.AddOp(byte(txscript.OP_CHECKSIG))
    } else {
        builder.AddData(pk)
        builder.AddOp(byte(txscript.OP_CHECKSIGADD))
    }
}
builder.AddOp(byte(txscript.OP_1 - 1 + 2))
builder.AddOp(byte(txscript.OP_GREATERTHANOREQUAL))

then create a tx(send satoshi from the script),and two keys sign it.but got "invalid schnorr signatures" when sent to bitcoind.
my golang code:
func TestGenTapscript(t *testing.T) {
    signpks := []string{
...
    }
    pks := []string{...}
    tapscript := NewMultisigTaprootScript(pks, 2, 3, &chaincfg.TestNet3Params)

    // build tx
    const utxoHash = "..."
    const utxoVout = 0
    const utxoAmount = 1000000
    const sendAmount = utxoAmount - 1000

    var (
        inputs     []*wire.OutPoint
        nSequences []uint32
        outputs    []*wire.TxOut
    )
    { // output
        ...
        outputs = append(outputs, redeemTxOut)
    }
    { // input
        ...
    }

    // Build PSBT
    packet, err := psbt.New(inputs, outputs, 2, 0, nSequences)
    if err != nil {
        t.Fatal(err)
    }
    packet.Inputs[0].TaprootLeafScript = []*psbt.TaprootTapLeafScript{
        &psbt.TaprootTapLeafScript{
            ControlBlock: tapscript.controlBlock,
            Script:       tapscript.leafScript,
            LeafVersion:  0xc0,
        },
    }

    // update
    updater, err := psbt.NewUpdater(packet)
    if err != nil {
        t.Fatal(err)
    }
    if err := updater.AddInWitnessUtxo(wire.NewTxOut(utxoAmount, tapscript.output), 0); err != nil {
        t.Fatal(err)
    }

    var serializedTx bytes.Buffer
    if err := packet.Serialize(&serializedTx); err != nil {
        t.Fatal(err)
    }
    psbtHex := hex.EncodeToString(serializedTx.Bytes())
    t.Log("psbtHex before sign:", psbtHex)

    // signit
    cu := cuabs.New()
    signedPsbtHex, err := cu.PsbtSign(context.Background(), signpks[0], psbtHex)
    if err != nil {
        t.Fatal(err)
    }
    signedPsbtHex, err = cu.PsbtSign(context.Background(), signpks[2], signedPsbtHex)
    if err != nil {
        t.Fatal(err)
    }
    t.Log("psbtHex after sign:", signedPsbtHex)

    // addDummySigs like bitcoinjs-lib
    psbtBz, _ := hex.DecodeString(signedPsbtHex)
    packet, err = psbt.NewFromRawBytes(bytes.NewReader(psbtBz), false)
    if err != nil {
        t.Fatal(err)
    }

    for index, input := range packet.Inputs {
        for _, pk := range pks {
            pkbz, _ := hex.DecodeString(pk)
            var signed bool
            for _, x := range input.TaprootScriptSpendSig {
                if bytes.Equal(pkbz, x.XOnlyPubKey) {
                    signed = true
                    break
                }
            }
            if !signed {
                packet.Inputs[index].TaprootScriptSpendSig = append(packet.Inputs[index].TaprootScriptSpendSig, &psbt.TaprootScriptSpendSig{
                    XOnlyPubKey: pkbz,
                    LeafHash:    tapscript.tapleafHash,
                    Signature:   nil,
                    SigHash:     0,
                })
            }
        }

        // sigs := packet.Inputs[index].TaprootScriptSpendSig

        // sort.Slice(sigs, func(i, j int) bool {
        //  return bytes.Compare(sigs[i].XOnlyPubKey, sigs[j].XOnlyPubKey) < 0
        // })
        // packet.Inputs[index].TaprootScriptSpendSig = sigs
    }

    {
        var serializedTx bytes.Buffer
        if err := packet.Serialize(&serializedTx); err != nil {
            t.Fatal(err)
        }
        t.Log("psbtHex before finalize", hex.EncodeToString(serializedTx.Bytes()))
    }

    if err = psbt.MaybeFinalizeAll(packet); err != nil {
        t.Fatal(err)
    }
    {
        var serializedTx bytes.Buffer
        if err := packet.Serialize(&serializedTx); err != nil {
            t.Fatal(err)
        }
        t.Log("psbtHex after finalize", hex.EncodeToString(serializedTx.Bytes()))

    }
    //extract()
    //broadcast()
}

Use js code,it work. "tapscript.tapleafHash" in golang is equal "leafHash" in js,and "pubkey" is equal.
After comparison, it was found that the "psbtHex before finalize" and "psbtHex after finalize" were different.
my js code:
const psbt = bitcoin.Psbt.fromHex(signedPsbtHex)
{
  const leafHash = tapleafHash({
    output: leafScript,
    version: LEAF_VERSION_TAPSCRIPT,
  })
  console.log(leafHash.toString('hex'))
  for (const input of psbt.data.inputs) {
    if (!input.tapScriptSig) continue
    const signedPubkeys = input.tapScriptSig.filter((ts) => ts.leafHash.equals(leafHash)).map((ts) => ts.pubkey)
    for (const pubkey of leafPubkeys) {
      if (signedPubkeys.some((sPub) => sPub.equals(pubkey))) continue
      input.tapScriptSig.push({
        // This can be reused for each dummy signature
        leafHash,
        // This is the pubkey that didn't sign
        pubkey,
        // This must be an empty Buffer.
        signature: Buffer.from([]),
      })
    }
  }
} // this code from bitcoinjs-lib

psbt.finalizeAllInputs()
const tx = psbt.extractTransaction()
broadcast(...)

I solved this problem, you can use the following code, it is equivalent to js's "addDummySigs".
    for index, input := range packet.Inputs {
        for _, pk := range pks {
            pkbz, _ := hex.DecodeString(pk)
            var signed bool
            for _, x := range input.TaprootScriptSpendSig {
                if bytes.Equal(pkbz, x.XOnlyPubKey) {
                    signed = true
                    break
                }
            }
            if !signed {
                packet.Inputs[index].TaprootScriptSpendSig = append(packet.Inputs[index].TaprootScriptSpendSig, &psbt.TaprootScriptSpendSig{
                    XOnlyPubKey: pkbz,
                    LeafHash:    tapscript.tapleafHash,
                    Signature:   make([]byte, 0),
                    SigHash:     txscript.SigHashDefault,
                })
            }
        }

        sigs := packet.Inputs[index].TaprootScriptSpendSig
        sort.Slice(sigs, func(i, j int) bool {
            return bytes.Compare(sigs[i].XOnlyPubKey, sigs[j].XOnlyPubKey) > 0
        })
        packet.Inputs[index].TaprootScriptSpendSig = sigs
    }


text:
I have .3081 BTC & cost basis of 97.530 & account value of $30,000. I need the formula to 'predict' what I will have when BTC hits $120,000 etc
Will you please help me? I have .3081 BTC and cost basis of 97.530 and account value of $30,000. I need the formula to 'predict' what I will have when BTC hits $110,000, $115,000 , $120,000 etc.

At this time
You have or will have

Now
0.3081 BTC

When BTC hits $110,000
0.3081 BTC

When BTC hits $115,000
0.3081 BTC

When BTC hits $120,000
0.3081 BTC

If you want the answer in some arbitrary fiat currency, apply the appropriate exchange rate

At this time
You have or will have the equivalent of

Now
0.3081 x 97,740 USD

When BTC hits $110,000
0.3081 x 110,000 USD

When BTC hits $115,000
0.3081 x 115,000 USD

When BTC hits $120,000
0.3081 x 120,000 USD

If you want to calculate capital gains to calculate your liability for capital gains tax or similar purposes, subtract your cost basis expressed in your reporting currency. I'm no tax expert but I believe in most jurisdictions a capital gain is only realised when the asset is sold. In the case of cash, I think that would normally be when the cash is converted to another currency or used to purchase something. But you should ask a tax adviser about that.

The formula is number of BTC * price.


text:
Are there any Bitcoin block explorers still around that log First Seen by node data?
Title..  Hoping to find out when a historical tx went into the mempool.  I'm aware this is transient data and not in the blockchain.  However i'm pretty sure I remember in the old days explorers used to log it.
edit:
i would like to find a block explorer that logs the first time its node saw particular transactions in the mempool, as opposed to the first time they were in a block.   ie:  I would like to look up a tx and see how long it sat in the mempool before it was mined.

The closest thing i know of is https://mempool.observer/monitor/ but i don't think they store the first seen version of an RBFed tx.

From my recollection: For transaction in the mempool, a timestamp in a block explorer is set to when the transaction was first observed; once the transaction is mined, the timestamp is changed to the timestamp of the block.

Could you be a bit more specific?
There are a few block explorers that do provide information specific to their block explorer's running node.
Best lead I have for you is: https://bitcoinvisuals.com/
There's a lot of node information on there though I'm not sure its exactly what you're looking for.
However, I know that the owner of the site is pretty responsive and very easy to get into contact with.

I edited my question.


text:
Is there an alternative to identify a lightning node without their IP or onion address?
In the country where I live, only dynamic IPs are assigned to most customers unless you are willing to pay a lot more for a business service.
I guess not everyone in the world can get a static IP without paying a lot extra or doing something like running a VPS.
Also, a node operator with a static IP address doesn't have total control of the IP assigned to them.
I learned that lightning uses the IP or onion address of the node to identify it, so if a node changes their IP - I guess - it assumes the node is not online anymore. Which, I understand, is a problem if you open a channel with a node.
So, my question is: is there an alternative method, implemented or not, to identify a lightning node without knowing their IP or onion address?

Lightning network nodes are identified by their node_id which is a ECDSA pubkey. This key will not change if the network Adress (IP Adress or onion Adress) changes.
If you issue invoices you will see that neither IP nor onion Adresse are part of the invoice and necessary for routing. Only your node ID (which can be derived from yours signature) is part of the invoice. This means as long as your node is online, has open channels and is connected to its peers it will be able to send and receive money.
So the question is what happens to your node and its connections if the node changes its IP Adress? Well it will in the background open a new connection to its peers and channel partners so that they can talk to you again.
Of course for other peers to be able to connect to your node your node has to send out a new node announcment message via the gossip protocol in order to update its network adress. As gossip messages in lightning are not relayed in real time to protect against spam it can be tricky for other nodes to connect to you if your network address changes too often. However this will not be an issue for end users as their node can reestablish its necessary connections to its channel partners.
If course if all channel partners have the same problem peers could not find each other and conduct the reestablishing in real time. Thus for the routing part of the network somewhat stable network addresses are useful. In general toronions are considered more stable than dynamic IP addresses.
Of course lightning network could have relied on DNS as an alternative to solve that issue. While it does rely on DNS for node discovery as described in BOLT10 it does not use dns for your described problem. So to answer your question fully: no there is currently no alternative but that is most likely never a problem.


text:
Are transactions from two separate bitcoin accounts on Ledger Nano S independent of each other?
John Doe creates two separate bitcoin accounts on a ledger nano s and funds the accounts from two separate sources. The first funding source is a known terrorist organization and the second funding source is Coinbase or some other KYC compliant exchange.
Can the bitcoin on the first account funded by the terrorist organization be linked to the bitcoin on the second account belonging to John Doe if both accounts live on the same Ledger Nano S? Assume that there are no transactions between the two accounts.

A single future transaction between the two accounts would trigger a reaction from any Onchain surveillance system that is being used.
If the IP address or device fingerprint that was used to send a TX at the major exchange was ever used on another account at the same exchange or was affiliated with a TX of another known terrorist financing address. Onchain surveillance just scans all public lists even if they aren’t all trust worthy, depends how reliable of data the researcher is willing to use.


text:
Do inputs have a minimum value in order to be "standard" transactions?
I am aware that a transaction which creates an output below dust value is considered "non-standard" and not relayed by default nodes.
Does a similar rule apply for spending a utxo?
For example, imagine there already exists a mined utxo with an output value of 1 (below dust). I attempt to spend this utxo (appending another input to help pay the mining fee). Will my new transaction also be considered non-standard due to the low-valued input or is it considered standard?

No, the dust rule only applies to transaction outputs, and it wouldn't make sense otherwise. The policy exists to prevent the creation of outputs that would likely live forever because they are not economical to spend, but if they end up being created and someone wants to spend them anyway, we don't want to stop them.
You can find the source code for this policy rule here.


text:
Am I correct in assuming that for-profit Lightning Channels need to be regularly "emptied out"?
Lets say we have three people/nodes, Tom, Jack and Bob. Tom wants to send Bob 50 satoshi. Tom has a channel with Jack with 1000 sats capacity (the multisig transactions contains 1000 sats from Tom and 0 from Jack). Jack also has a channel with Bob, where Jack has spent 1000 sats and Bob 0 sats. Lets assume Bob is a coffee owner and therefore never sends money to Tom, since Tom is his customer.Now Tom buys a coffee everyday for a while, routing the payments through Jack. Since both Jack and Tom only ever send money in one direction, eventually it will get to the point where they both run out of capacity. Since each hop channel needs to be able to cover the full transaction (which means the channels need a combined capacity of number_of_hops*money_to_be_sent) eventually their channel is useless. Which means they have to both empty their now useless channel (submitting the two final commitments to the blockchain), which incurs bitcoin on-chain transaction costs for both of them (on top of the transaction costs they both had to pay in order to open the channel). Jack may make a profit if his routing fees exceed the bitcoin transaction costs, but for Tom its a complete loss. Is this correct so far?

When you write "for Tom its a complete loss" What exactly do you mean, didn't Tom receive coffee every day? Don't all purchases, regardless of payment method, necessarily involve monetary loss? You have to pay for the coffee after all.

Yeah but unlike Jack, Tom has achieved no positive balance. He only ever spends coins, leaving him with nothing (aside from coffee, but that has nothing to do with the channels). The main question is whether or not his channel is now useless or not (since Bob will never send money back).

I believe the expectation is that, if Tom buys a coffee everyday for a year, the 365 lightning transactions and two Bitcoin transactions are cheaper than 365 Bitcoin transactions. Are you asking if empty channels can be topped up as an alternative to closure?

You write "Tom has achieved no positive balance." But doesn't Tom have a positive balance when he pays money in to open the channel?

yeah but there is never any coins flowing towards Tom. guess more accurate is to say he never achieves positive cashflow

My question is, if I run a backbone lightning node where bitcoins only flow into one direction, will I have to routinely close and reopen channels (probably with the same bitcoin) in order to continue processing lightning payments?

Does this answer your question? Why can't lightning network channels increase balances？

I mostly just want to know if it is true that to send 50 sats from node_1 to node_2 to node_3 to node_4, each node need to have capacity of 50sats in the direction of the transaction. And if once that transaction is processed, each of them loose 50 sats of channel capacity in that given direction


text:
Does a Raspberry Pi have enough CPU power to run a full node and an electrs server?
Very curious if anyone has this particular setup, currently am running the aforementioned on an old Acer laptop but it's struggling hard.

Which rPI? There are several versions.


text:
Whats it called when two blocks are solved at the same time and create their own chain?
I'm trying to find more information on this topic but I can't remember what this is called in order to look up more information on it.
Is there an easy way to see the "trusted" amount of confirmations? I've noticed many people consider 3 confirmations to be good, however for larger transactions 6 is better. I've heard that bitcoin has had separate chains goings for 3, maybe 4 blocks.

Are you looking for one of the tags [tag:blockchain-fork], [tag:best-chain], or [tag:chain-reorganization]?

I think you mean a fork. Blockchain has forked if a block has got two or more children blocks. In bitcoin there is a longest-chain rule, that means that only the longest chain is valide.
At the same time, there is a possibility that an attacker can catch up from a given deficit of k blocks. But the probability that this will happen decreases exponentially with k.
In the white paper, Satoshi Nakamoto got some calculations. If an attacker has 10% of the network power, he can catch up to 6 blocks with a probability of less than 0.1%. That's why I think 6 blocks is something canonical. But some people and services wait less than 6 blocks. For example, some mixers may wait even 1 block.

I believe you are referring to the "longest chain" where two nonce are found and the respective blocks are broadcasted simultaneously. The following is an excerpt from the bitcoin whitepaper describing this scenario.
Section 5: Network: Bitcoin Whitepaper
"Nodes always consider the longest chain to be the correct one and will keep working on
extending it. If two nodes broadcast different versions of the next block simultaneously, some
nodes may receive one or the other first. In that case, they work on the first one they received,
but save the other branch in case it becomes longer. The tie will be broken when the next proofof-work is found and one branch becomes longer; the nodes that were working on the other
branch will then switch to the longer one"


text:
Do I need to download the entire blockchain in order to use bitcoin-cli?
I want to try and compile and run bitcoin-cli locally. Do I need to download the entire blockchain first?

For testing, you can run your node on testnet or signet which have much smaller blockchains, or run on regtest where there is no blockchain to download. If you need to run on mainnet but don't want to download the blockchain, you can disable all connections on your node. Of course, most CLI commands will be useless that way.

That would work for me. I will try and see how to run my node on testnet. I read it is only like this  bitcoind --testnet

You can use Bitcoin-CLI with only a partial copy of the blockchain. Obviously it will be limited in what it can do.


text:
There's any open API to gather the blockNumber data?
Trying to create a scrip to convert wordpress posts/pages date and display it as blockNumber instead. For context, a similar question also posted on this stack.
Do anyone knows if there's any open API or where the blockNumber can be retrieved from?

Similar question was answered in this stack overflow: Getting Bitcoin's block number in a specific date and hour?
Example: Convert the time of your wordpress post "Thursday, March 30, 2023 3:57:52 PM" to seconds since the UNIX epoch --> 1680191872, add three zeroes to that number --> 1680191872000 and insert it in URL like this: https://blockchain.info/blocks/1680191872000?format=json

There is an answer to a similar question on the WordPress StackExchange site here

You can use Bitquery Bitcoin APIs.
https://docs.bitquery.io/v1/docs/category/bitcoin-examples
Here's the query to get latest block info: https://ide.bitquery.io/latest-Bitcoin-blocks-number
You can create a free developer account and use it.
Full disclosure: I work at Bitquery. Feel free to ask questions in our support channels.


text:
Can a desktop wallet be tracked using IP address?
I'm wondering if I use a vanilla desktop wallet like MultiBit or Bitcoin Core to send and receive bitcoins, who can track my IP address and how?

Surveillance nodes in the Bitcoin network that mass-connect to many nodes within the network could pin-point and identify your node as the first relay for some of your transactions with some degree of confidence.
Receiving is not so much of an issue.
But spending from the same address consistently will enable surveillance nodes to figure out that a certain IP address is in control of some address.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Transaction creation process is not non-interactive(Mimblewimble)?
I have read Mimblewimble paper.
Certainly, Transaction merging process is non-interactive.
However, Transaction creation process seems to be not non-interactive.
To create transaction, a sender must interact a receiver because a sender shouldn't know all output's blinding factor(except change).
If a sender knows output's blinding factor, he can spend output.
Is my understanding of this correct?

It is possible to create MW transactions interactively, and if you're creating multisignature outputs I think this is actually necessary. But ordinary transactions can be created non-interactively (well, with half a round of interaction, as in Bitcoin where one party sends an address to another party who builds a transaction) in two ways:
Suppose the sender is trying to send 5BTC to the receiver.

The sender can create a transaction that doesn't balance unless a 5BTC output is added. Aside from this discrepancy the transaction is valid; she sends this to the recipient.
The recipient then adds a 5BTC output, adds another kernel to the transaction so that the blinding factors still add up, and the transaction is complete.
The sender acts as above, but sends the opening of the kernel. This is a bit dangerous because it gives the sender the ability to reverse the transaction long after the fact, but I'm unsure what sort of attack this would enable.

Note that both cases require a secure channel from the sender to the receiver because anyone who gets the incomplete transaction could add their own 5BTC output to it.
It's also possible to do this in reverse: the recipient sends the sender an incomplete transaction that needs a 5 BTC input to balance, and the same considerations apply.

Does the kernel means excess value? and What is opening?

Kernel is the more generic term for excess value. Opening means being able to spend.

Could some form of DH be used for the secure channel and passive receiving? Like, I publish some pubkey (A=a*G) of mine, you generate some random one-time private key (R=r*G), and publish the (R, H(r*A), unbalanced transaction encrypted with H(r*A)) to the blockchain. I can claim this TX at any time (unless you double-spend?), after which it could be purged from the blockchain.

There is a fundamental flaw in (1), the transaction which consists of 2 parts, whose the blinding factors are balanced, whereas the sum is not. So there are donor and acceptor parts. The attacker (malicious Node) may brute-force the sum that you're trying to send, and eventually puzzle out its structure. And then it just removes the intended acceptor part, and substitutes its own.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
What prevents a node from receiving a solved solution and claiming it as its own work?
During the relay process a node finds the solution and forwards that solved block to all other nodes in the network to validate that it has indeed solved the problem. But then what if another node decides to rebroadcast it again and claim that he was the one who found the answer first.

Do you modify the block or do you not modify the block?
If you don't modify the block, it still pays the mining reward to the same account. So you've just done what everyone wants you to do.
If you do modify the block, it won't be valid anymore until and unless you mine it. That leaves you two choices:
1) You can ignore this block and mine some other block. But then someone else who mines on top of this block will have a longer chain than you and you won't get any reward. So why would you do this?
2) You can mine on top of this block. Well, that will just help ensure the person who mined that block gets their reward by producing an even longer chain that includes their block.

A block contains: Version, HashPrevBlock, HashMerkelRoot, Time, Bit, Nonce, which one of these is the miner identifier.

@UtsavMitrakaushiBasak None of those are. The coinbase transaction specifies what account the mining reward is paid to. The HashMerkleRoot is the hash of the Merkle tree of transactions, including the coinbase transaction. The whole point of mining is to secure the transactions.

Understood, as in the transaction for the reward is included in the block, so no matter who confirms it the reward will go to the sender right?

@UtsavMitrakaushiBasak Everyone confirms the same block. The whole point of mining is to bind the transactions into the block so that they cannot be disassociated. There is nothing but the block. There isn't a block plus something else that claims it somehow. The block is the claim.

I still don't get it. When the solution is broadcasted, I don't have to modify a block. I simply use the nounce thats broadcasted, abandon the block in which the solution was broadcasted and creaty my own with the solution I just stole and then broadcast my new blockchain to as many nodes as possible and simply hope I'm connected to more than the original sender. I still see a big problem here.

You say "create your own with the solution I just stole". That is impossible. If you create your own block, you will have no solution to the block you just created. A solution for one block is of no use when trying to produce a different block (otherwise, you could just re-use the solution to an old block!). If you abandon the block, you abandon the solution to that block.

So, the coinbase transaction in the block that I'm about to mine changes the puzzle I want to solve, and thus, the correct answer to it? (The other transaction and data are of no value to me, they can stay the same)

@user2762996 Yes. The puzzle is to find a valid next block. The block is the solved puzzle.


text:
Why are miners allowed to change a tx id?
BIP 62 proposed to make transaction malleability impossible.
Why was this retracted and why are miners allowed to change a transaction id?
Also, what does it mean when someone says signatures cannot sign themselves?  Is this implying we not only need a signature for the transaction, we need another signature for the transaction + signature?

BIP 62 proposed to make transaction malleability impossible.

No it didn't. It would have outlawed a limited number of known and addressable forms of malleability.
In particular, it did not prevent multisig transaction participants from just creating a new signature, malleating the transaction without invalidation. This type of malleability is trivial to perform, and breaks nearly every smart contract construction imaginable.
BIP62 was retracted because while it addressed some forms of malleability, it didn't and couldn't fix an equally bad one.
Instead, Bitcoin adopted BIP141 (Segregated Witness), which does not remove malleability, but makes it harmless. The transaction signatures just don't contribute to the txids anymore. Thus, while it is still possible to malleate transactions, doing so does not invalidate dependent transactions (as they refer to previous transactions using the txid). Other than BIP62, this solution applies to multisignatures as well, and also against all forms of non-discovered malleability.

Wow, the author of BIP62 himself.  Apologies for the incorrect interpretation and the above makes much more sense.  Why not, however, just make everything immutable and not just the inputs, outputs, amount, etc?

How do you propose to make things immutable? The best thing that can be required is that all signatures are valid. If one signature is acceptable, how do you prevent the same people from creating a different but equally valid signature?


text:
Is it possible to bruteforce the seed?
Is it true that the "seed words" bruteforce more reliable for to get profit than searching of a "random number" for to open some profitable outputs?
The last one is impossible due to math, but the first one?

No, it is not true. Both are impossible due to math. The mnemonic is just an encoding of a number that is randomly generated (i.e. just like a private key) so it has the same security properties of that 256-bit number.
If you ignore that it encodes a number, consider this: a seed phrase encoding a 256-bit number needs 24 words in the mnemonic. There are 2048 possible words which means that there are 2048^24 = 2.964... × 10^79 possible mnemonics. There are 2^256 = 1.157... × 10^77 possible 256-bit numbers. There are actually more possible mnemonics than there are values to be encoded in the mnemonic. Thus the mnemonics are just as secure as a randomly generated private key (256-bit number) itself.

Assuming BIP39, a 24 word mnemonic actually encodes exactly 256 bits of entropy (2048^24/2^(24/3) = 2^256), since 1 bit of every 3 words is used as a checksum.

See also this article about Deterministic Cryptocurrency wallets:  https://en.wikipedia.org/wiki/Cryptocurrency_wallet#Deterministic_wallet
and BIP39 Mnemonic code or sentences on: https://en.wikipedia.org/wiki/Bitcoin_Core#Bitcoin_Improvement_Proposals

Please elaborate on the contents of the links as relevant to the question within your answer. As it stands, if the link disappears, or is edited significantly, it may no longer answer the question.


text:
Does a transaction in Bitcoin Mempool reach many miners during mining or only a single miner?
I'm trying to understand the logic around the Mempool. What I understand is a miner will pick transactions based on an incentive given by the sender, i.e. a fee, so that the higher fee, the faster transaction will get confirmed.
But, What if the transaction get picked by a single miner regardless of fee and that miner is very unlucky miner that somehow it never win the block hashing lottery. Is that possible?
My question is:
Is only a single transaction picked by a single miner and the miner hashes the transaction with other transaction, then guessing the nonce, if it wins, then it includes in the block, else return to the Mempool?
Or,
Is only a single transaction picked by multiple miners and all those miners hash the transaction with other transactions, the guessing the nonce and the miner who wins the lottery included it in the block?

How it actually works:
You send your transaction to one or more nodes (your wallet does this job for you). Each of the nodes (some of them are miners) sends it immediately to all the nodes it knows (and again and again).
All the miners store the transaction (if it's valid) in their own mempool.
When a new block was created, all miners look in their mempool and try to find the best not-mined transactions, pick those with the highest fee per byte and include it in their block-mining-attemp.
If one of the miner's mempool-transactions is mined, they simply delete it out of your mempool.

Thanks for the answer, it's very clear.
Stored transactions in their own mempool, let's say, tx1, tx2, tx3
the miner, m1, picks tx1,tx2 -> block-mining-attempt -> get a new block. And, the miner,  m2, picks tx1, tx2, tx3 -> what will happen next to tx3, return to his own mempool?

Note that your transaction is not sent directly to miners but rather sent to other nodes on the network which may or may not be miners.

@zdk I'm not 100% sure, but I think, a transaction stays in the mempool when the miner picks it. The miner can remove it later (as soon it's mined by someone). It depends on the implementation of the mempool...


text:
How come some addresses show up in search results while others don't?
Some Bitcoin wallet addresses can be found by google, but some others shows no result. For example, this wallet is visible on many Bitcoin websites and google has a lot of results 1ENFY4h7ntGZbqwcwpQtXVFJrPnfXRHQLe and we can see its transactions. But this other address 126kUxBmdLTk4M7w1uaQ2pjAhm9KbZ6dxp (a ransom-ware wallet!) has no result. How it is possible? How can people do this?

The latter address does not show up in google because it has not been used for a transaction yet. Once someone sends money to it, it will show up.
It's possible that we'll be able to create systems in the future that don't have this problem, but don't hold your breath.

Systems using mandatotry stealth addressing (such as cryptonotes) achieve this already, and are in production.

@user36303 In some cases, yes, but in other cases, it's possible to correlate multiple transactions by the same person together. This reduces anonymity to psuedoanonymity. I would wait for more study before relying on those properties.

You are right, but I should have mentioned I was talking about the point made in the post I was replying to, rather than some other tangentially related one :)

Every (real) transaction made with Bitcoin is stored on the Blockchain. Forever. If you are able to send Bitcoins to another address without it showing up on the Blockchain, you are not sending (real) Bitcoins.
So for your question on how to create an anonymous wallet, (public key and private key i suppose) you can do so very easily by generating it on an offline machine (using bitaddress.org for example, how to use it is explained there), and only providing your public key to the services/people that would need to send Bitcoins to you.

This public key will remain anonymous as long as there aren't any
  obvious connections to it- making the exchange where you bought your
  Bitcoins and that has your credentials and ID send the Bitcoins
  directly to that public key for example.

And on how to 'hide' transactions on the Blockchain- it's impossible. You can send Bitcoins through various 'Mixers' (bitmixer.io - or the onion for that link, bitmixer2whesjgj.onion ) to 'hide' the actual destinations of your Bitcoins, or you can send Bitcoins through hundreds of wallets, in the hopes that anyone that might be tracing your digital steps get lost in the transactions.
But like i stated before, every transaction -ever- made on the Blockchain is saved by the many Full Nodes and will therefor never be hidden.
I hope this helped!

126kUxBmdLTk4M7w1uaQ2pjAhm9KbZ6dxp has never been used in a transaction, as can be verified at
https://blockchain.info/address/126kUxBmdLTk4M7w1uaQ2pjAhm9KbZ6dxp
If 126kUxBmdLTk4M7w1uaQ2pjAhm9KbZ6dxp is also not showing up in normal search engine results, then this address has likely never been openly published anywhere online.
If 126kUxBmdLTk4M7w1uaQ2pjAhm9KbZ6dxp is known to you as a ransom-ware address, this most likely means that the person who made the ransom-ware recently generated this address and is asking you for payment to it, but has otherwise not published this address anywhere else.


text:
How to disable RBF in Bitcoin Core?
I am creating a transaction with Bitcoin Core (v24.0.1) and it has RBF enabled (sequence: 4294967293) by default. I am trying to disable RBF by adding walletrbf=0 and mempoolfullrbf=0 to bitcoin.conf but it does not seem to make any difference to the input's sequence field.
EDIT:
I use bitcoin-cli createrawtransaction to create the transaction.

walletrbf=0 only disables RBF when creating transactions through wallet RPCs such as sendtoaddress, sendmany or sendall. If you use the low-level RPC createrawtransaction, you need to either set the replaceable parameter to false or manually set your sequence numbers. If you're creating transactions through the Send tab in the GUI, you simply need to uncheck a checkbox right below fee selection that says "Enable Replace-By-Fee".
mempoolfullrbf=0 controls a mempool policy (whether to allow replacements for transactions that don't signal RBF), it has nothing to do with the wallet.


text:
BIP for submitpackage rpc call
Is there a BIP for submitpackage RPC call? I do see BIP-431 for TRUC, and cannot find one for submitpackage.

The Bitcoin Core RPC interface is specific to Bitcoin Core, and doesn't need coordination across the ecosystem. Because of that, it is generally considered out of scope for the BIP process.


text:
Why is the bytestring 0xaa21a9ed used as the witness commitment header in SegWit?
As per BIP 141, the witness Merkle root hash is stored in a scriptPubkey field of a coinbase transaction output with a header consisting of the 4-byte string 0xaa21a9ed. What is the reasoning behind choosing this string?
Googling only yielded a reference to namecoin on a bitcoin-dev IRC log.

It's random.
The intent was choosing something long enough to avoid having someone accidentally create an output that matches, but short enough that it doesn't unnecessarily makes SegWit blocks larger.

Why was it not chosen to be some regular 4-byte string like all zeros or all ones or 0xAABBCCDD? Will the probability of someone creating a null data output which matches the header increase if the header had some regular structure?


text:
C secp256k1: What do prefixes 0x06 and 0x07 in an uncompressed public key signify?
In the eckey_impl.h header file, the implementation of secp256k1_eckey_pubkey_parse checks if the first byte of a 65-byte public key is 0x04, 0x06 or 0x07. Where can I find documentation regarding the 0x06 and 0x07 prefixes?
static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size) {
    if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) {
        secp256k1_fe x;
        return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == 0x03);
    } else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) {
        secp256k1_fe x, y;
        if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) {
            return 0;
        }
        secp256k1_ge_set_xy(elem, &x, &y);
        if ((pub[0] == 0x06 || pub[0] == 0x07) && secp256k1_fe_is_odd(&y) != (pub[0] == 0x07)) {
            return 0;
        }
        return secp256k1_ge_is_valid_var(elem);
    } else {
        return 0;
    }
}

These are used in the "hybrid" public key format, which is an uncompressed format (it has both X and Y coordinates, like 0x04) that still stores the odd/evenness of the Y coordinate (like 0x02/0x03).
It is defined in ANSI X9.62-1998 Sections 4.3.6 and 4.3.7, and seems totally useless to me. However, OpenSSL supported it, thus when switching to libsecp256k1 for validation, it had to support it too, or we'd risk consensus failures in the network if such a pubkey would ever be used. Now we're pretty much stuck with it.


text:
Can an output be spent in the block in which it is contained?
Is a Bitcoin block containing both a transaction that funds an output, and another transaction that immediately spends the same output, allowed by the protocol?
Does such behavior occur "in the wild", e.g. do any of the common clients allow spending unconfirmed Bitcoins? Would miners include such transactions?

possible duplicate of Can multiple transactions transferring the same bitcoin be done in one block?

allowed by the protocol?

Yes. It is possible to spend an output immediately. And two (three-four-etc) chaining transactions will be included in the same block. There are a lot of examples in blockchain. Note, that the their order in block is fixed.

do any of the common clients allow spending unconfirmed Bitcoins

Bitcoin-core client allows to send "raw transaction" to spend unconfirmed bitcoins. Also the "change" output can be spent without confirmations. Holding incoming bitcoins for several confirmations is an interface option only, not a protocol rule.

Sure. Miners simply receive both transactions and try to include them in a block.
Regarding confirmations, this is only a concern when wanting to claim a transaction you've received from someone else. If they're your own coins, there's no risk of a double spend.

There is risk of spending unconfirmed change because transactions are still malleable.

Can you elaborate more on this? Not sure I understand. Change is only calculated once the block's hash is found and therefore both transactions are included within it.

OK, I will try to explain. I pay for a cup of coffee, sending tx1. One output 0.01 BTC for StarBucks and 0.01 change to myself. Right after that I spend my change for another cup of coffee for my girlfriend. Tx1 was malled by somebody and included in block with different hash. Tx2 becomes orphan and never be confirmed. Now StarBacks think that I (or my girlfriend?) am double-spender. Isn't is a risk for my reputation?

@amaclin your statement that transactions content are malleable requires a reference. It can be malled to change the transaction hash, but the miners won't think it's a different transaction because they check inputs/outputs.

tx1 will still valid after [S := G-S] attack to ecdsa signature, but tx2 will not be confirmed, because its inputs refer to original hash of tx1. OK, it is not risk to lose your funds. It is a risk not to pay for something you want to pay. So, it does not matter - are you spending your own change, or funds incoming from anyone


text:
Do bloom filters protect against a persistent eavesdropper?
As far as I understand it, bloom filters can be defined with some target hashes and false-positive rate. When filtering the blockchain, all of the target transactions are guaranteed to be found, but many false-positives will also be returned to the client by design.
Suppose that an attacker is able to monitor many bloom filter specifications sent by an SPV client to its peers. Will he be able to eventually eliminate all false positives by performing subset matching on all transactions matching the filters?
As an example, let the set of all transactions be the integers from 1 to 100, and suppose that a client is interested in the transactions 4, 8 and 15. The first time he connects to the network, he transmits a bloom filter matching (1, 4, 7, 8, 15, 27, 44, 73); the second time, his filter matches (3, 4, 6, 8, 15, 27, 66). An attacker would immediately be able to narrow the possible transactions down to (4, 8, 15, 27); after several more invocations, he would then find the correct answer.
Am I misunderstanding how bloom filters work (e.g. the false positives do not change between connections), or is this a theoretical or even practical concern?

See this paper for a good discussion:
On the Privacy Provisions of Bloom Filters in Lightweight
Bitcoin Clients

Yes, you are misunderstanding how vanilla/canonical bloom filters work. For the standard definition, false positives do not change between connections - the set returned on a second request, if different, will be a superset of the first set.
Also, vanilla bloom filters are not used as solutions to security/eaves dropping problems - they're a computation vs. disk access tradeoff optimization (I think of them as a subset of caching algorithms). You might use a local bloom filter to check whether a given url is malicious, to avoid making an expensive network call/lookup on each url access, and only make the network call when you get a positive response.

That said, there are techniques to make bloom filter like structures, which are more robust/have stronger security-characteristics. I don't believe any of them have been applied to bitcoin implementations.

The bitcoin specification of bloom filters seems to contain a random input to the hash functions (ntweak) - doed this also not influence the false positives?

@lxgr quickly looking through the code, it seems to me that the ntweak value is meant to help better distribute the use of hash functions, and ultimately reduce the number of false positives you get (even further reducing the security value that the bloom filter might provide, but increasing it's effectiveness as a cache) - you're right, the implementation is non-canonical in the sense of being likely to return random false positives on successive calls.


text:
Golang how to derive address from bip32's xpubkey?
i'm trying to derive HD address of bitcoin using Golang. I have extended private/public key. The problem is i'm unable to find any library in Golang that can generate/derive address from the xpubkey/xprivkey. any advice?

Take a look on https://github.com/wemeetagain/go-hdwallet
// Generate a random 256 bit seed
seed, err := hdwallet.GenSeed(256)

// Create a master private key
masterprv := hdwallet.MasterKey(seed)

// Convert a private key to public key
masterpub := masterprv.Pub()

// Generate new child key based on private or public key
childprv, err := masterprv.Child(0)
childpub, err := masterpub.Child(0)

// Create bitcoin address from public key
address := childpub.Address()

// Convenience string -> string Child and ToAddress functions
walletstring := childpub.String()
childstring, err := hdwallet.StringChild(walletstring,0)
childaddress, err := hdwallet.StringAddress(childstring)


text:
How are parts of Bitcoins traded?
I understand how whole Bitcoins are traded (each coin has its own identifier, this identifier is associated with a wallet), though I do not understand how it is possible to trade parts of a Bitcoin (e.g. I can buy 0.7 BTC from Mt. Gox). How are the Bitcoins tracked once they are split into parts, and associated with different wallets?

It is not true that individual bitcoins have an identifier. In fact, individual bitcoins do not exist.
What your wallet holds are addresses. These addresses can occur in the Bitcoin block chain, which can - at its simplest - be seen as a big database of balances for each Bitcoin address. Your wallet also holds a private key for each address, which can be seen as the password needed to spend the balance that is accredited to the corresponding address.
When you spend some bitcoins, you send them from one of your addresses to another address. Only the person that owns the private key corresponding to the address, can spend the bitcoins on its balance.
Now, that still not explains how bitcoins can be divided into smaller fractions. In fact, the Bitcoin protocol does not really work with the unit bitcoin, but with a smaller unit, called satoshi. 1 bitcoin equals 100,000,000 (= 10^8) satoshi. So 1 satoshi (=10^-8 BTC) is the smallest amount you can send.
This means that when you send 0.7 BTC, you actually send 70,000,000 satoshis.

Each coin does not have it's own identifier.  You create a bitcoin "address" which is just a public key (you hold the private side which is proof that you own the address).  You can have an unlimited amount of public keys.  At all times, the blockchain contains information that defines how many BTC each address owns.  The blockchain is like an accounting journal.  Everyone knows how many BTC every address owns at any one time.
Expanding on this, if you want to send BTC to someone, you send ALL of the BTC that address owns.  However, you send to more than one recipient, one of those recipients can be yourself.
This is demonstrated in this transaction:
http://blockchain.info/tx/b2391755af7382c6643822a52e25620899396cc0dceab0a399033aeafa516310
The address at the left sent 1.6628596 BTC to the first address and 10.57632087 BTC to the second.  This is also how you make "change".  You send a portion of the owned BTC to the recipient, and the rest to yourself (and this also serves to further anonymize transactions).
Knowing this, you can probably see that you can send a small portion (It's claimed that one BTC is infinitely divisible) out of one address and to another.

Bitcoins are not infinitely divisible.

You defined the lower limit in your post, thank you. I was just assuming that there was a practical limit even though it is claimed that there is not: https://en.bitcoin.it/wiki/FAQ.  "Bitcoin, however, offers a simple and stylish solution: infinite divisibility. Bitcoins can be divided up and trade into as small of pieces as one wants, so no matter how valuable Bitcoins become, one can trade them in practical quantities."

It's true that the Bitcoin concept supports infinite divisibility. But the current implementation of the protocol does not. The protocol could be changed to allow for higher divisibility, and perhaps that will happen whenever the price becomes to high and a higher divisibility is desired.

Your understanding of bitcoins is incorrect.  A bitcoin is only a number in a ledger, called the blockchain.  When someone receives bitcoins, a transaction is added to their ledger which shows them as having received the bitcoins.  When they send out bitcoins, a transaction is added to their ledger which shows them as having given away bitcoins.


text:
Can there be a half segwit, half normal Bitcoin transaction?
I was wondering if it's feasible to compile a bitcoin transaction that is somewhere in between (segwit and non-segwit), maybe one of these scenarios. I'll call the non-segwit inputs, normal inputs just for the sake of simplicity.

Use one normal UTXO input and one segwit input
Use Segwit inputs but have normal outputs
Have a transaction with two outputs, one Segwit and one normal

If the answer to any of these is yes (maybe doesnt apply to the last scenario), what would be the case for transaction malleability? would the final transaction be still vulnerable to transaction malleability as the signature is still in the main transaction object?

Yes, absolutely.
Every output can independently be a normal or SegWit output (when using P2SH-embedded SegWit, you can't even tell until it is being spent).
Every input can independently spend a normal output or SegWit output.
When a transaction has at least 1 SegWit input it's called a SegWit transaction.
When not all inputs are SegWit inputs, the transaction is still malleable.

Thanks Pieter. your answer and some readings here resolved most of my questions: https://bitcoincore.org/en/segwit_wallet_dev/

Yes, that is certainly possible. BIP 143 has examples of such transactions. Transactions that spend from both segwit outputs and non-segwit outputs are still vulnerable to transaction malleability.


text:
Can you pay with Litecoin anywhere you can pay with Bitcoin?
Can you pay with Litecoin at any place that accepts Bitcoin? If no where can you spend Litecoins?

Merchants that only accept Bitcoin, will not accept Litecoin directly.
However you can pay any Bitcoin merchant with a 3rd party that automatically converts your Litecoin to Bitcoin. The most well known service of this type is shapeshift.io
Merchants can integrate their "shifty" button to make this easier for consumers to use, but the Shapeshift service is available for every consumer wishing to pay a Bitcoin merchant regardless of if they have integrating the Shapeshift API or not.
https://shapeshift.io/shifty_button.html
https://shapeshift.io/#/coins

While the process of spending Litecoins is extremely similar to Bitcoins, it is an alternative currency without a community accepted fixed exchange to Bitcoin therefore the merchant has to accept the work of conversion.
To the best of my understanding, Bitpay, bitmit.net and the other major markets and payment portals do not accept Litecoin. I'll refer you to this discussion as it probably is more informed and active than anything you'll get in a stackexchange format https://bitcointalk.org/index.php?topic=139940.0

I'll see if I can fish some more links out for you

ltc and btc are two different crypto currencies and are treated as such.  For example, BitInstant currently does NO business in ltc.  However, you will find some places like btc-e will deal in BOTH ltc AND btc.


text:
What wallet size difference to expect between Bitcoin Core (binary) and Electrum (json) wallet files?
Imagine a relatively big wallet with tens of thousands of addresses and 3x transactions.
Now, let's say I restore such a wallet and do full re-scan in two applications - in Bitcoin Core and in Electrum.
Ignoring the size of the blockchain itself when it comes to Bitcoin Core, and comparing only the file size of the wallet file(s), what difference should I expect between Bitcoin Core and Electrum, or, more generally, between Bitcoin Core and other wallet client software that uses json/other textual format to store the wallet data?

According to some people, the difference between simple binary encoding and JSON is often one or two orders of magnitude (10 to 100 times).
Obviously it depends on the data and the exact details, including indexing strategies etc. I think you'd have to restore an example wallet in both applications and measure the result.


text:
Creating a P2SH-P2WPKH using Bitcoin Functional Test Framework
I'm using the Bitcoin Functional Test framework to understand how  SegWit works by analyzing and building a P2SH-P2WPKH transaction.
When I run my code the transaction gets created, but when I inspect the Tx Hex, I cannot see the SegWit marker 00 on the 5th byte nor the segWitFlag, so probably I'm doing something wrong. Can anyone point out what could be the correct way to do it? Thanks so much in advance
Here is my Python Code:
key = ECKey()
key.generate() # generate private key
pubkey = key.get_pubkey().get_bytes()
pubkey_hash = hash160(pubkey)
witness_script = keyhash_to_p2pkh_script(pubkey_hash)
hashed_script = hash160(witness_script)

script_sig = CScript([ OP_0, pubkey_hash ])

script_pubkey = scripthash_to_p2sh_script(hashed_script)
destination_address = byte_to_base58(hashed_script, 196) # 196, Bitcoin testnet script hash

self.log.info("Witness script: {}".format(repr(witness_script)))
self.log.info("scriptSig): {}".format(repr(script_sig)))
self.log.info("scriptPubKey: {}".format(repr(script_pubkey)))
self.log.info("Destination Address: {}".format(repr(destination_address)))

# Create transaction
tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(int(utxo['txid'],16), int(utxo['vout'])), scriptSig=script_sig))
tx.vout.append(CTxOut((int(utxo['amount']) * COIN) - 1000, script_pubkey))
tx.rehash()
self.log.info("Transacción: {}".format(tx))

# Add witnessscript
tx.wit.vtxinwit.append(CTxInWitness())
tx.wit.vtxinwit[0].scriptWitness.stack = [witness_script]

self.log.info("Sign transaction")
tx_hex = self.nodes[0].signrawtransactionwithwallet(tx.serialize().hex())["hex"]
self.log.info("Transaction HEX: {}".format(tx_hex))

decrawtx = self.nodes[0].decoderawtransaction(tx_hex, True)
descriptor = decrawtx['vout'][0]['scriptPubKey']['desc']
# Get descriptor
self.log.info("descriptor: {}".format(descriptor))

What does the transaction look like before you give it to signrawtransactionwithwallet? It's possible that the RPC is removing the scriptSig and scriptWitness data from the input because the wallet cannot sign for it and so it is incomplete/invalid. Since you generated the key with the test framework, you should use signrawtransactionwithkey.

Here is the Transaction before signing: CTransaction(nVersion=2 vin=[CTxIn(prevout=COutPoint(hash=b31ca5d5ba91df771d2e4c17dc67ed4fb9e3165acb99730df3bf44bf22403928 n=0) scriptSig=0014ddc48b68a304b5c9cbf7e52610398aa405b2aa62 nSequence=0)] vout=[CTxOut(nValue=49.99999000 scriptPubKey=a91418e6390ad3f0ae6f82a19b9bb163406a78e4356587)] wit=CTxWitness() nLockTime=0)

Based on your comment, I tried to generate the Address from the node:
      pubkey = self.nodes[0].getaddressinfo(address)['pubkey']
      pubkey_hash = hash160(pubkey.encode()) # .encode()```

this is the Transaction HEX I get (still weird, cause the scriptSig is not there): 020000000128394022bf44bff30d7399cb5a16e3b94fed67dc174c2e1d77df91bad5a51cb3000000006a47304402200cf88582d5827d18b7756ca361634353adf967300030ba3090ecb749796d906b02204b7181eaf802b134a48ea4feb365333286045e1904c7c09d5f8d40c3d8ed230201210227d85ba011276cf25b51df6a188b75e604b38770a462b2d0e9fb2fc839ef5d3f000000000118ee052a0100000017a9141923ac992a31635121f6177babbdcf5ba576a4858700000000

To use signrawtransactionwithkey first I would need to construct the raw transaction, createrawtransaction requires the inputs and the outputs, the destination address, but not the scriptPubKey or scriptSig, how should I do it? We got back to my original question. Can anyone point out what will be the correct way to do it? thx!


text:
Bitcoin transfer missing
I transferred $100 from my Crypto.com wallet to my blockchain.com only for blockchain.com to say it was never received. Here is the transaction Id
c8b7d7b-01e9-4009-be27-
b23bdabb64b0
What can I do

That isn't a Bitcoin transaction-ID. It might be a proprietary wallet-ID - but those mean nothing in the Bitcoin network. You probably need to resolve this directly with the two businesses.

As mentioned, this is not a Bitcoin TXID. Contact Crypto.com support here


text:
Why is the average transaction fee so high created by my own written code?
Recently, I'm trying coding with Bitcoin like creating raw transaction and filling with some data finally send the raw transcation.
There is a question I don't know how to deal with.
With my own Golang code to create and send raw transcations, the average transcation fee is so much higher than that of the transcation I create with Bitcoin core software. Refer to tx1
and tx2.
Is there some kind of optimization to create transcations?

It looks like you aren't adding a change output so you're just throwing away the change to transaction fees. The transaction fee is the difference between the sum of the output amounts, and the sum of the input amounts. Additionally, change does not automatically come back to you. When you spend a UTXO, you can't spend just a part of it, you must spend all of it, and send the remainder (minus however much for transaction fees) back to yourself in another output. If you forget to make a change output, then that change becomes part of the difference between the sum of the output amounts and the sum of the inputs amounts, and so it becomes part of the transaction fee.

Thanks a lot! I read docs about change, now I knew how to save BTCs.


text:
How many Bitcoin addresses are there?
I was wondering where I could see how many unique addresses currently exist in the blockchain, and especially how many of those have a positive balance. Is that data available somewhere?

As of 12th May 2013 there have been just over 13 million distinct Bitcoin addresses which have been recipients of funds, and of those just over 1.6 million carry a positive balance.
However, please be aware that a single person's wallet is very likely to have multiple addresses in it, so the above numbers should not be extrapolated to assume anything about the number of users of Bitcoin.

You could create an index of all addresses and their balances by going over the whole block chain, f.e. using the RPC API.
I quickly wrote this script in Python. Note that I did not verify it! I only made it to give you an idea on how you can iterate over all transactions. Also, there is probably a more time-efficient way to do it by reading the block chain files yourself.
# setup bitcoind as RPC connection to your bitcoind client using JSON-RPC
block_hash = bitcoind.getblockhash(0)
while True:
    block = bitcoind.getblock(block_hash)
    for txid in block["tx"]:
        # you will need to run bitcoind with -txindex to be able to do this
        tx = bitcoind.gettransaction(txid)
        for det in tx["details"]:
            address = det["address"]
            amount = det["amount"]
            # do something with address and amount
            #  f.e. put them in a dictionary (this will take a lot of RAM)
            #  it is more advised to setup a db on disk
    if block.has_key("nextblockhash"):
        block_hash = block["nextblockhash"]
    else:
        break


text:
Why does bitcoin use signatures to verify transactions?
Why does bitcoin use signatures to verify transactions in order for them to be broadcasted and mined and is there any other method that could be used instead of signatures?

Any viable system of value needs this simple property: only the rightful owner of the asset is able to spend it. For example: if you owned some bitcoins, but someone else was easily able to spend them, then that wouldn't be a very trustworthy system now would it?
So, we need a system where someone can prove that they are the rightful owner! A naive way to implement this would be to create a secret password that locks your funds, so that you have to attach your secret password to the transaction, in order to spend them.
But there is a problem with this: once you attach your password, anyone else monitoring the system could see your transaction, and just copy the secret onto a new transaction, which sends your money to the attacker!
What is a solution? Using a cryptographic signature allows the owner of a private key to prove that they have knowledge of the secret, without revealing the secret itself! Everyone else can check the signature, and know that it must have been made by the private key for that address, and they can do this without knowing what the private key actually is.
Plus, the signature changes depending on the data being signed, so an attacker cannot just copy the signature to a new transaction to steal the funds (like in the example above). If you use the same private key to sign two distinct transactions, the signature data will be different for each one.

is there any other method that could be used instead of signatures?

Perhaps there is, but using cryptographic signatures works just fine, and the underlying cryptography has been studied and tested extensively over the last few decades, so we can be fairly confident it works well.
Many other common authentication schemes require some sort of centralized store of data (eg, user accounts for a website, that are accessible by password), so a decentralized cryptocurrency network has some special considerations in this regard. Cryptographic signatures are used in a LOT of different applications though, they are not specific to bitcoin or cryptocurrencies, they are just a useful cryptographic tool in general.

Is there any other way to verify transactions currently without using signatures?

No, obviously not. Without digital signature the system is not secure.