Skip to content

Repository files navigation

bsvlib

buildcodecovPyPI versionPython versionsMIT license

A Bitcoin SV (BSV) Python Library that is extremely simple to use but more.

  • MAINNET and TESTNET supported
  • P2PKH, P2PK, and bare-multisig supported
  • All the SIGHASH flags supported
  • Additional script types can be customized
  • WhatsOnChain API integrated
  • Ability to adapt to different service providers
  • Fully ECDSA implementation
  • ECDH and Electrum ECIES (aka BIE1) implementation
  • HD implementation (BIP-32, BIP-39, BIP-44)

Installation

$ pip install bsvlib

Examples

  1. Send BSV in one line
frombsvlibimportWallet# Donate to aaron67!outputs= [('1HYeFCE2KG4CW4Jwz5NmDqAZK9Q626ChmN', 724996)]
print(Wallet(['YOUR_WIF']).create_transaction(outputs=outputs).broadcast())
  1. Send unspent locked by different keys in one transaction, support OP_RETURN output as well
frombsvlibimportWalletfrombsvlib.constantsimportChainw=Wallet(chain=Chain.TEST)
w.add_key('cVwfreZB3i8iv9JpdSStd9PWhZZGGJCFLS4rEKWfbkahibwhticA')
w.add_key('93UnxexmsTYCmDJdctz4zacuwxQd5prDmH6rfpEyKkQViAVA3me')
print(w.get_balance(refresh=True))
outputs= [('mqBuyzdHfD87VfgxaYeM9pex3sJn4ihYHY', 724), ('mr1FHq6GwWzmD1y8Jxq6rNDGsiiQ9caF7r', 996)]
pushdatas= ['hello', b'world']
print(w.create_transaction(outputs=outputs, pushdatas=pushdatas, combine=True).broadcast())
  1. Operate P2PK
importtimefrombsvlibimportWallet, TxOutput, Transactionfrombsvlib.constantsimportChainfrombsvlib.keysimportKeyfrombsvlib.scriptimportP2pkScriptTypechain=Chain.TESTk=Key('cVwfreZB3i8iv9JpdSStd9PWhZZGGJCFLS4rEKWfbkahibwhticA')
p2pk_output=TxOutput(P2pkScriptType.locking(k.public_key().serialize()), 996, P2pkScriptType())
unspents=Wallet(chain=chain).add_keys([k, '93UnxexmsTYCmDJdctz4zacuwxQd5prDmH6rfpEyKkQViAVA3me']).get_unspents(refresh=True)
t=Transaction(chain=chain).add_inputs(unspents).add_output(p2pk_output).add_change(k.address()).sign()
print('create p2pk:', t.broadcast())
time.sleep(2)
unspents=t.to_unspents(args=[{'private_keys': [k]}] *2)
t=Transaction(chain=chain).add_inputs(unspents).add_change(k.address()).sign()
print('sepnd p2pk:', t.broadcast())
  1. Operate bare-multisig
importtimefromtypingimportList, UnionfrombsvlibimportKey, Unspent, Transaction, TxOutputfrombsvlib.constantsimportChainfrombsvlib.scriptimportBareMultisigScriptType, Scriptfrombsvlib.serviceimportWhatsOnChaink1=Key('cVwfreZB3i8iv9JpdSStd9PWhZZGGJCFLS4rEKWfbkahibwhticA')
k2=Key('93UnxexmsTYCmDJdctz4zacuwxQd5prDmH6rfpEyKkQViAVA3me')
provider=WhatsOnChain(Chain.TEST)
unspents=Unspent.get_unspents(provider=provider, private_keys=[k1])
# a 2-of-3 multi-sig outputpublic_keys: List[Union[str, bytes]] = [k1.public_key().hex(), Key().public_key().hex(), k2.public_key().serialize()]
multisig_script: Script=BareMultisigScriptType.locking(public_keys, 2)
output=TxOutput(out=multisig_script, satoshi=1000, script_type=BareMultisigScriptType())
# create a multi-sig outputt=Transaction(provider=provider).add_inputs(unspents).add_output(output).add_change().sign()
r=t.broadcast()
print(f'create multisig - {r}')
assertr.propagatedtime.sleep(2)
# send the multi-sig unspent we just createdunspent=t.to_unspent(0, private_keys=[k1, k2])
r=Transaction(provider=provider).add_input(unspent).add_change(k1.address()).sign().broadcast()
print(f'spend multisig - {r}')
  1. Sign with different SIGHASH flags, more examples
frombsvlibimportKey, Wallet, Transaction, TxInput, TxOutputfrombsvlib.constantsimportSIGHASH, Chainfrombsvlib.serviceimportWhatsOnChainprovider=WhatsOnChain(Chain.TEST)
private_key=Key('cVwfreZB3i8iv9JpdSStd9PWhZZGGJCFLS4rEKWfbkahibwhticA')
unspents=Wallet([private_key]).get_unspents(refresh=True, provider=provider)
t=Transaction(provider=provider)
t.add_input(TxInput(unspents[0], sighash=SIGHASH.SINGLE_FORKID))
t.add_output(TxOutput(private_key.address(), 135))
t.sign()
# it's good to append any outputs AFTER the first output, no need to sign, can broadcast directlyprint(t.add_change().broadcast())
  1. Sign arbitrary text with private key
frombsvlibimportKey, verify_signed_textprivate_key=Key('L5agPjZKceSTkhqZF2dmFptT5LFrbr6ZGPvP7u4A6dvhTrr71WZ9')
text='hello world'# sign arbitrary text with bitcoin private keyaddress, signature=private_key.sign_text(text)
# verify https://reinproject.org/bitcoin-signature-tool/print(address, signature)
# verifyprint(verify_signed_text(text, address, signature))
  1. Encrypt message with public key, decrypt with the corresponding private key
frombsvlibimportKeyprivate_key=Key('L5agPjZKceSTkhqZF2dmFptT5LFrbr6ZGPvP7u4A6dvhTrr71WZ9')
public_key=private_key.public_key()
plain='hello world'# use public key to encryptencrypted=public_key.encrypt_text(plain)
print(encrypted)
# decrypt with the corresponding private keyprint(private_key.decrypt_text(encrypted))
  1. Process HD wallet derivation

image

fromtypingimportListfrombsvlib.hdimportmnemonic_from_entropy, Xprv, derive_xprvs_from_mnemonic## HD derivation#entropy='cd9b819d9c62f0027116c1849e7d497f'# snow swing guess decide congress abuse session subway loyal view false zebramnemonic: str=mnemonic_from_entropy(entropy)
print(mnemonic)
keys: List[Xprv] =derive_xprvs_from_mnemonic(mnemonic, path="m/44'/0'/0'", change=1, index_start=0, index_end=5)
forkeyinkeys:
print(key.address(), key.private_key().wif())
## random mnemonic#print()
print(mnemonic_from_entropy())
print(mnemonic_from_entropy(lang='en'))
print(mnemonic_from_entropy(lang='zh-cn'))

Credits

Donation

If you like my work or have found this library useful, feel free to donate me a cup of coffee.

Every little satoshi helps. 👏

1HYeFCE2KG4CW4Jwz5NmDqAZK9Q626ChmN

About

Bitcoin SV (BSV) Python Library

Resources

Stars

37 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages