def test_htlc_init(): htlc = HTLC(network="testnet") htlc.init(secret_hash=sha256("BooOoom!".encode()).hex(), recipient_address="mrmtGq2HMmqAogSsGDjCtXUpxrb7rHThFH", sender_address="mqLyrNDjpENRMZAoDpspH7kR9RtgvhWzYE", sequence=5) htlc_bytecode = htlc.bytecode() assert htlc_bytecode == "63aa20b9b9a0c47ecee7fd94812573a7b14afa02ec250dbdb5875a55c4d02367" \ "fcc2ab8876a9147b7c4431a43b612a72f8229935c469f1f690365888ac6755b2" \ "7576a9146bce65e58a50b97989930e9a4ff1ac1a77515ef188ac68" htlc_opcode = htlc.opcode() assert htlc_opcode == "OP_IF OP_HASH256 b9b9a0c47ecee7fd94812573a7b14afa02ec250dbdb5875a5" \ "5c4d02367fcc2ab OP_EQUALVERIFY OP_DUP OP_HASH160 7b7c4431a43b612a7" \ "2f8229935c469f1f6903658 OP_EQUALVERIFY OP_CHECKSIG OP_ELSE OP_5 OP" \ "_CHECKSEQUENCEVERIFY OP_DROP OP_DUP OP_HASH160 6bce65e58a50b979899" \ "30e9a4ff1ac1a77515ef1 OP_EQUALVERIFY OP_CHECKSIG OP_ENDIF" htlc_address = htlc.address() assert str(htlc_address) == "2N729UBGZB3xjsGFRgKivy4bSjkaJGMVSpB" htlc_hash = htlc.hash() assert str(htlc_hash) == "a914971894c58d85981c16c2059d422bcde0b156d04487"
def htlc(secret_hash, recipient_address, sender_address, sequence, network): try: click.echo( HTLC(network=network).init(secret_hash=secret_hash, recipient_address=recipient_address, sender_address=sender_address, sequence=sequence).bytecode()) except Exception as exception: click.echo(click.style("Error: {}").format(str(exception)), err=True) sys.exit()
def fund(sender_address, amount, bytecode, version, network): try: click.echo( FundTransaction(version=version, network=network).build_transaction( wallet=Wallet(network=network).from_address( address=sender_address), htlc=HTLC(network=network).from_bytecode( bytecode=bytecode), amount=int(amount)).unsigned_raw()) except Exception as exception: click.echo(click.style("Error: {}").format(str(exception)), err=True) sys.exit()
recipient_p2pkh = recipient_wallet.p2pkh() print("Recipient P2PKH:", recipient_p2pkh) recipient_p2sh = recipient_wallet.p2sh() print("Recipient P2SH:", recipient_p2sh) recipient_balance = recipient_wallet.balance() print("Recipient Balance:", recipient_balance) # recipient_unspent = recipient_wallet.unspent() # for index, unspent in enumerate(recipient_unspent): # print("Recipient %d Unspent" % index, unspent) print("=" * 10, "Hash Time Lock Contract (HTLC) between Sender and Recipient") # Initialize Hash Time Lock Contract (HTLC) htlc = HTLC(network=network).init(secret_hash=sha256( "Hello Meheret!".encode()).hex(), recipient_address=recipient_address, sequence=100, sender_address=sender_address) htlc_bytecode = htlc.bytecode() print("HTLC Bytecode:", htlc_bytecode) htlc_opcode = htlc.opcode() print("HTLC OP_Code:", htlc_opcode) htlc_address = htlc.address() print("HTLC Address:", htlc_address) htlc_hash = htlc.hash() print("HTLC Hash:", htlc_hash) print("=" * 10, "Unsigned Fund Transaction") # Initialization fund transaction
# Initialize sender bitcoin wallet sender_wallet = Wallet(network=network) sender_wallet.from_passphrase(sender_passphrase, False) sender_private_key = sender_wallet.private_key() sender_public_key = sender_wallet.public_key() sender_address = sender_wallet.address() # Initialize recipient bitcoin wallet recipient_wallet = Wallet(network=network) recipient_wallet.from_address("muTnffLDR5LtFeLR2i3WsKVfdyvzfyPnVB") recipient_address = recipient_wallet.address() # Initialize Hash Time Lock Contract (HTLC) htlc = HTLC(network=network).init(secret_hash=sha256( "Hello Meheret!".encode()).hex(), recipient_address=recipient_address, sequence=100, sender_address=sender_address) # Testing bitcoin fund def test_bitcoin_fund(): # Initialization fund transaction unsigned_fund_transaction = FundTransaction(version=2, network=network) # Building fund transaction unsigned_fund_transaction.build_transaction(wallet=sender_wallet, htlc=htlc, amount=10000) assert unsigned_fund_transaction.fee == 678 assert unsigned_fund_transaction.hash(
def test_bytom_htlc_init_validation(): with pytest.raises(ValueError, match="invalid network, only mainnet or testnet"): HTLC(network="unknown") with pytest.raises(ValueError, match="htlc script is none, initialization htlc first"): HTLC(network="testnet").bytecode() with pytest.raises(ValueError, match="htlc script is none, initialization htlc first"): HTLC(network="testnet").opcode() with pytest.raises(ValueError, match="htlc script is none, initialization htlc first"): HTLC(network="testnet").hash() with pytest.raises(ValueError, match="htlc script is none, initialization htlc first"): HTLC(network="testnet").address() with pytest.raises(TypeError, match="secret hash must be string format"): HTLC(network="mainnet").init(int(), str(), str(), int()) with pytest.raises(ValueError, match="invalid secret hash, length must be 64."): HTLC(network="mainnet").init(str(), str(), str(), int()) with pytest.raises(TypeError, match="recipient address must be string format"): HTLC(network="mainnet").init( "3a26da82ead15a80533a02696656b14b5dbfd84eb14790f2e1be5e9e45820eeb", float(), str(), int()) with pytest.raises(AddressError, match=r"invalid .* recipient .* address"): HTLC(network="mainnet").init( "3a26da82ead15a80533a02696656b14b5dbfd84eb14790f2e1be5e9e45820eeb", "2N729UBGZB3xjsGFRgKivy4bSjkaJGMVSpB", str(), int()) with pytest.raises(TypeError, match="sender address must be string format"): HTLC(network="testnet").init( "3a26da82ead15a80533a02696656b14b5dbfd84eb14790f2e1be5e9e45820eeb", "2N729UBGZB3xjsGFRgKivy4bSjkaJGMVSpB", bool(), int()) with pytest.raises(AddressError, match=r"invalid .* sender .* address"): HTLC(network="mainnet").init( "3a26da82ead15a80533a02696656b14b5dbfd84eb14790f2e1be5e9e45820eeb", "1EzQPm2RFqtY7fGpcjVkXvQ9xzEKhDZmWP", "muTnffLDR5LtFeLR2i3WsKVfdyvzfyPnVB", int()) with pytest.raises(TypeError, match="sequence must be integer format"): HTLC(network="testnet").init( "3a26da82ead15a80533a02696656b14b5dbfd84eb14790f2e1be5e9e45820eeb", "2N729UBGZB3xjsGFRgKivy4bSjkaJGMVSpB", "muTnffLDR5LtFeLR2i3WsKVfdyvzfyPnVB", str())
def test_bitcoin_fund_transaction(): unsigned_fund_transaction = FundTransaction(version=2, network=network) unsigned_fund_transaction.build_transaction( wallet=sender_wallet, htlc=HTLC(network=network).init( secret_hash=sha256("Hello Meheret!".encode()).hex(), recipient_address=recipient_wallet.address(), sender_address=sender_wallet.address(), sequence=1000), amount=10_000) assert unsigned_fund_transaction.fee() == 678 assert unsigned_fund_transaction.hash( ) == "f05f2afb0706020cc15b66d63e2fd9d89cfe5ce7a9f458f3a8a6fb3c1849cf20" assert unsigned_fund_transaction.raw( ) == "0200000001ec312e92d8387b15f6238d4918344b62ab147d7f3844dc81e653776fe8b84ef30100000000ffffffff02102700000000000017a9142bb013c3e4beb08421dedcf815cb65a5c388178b87508a0e00000000001976a91464a8390b0b1685fcbf2d4b457118dc8da92d553488ac00000000" assert unsigned_fund_transaction.json() == { 'hex': '0200000001ec312e92d8387b15f6238d4918344b62ab147d7f3844dc81e653776fe8b84ef30100000000ffffffff02102700000000000017a9142bb013c3e4beb08421dedcf815cb65a5c388178b87508a0e00000000001976a91464a8390b0b1685fcbf2d4b457118dc8da92d553488ac00000000', 'txid': 'f05f2afb0706020cc15b66d63e2fd9d89cfe5ce7a9f458f3a8a6fb3c1849cf20', 'hash': 'f05f2afb0706020cc15b66d63e2fd9d89cfe5ce7a9f458f3a8a6fb3c1849cf20', 'size': 117, 'vsize': 117, 'version': 2, 'locktime': 0, 'vin': [{ 'txid': 'f34eb8e86f7753e681dc44387f7d14ab624b3418498d23f6157b38d8922e31ec', 'vout': 1, 'scriptSig': { 'asm': '', 'hex': '' }, 'sequence': '4294967295' }], 'vout': [{ 'value': '0.00010000', 'n': 0, 'scriptPubKey': { 'asm': 'OP_HASH160 2bb013c3e4beb08421dedcf815cb65a5c388178b OP_EQUAL', 'hex': 'a9142bb013c3e4beb08421dedcf815cb65a5c388178b87', 'type': 'p2sh', 'address': '2MwEDybGC34949zgzWX4M9FHmE3crDSUydP' } }, { 'value': '0.00952912', 'n': 1, 'scriptPubKey': { 'asm': 'OP_DUP OP_HASH160 64a8390b0b1685fcbf2d4b457118dc8da92d5534 OP_EQUALVERIFY OP_CHECKSIG', 'hex': '76a91464a8390b0b1685fcbf2d4b457118dc8da92d553488ac', 'type': 'p2pkh', 'address': 'mphBPZf15cRFcL5tUq6mCbE84XobZ1vg7Q' } }] } assert unsigned_fund_transaction.type() == "bitcoin_fund_unsigned" assert unsigned_fund_transaction.unsigned_raw( ) == "eyJmZWUiOiA2NzgsICJyYXciOiAiMDIwMDAwMDAwMWVjMzEyZTkyZDgzODdiMTVmNjIzOGQ0OTE4MzQ0YjYyYWIxNDdkN2YzODQ0ZGM4MWU2NTM3NzZmZThiODRlZjMwMTAwMDAwMDAwZmZmZmZmZmYwMjEwMjcwMDAwMDAwMDAwMDAxN2E5MTQyYmIwMTNjM2U0YmViMDg0MjFkZWRjZjgxNWNiNjVhNWMzODgxNzhiODc1MDhhMGUwMDAwMDAwMDAwMTk3NmE5MTQ2NGE4MzkwYjBiMTY4NWZjYmYyZDRiNDU3MTE4ZGM4ZGE5MmQ1NTM0ODhhYzAwMDAwMDAwIiwgIm91dHB1dHMiOiBbeyJhbW91bnQiOiA5NjM1OTAsICJuIjogMSwgInNjcmlwdCI6ICI3NmE5MTQ2NGE4MzkwYjBiMTY4NWZjYmYyZDRiNDU3MTE4ZGM4ZGE5MmQ1NTM0ODhhYyJ9XSwgIm5ldHdvcmsiOiAidGVzdG5ldCIsICJ0eXBlIjogImJpdGNvaW5fZnVuZF91bnNpZ25lZCJ9" signed_fund_transaction = unsigned_fund_transaction.sign(solver=FundSolver( private_key=sender_wallet.private_key())) assert signed_fund_transaction.fee() == 678 assert signed_fund_transaction.hash( ) == "7e52333d38b7571807caac7971c925dd2c007dbf34a6c46138ff3d0213281d60" assert signed_fund_transaction.raw( ) == "0200000001ec312e92d8387b15f6238d4918344b62ab147d7f3844dc81e653776fe8b84ef3010000006b483045022100b4d4de4c10bec380a9f07019d5232a9af9f0c2321e5efcf33f5326a60378144502203e1ab2ddaac8afade132832e715f055f956d3e730b9d035a4e99ec9dfdc7acfd012103c56a6005d4a8892d28cc3f7265e5685b548627d59108973e474c4e26f69a4c84ffffffff02102700000000000017a9142bb013c3e4beb08421dedcf815cb65a5c388178b87508a0e00000000001976a91464a8390b0b1685fcbf2d4b457118dc8da92d553488ac00000000" assert signed_fund_transaction.json() == { 'hex': '0200000001ec312e92d8387b15f6238d4918344b62ab147d7f3844dc81e653776fe8b84ef3010000006b483045022100b4d4de4c10bec380a9f07019d5232a9af9f0c2321e5efcf33f5326a60378144502203e1ab2ddaac8afade132832e715f055f956d3e730b9d035a4e99ec9dfdc7acfd012103c56a6005d4a8892d28cc3f7265e5685b548627d59108973e474c4e26f69a4c84ffffffff02102700000000000017a9142bb013c3e4beb08421dedcf815cb65a5c388178b87508a0e00000000001976a91464a8390b0b1685fcbf2d4b457118dc8da92d553488ac00000000', 'txid': '7e52333d38b7571807caac7971c925dd2c007dbf34a6c46138ff3d0213281d60', 'hash': '7e52333d38b7571807caac7971c925dd2c007dbf34a6c46138ff3d0213281d60', 'size': 224, 'vsize': 224, 'version': 2, 'locktime': 0, 'vin': [{ 'txid': 'f34eb8e86f7753e681dc44387f7d14ab624b3418498d23f6157b38d8922e31ec', 'vout': 1, 'scriptSig': { 'asm': '3045022100b4d4de4c10bec380a9f07019d5232a9af9f0c2321e5efcf33f5326a60378144502203e1ab2ddaac8afade132832e715f055f956d3e730b9d035a4e99ec9dfdc7acfd01 03c56a6005d4a8892d28cc3f7265e5685b548627d59108973e474c4e26f69a4c84', 'hex': '483045022100b4d4de4c10bec380a9f07019d5232a9af9f0c2321e5efcf33f5326a60378144502203e1ab2ddaac8afade132832e715f055f956d3e730b9d035a4e99ec9dfdc7acfd012103c56a6005d4a8892d28cc3f7265e5685b548627d59108973e474c4e26f69a4c84' }, 'sequence': '4294967295' }], 'vout': [{ 'value': '0.00010000', 'n': 0, 'scriptPubKey': { 'asm': 'OP_HASH160 2bb013c3e4beb08421dedcf815cb65a5c388178b OP_EQUAL', 'hex': 'a9142bb013c3e4beb08421dedcf815cb65a5c388178b87', 'type': 'p2sh', 'address': '2MwEDybGC34949zgzWX4M9FHmE3crDSUydP' } }, { 'value': '0.00952912', 'n': 1, 'scriptPubKey': { 'asm': 'OP_DUP OP_HASH160 64a8390b0b1685fcbf2d4b457118dc8da92d5534 OP_EQUALVERIFY OP_CHECKSIG', 'hex': '76a91464a8390b0b1685fcbf2d4b457118dc8da92d553488ac', 'type': 'p2pkh', 'address': 'mphBPZf15cRFcL5tUq6mCbE84XobZ1vg7Q' } }] } assert signed_fund_transaction.type() == "bitcoin_fund_signed"