Szyfrowanie, szyfrowanie
Bitcoin kojarzy się większości osób z przelewaniem.. bitcoina. Wysyłasz transakcję, ktoś ją odbiera. W rzeczywistości sieci takie jak Bitcoin SV potrafią znacznie więcej. Każda transakcja może nieść ze sobą dane. A skoro dane - to również wiadomości.

Wyobraź sobie, że możesz wysłać komuś zaszyfrowaną wiadomość: bez serwera, bez pośrednika, bez możliwości ocenzurowania i zapisaną na zawsze w blockchainie. Mechanizm, który to umożliwia, nazywa się OP_RETURN (pisałem o nim tutaj). W tym wpisie pokażę, jak wykorzystać OP_RETURN jako kanał komunikacji - zapisując zaszyfrowaną wiadomość, którą odczytać może tylko wybrany odbiorca. Całość zrobimy w Pythonie, używając biblioteki py-sdk-bsv.
Mógłbyś zapytać: ale po co ktoś miałby prowadzić komunikację, na publicznym blockchainie, szyfrując wiadomości?
Zaszyfrowana wiadomość w OP_RETURN ma kilka unikalnych cech:
- niezmienność
- globalna dostępność
- brak cenzury
- prywatność
To połączenie jest bardzo rzadkie. Możesz wysyłać zaszyfrowane wiadomości komuś innemu albo opublikować zaszyfrowaną wiadomość lub nawet wielotomowe historie, wysyłając je na jakiś swój (pusty) nowo utworzony adres, a po kilku latach ujawnić klucz publicznie i treści z nim związane. Możesz też wysłać sam sobie taką zaszyfrowaną wiadomość, podpisać się, zapisać prototyp, pomysły, gromadzić dowody lub prowadzić dziennik a gdy przyjdzie potrzeba, udowodnić to już według formalnych procedur (które z pewnością kiedyś nadejdą).
Zaczniemy od wykorzystania poprzednich skryptów, bo tak naprawdę nic nowego nam nie dojdzie - no może kilka linijek :) Na początek trochę importów.
*Jedno zastrzeżenie - dodajemy w naszym imporcie EncryptedMessage i WhatsOnChainBroadcaster, zmienimy go też w linii kodu z rozgłoszeniem transakcji.
import nest_asyncio
nest_asyncio.apply()
import asyncio
from bsv import PrivateKey, P2PKH, ARC, Transaction, TransactionInput, TransactionOutput, OpReturn, WhatsOnChainBroadcaster
from bsv.encrypted_message import EncryptedMessage
import requests
import json
Teraz kilka linijek na szybkie zrozumienie szyfrowania:moj_wif = "xxxxxxxxxxxxxxxxxxx"
klucz_prywatny = PrivateKey(moj_wif)
address_testnet = klucz_prywatny.address(network="testnet")
url = f"https://api.whatsonchain.com/v1/bsv/test/address/{address_testnet}/confirmed/balance"
response = requests.get(url)
data = response.json()
saldo = data['confirmed']
# Szyfrowanie / Odszyfrowanie
nadawca = klucz_prywatny # Nadawca
odb_wif = "xxxxxxxxxx" # Odbiorca
odbiorca = PrivateKey(odb_wif)
message = "To nasza wiadomość"
encrypted = nadawca.public_key().encrypt_text(message)
print(f"Wiadomość od A: {message}")
print(f"Zaszyfrowana wiadomość A: {encrypted}")
print(f"Odszyfrowana wiadomość przez B: {odbiorca.decrypt_text(encrypted)}")
Teraz wykonuję kod 4 razy. Zobacz co się stało:
# Szyfrowanie / Odszyfrowanie
nadawca = klucz_prywatny # Nadawca
odb_wif = "xxxxxxxxxx"
odbiorca = PrivateKey(odb_wif)
message = b"To nasza wiadomość"
encrypted = EncryptedMessage.encrypt(
message=message,
sender=nadawca,
recipient=odbiorca.public_key())
print(f"Wiadomość od A: {message}")
print(f"Zaszyfrowana wiadomość A: {encrypted}")
try:
decrypted = EncryptedMessage.decrypt(
message=encrypted,
recipient=odbiorca) # w 3 wykonaniu zamieniam na nadawcę :)
print(f"Odszyfrowana wiadomość przez B: {decrypted.decode()}")
except Exception as e:
print("Nie udało się odszyfrować wiadomości")
print("Powód:", str(e))
Co się teraz zadzieje jak wykonany kod? Sprawdźmy!
Rozgłoszenie transakcji z wiadomością w sieci Bitcoin SV.
address_odbiorcy = odbiorca.address(network="testnet")
url = f"https://api.whatsonchain.com/v1/bsv/test/address/{address_testnet}/unspent/all"
response = requests.get(url)
data = response.json()
niewydane_utxo = len(data['result'])
print(f"Adres testnet : {address_testnet}")
print(f"Saldo : {saldo} satoshi / {saldo / 100000000} BSV")
print(f"Ilość niewydanych UTXO: {niewydane_utxo}")
for i in data['result']:
print(f"Index : {i['tx_pos']}, Hash : {i['tx_hash']}, Satoshi : {i['value']}")
txid = data['result'][1]['tx_hash']
tx_pos = data['result'][1]['tx_pos']
print(f"\nTransakcja z niewydanym UTXO: {txid}")
print(f"Indeks transakcji: {tx_pos}\n")
url = f"https://api.whatsonchain.com/v1/bsv/test/tx/{txid}/hex"
response = requests.get(url)
tx_hex = response.text
print(f"HEX : {tx_hex}\n")
op_ret = OpReturn()
block_script = op_ret.lock([encrypted])
do_wyslania = 2 # Poinformujemy odbiorcę, że ma jakieś nowe UTXO :)
async def create_and_broadcast_transaction():
tx = Transaction()
tx.add_input(TransactionInput(
source_transaction = Transaction.from_hex(tx_hex),
source_output_index = tx_pos,
unlocking_script_template = P2PKH().unlock(klucz_prywatny)))
tx.add_output(TransactionOutput(
locking_script=P2PKH().lock(address_odbiorcy),
satoshis=do_wyslania)) # <-- 2 satoshi
tx.add_output(TransactionOutput(
locking_script = block_script,
satoshis = 0))
tx.add_output(TransactionOutput(
locking_script = P2PKH().lock(address_testnet),
change = True))
tx.fee()
tx.sign()
response = await tx.broadcast(WhatsOnChainBroadcaster("test"))
print(f"Status rozgłoszenia: {response.status}")
try:
print(f"Opis rozgłoszenia: {response.description}")
except:
pass
print(f"ID transakcji: {tx.txid()}")
if __name__ == "__main__":
asyncio.run(create_and_broadcast_transaction())
Uruchamiamy kod, nasza transakcja została rozgłoszona w sieci, możemy zobaczyć nasz OP_RETURN, 2 satoshi jako poinformowanie adresu i naszą resztę:
Pobranie i odszyfrowanie wiadomości z blockchain.
from bsv.encrypted_message import EncryptedMessage
import requests
import json
odb_wif = "klucz_prywatny_odbiorcy" # Odbiorca
odbiorca = PrivateKey(odb_wif)
address_odbiorcy = odbiorca.address(network="testnet")
url = f"https://api.whatsonchain.com/v1/bsv/test/address/{address_odbiorcy}/unspent/all"
response = requests.get(url)
data = response.json()
niewydane_utxo = len(data['result'])
print(f"Adres testnet : {address_odbiorcy}")
print(f"Ilość niewydanych UTXO: {niewydane_utxo}")
for i in data['result']:
print(f"Index : {i['tx_pos']}, Hash : {i['tx_hash']}, Satoshi : {i['value']}")
txid = input("Wybierz UTXO gdzie siedzi 2 satoshi:") # <-- Tu wkleisz swoje txid
url = f"https://api.whatsonchain.com/v1/bsv/test/tx/hash/{txid}"
response = requests.get(url)
data = response.json()
wiadomosc = data['vout'][1]['scriptPubKey']['hex']
data = bytes.fromhex(wiadomosc)
payload = data[3:] # <-- ucinamy 3 pierwsze bajty
try:
decrypted = EncryptedMessage.decrypt(
message=payload,
recipient=odbiorca)
print(f"Odszyfrowana wiadomość przez B z Blockchain: {decrypted.decode()}")
except Exception as e:
print("Nie udało się odszyfrować wiadomości")
print("Powód:", str(e))Po uruchomieniu kodu mamy taki oto wynik:
**Gwarantuję Ci niezmienność moich treści**
Hash artykułu:
ID transakcji: sprawdź OP_RETURN i porównaj jego hash
Komentarze
Prześlij komentarz