Skip to content

Instantly share code, notes, and snippets.

@mflaxman
mflaxman / wallet ID thoughts.txt
Created April 12, 2021 17:03
Encoding Proposal for Bitcoin Multisig Address as Wallet ID
Separately, I'm now conflicted on whether the first address should be encoded in some non-address format, so that there is no ambiguity for end-users.
Here's one imperfect solution that would be trivial for any bitcoin wallet developer to implement:
1. Fetch receive address 2,147,483,647 (`2^31 -1`) for the descriptor record, let's call this address X
2. Calculate the double-sha256 digest of X in hex
3. Truncate to something more reasonable, perhaps 160 bits (40 characters in hex)
4. Prepend some identifier for UX, I suggest `MW-` (multisig wallet).
I find code much clearer as a way to communicate, here is what that looks like in python:
```
@mflaxman
mflaxman / blinding.py
Last active November 20, 2020 20:57
Using a BIP32 Path as a Blinding Factor for 1 key in your p2wsh - RESEARCH IDEA, DO NOT USE
from hashlib import sha256
# https://bitcoin.stackexchange.com/questions/92056/what-is-the-max-allowed-depth-for-bip32-derivation-paths
MAX_BIP32 = 2 ** 31 - 1
def encode(num, base=MAX_BIP32):
result = []
while num > 0:
num, remainder = divmod(num, base)
@mflaxman
mflaxman / trezor_recovery.py
Created August 15, 2017 13:50
Proof you can recover your Trezor funds without a Trezor (if it breaks and/or the company goes out of business)
from bitmerchant.wallet import Wallet
from mnemonic import Mnemonic
# put in whatever Trezor generates for you here (or backup from this empty/insecure one as a test)
mnemonic = 'clean health food open blood network differ female lion eagle rough upon update zone antique defense venture uncover mobile charge actress film vocal enough'
passphrase = '' # empty string or whatever you actually choose
path = "m/44'/0'/0'/0/0" # whatever shows up on the UI for that account (everything will start with m/44'/0' since it's bip44)
child = Wallet.from_master_secret(Mnemonic('english').to_seed(mnemonic, passphrase)).get_child_for_path(path)
child.to_address() # '18K9axbPpwqZgngB58nuwsYevL2z6ey4YG' (confirm this matches what Trezor is showing you)
╔══════════════╦══════════════════════════════════════╗
║ BTC Amount ║ Wallet ║
╠══════════════╬══════════════════════════════════════╣
║ < $1k USD ║ Trusted Service ║
║ < $50k USD ║ Breadwallet App ║
║ < $250k USD ║ Hardware Wallet ║
║ < $2 MM USD ║ Electrum on Tails OS (with Airgap) ║
║ > $2 MM USD ║ Bitcoin Core Full Node (with Airgap) ║
╚══════════════╩══════════════════════════════════════╝
@mflaxman
mflaxman / sweep.py
Created September 7, 2017 17:04
Sweep funds from one BTC address to another
from pycoin.tx.tx_utils import create_signed_tx
from pycoin.services.blockcypher import BlockcypherProvider
# inspect your spendables
spendables = [x.as_text() for x in BlockcypherProvider().spendables_for_address(address=FROM_ADDRESS)]
# sign TX
signed_tx = create_signed_tx(
spendables=spendables,
payables=[TO_ADDRESS],