
Lập trình PyCardano: Xây Dựng, Ký và Gửi Giao Dịch ADA Đầu Tiên
Chào mừng các bạn quay trở lại với series Lập trình PyCardano! Ở bài học trước, chúng ta đã lấy thành công một ít Test ADA (tADA) từ Faucet và học cách truy vấn số dư bằng Python. Tiền đã nằm trong ví, và hôm nay là khoảnh khắc mong chờ nhất: Chúng ta sẽ chính thức viết chương trình để “tiêu” số tiền đó bằng cách chuyển ADA từ ví A sang ví B!
Trong bài viết này, bạn sẽ nắm vững quy trình cốt lõi của một giao dịch trên blockchain, làm quen với công cụ mạnh mẽ TransactionBuilder, và hiểu rõ cơ chế “tiền thối lại” độc đáo của Cardano.
1. Quy trình 3 bước của một giao dịch (Build – Sign – Submit)
Bất kỳ giao dịch nào trên mạng lưới Cardano cũng đều phải trải qua 3 bước bắt buộc sau:
-
Build (Xây dựng): Đây là bước phức tạp nhất. Bạn phải gom các mảnh tiền (UTxO) đầu vào, định nghĩa số tiền và người nhận ở đầu ra, sau đó tính toán phí mạng (Fee) một cách chính xác. Rất may, PyCardano sẽ làm hộ chúng ta phần khó nhất này.
-
Sign (Ký xác nhận): Sử dụng Private Key (Khóa riêng tư) của bạn để ký vào giao dịch. Bước này giống như việc bạn đóng dấu mộc đỏ để khẳng định: “Tôi là chủ sở hữu hợp pháp của số tiền này và tôi đồng ý chuyển nó đi”.
-
Submit (Gửi): Đẩy gói tin đã được ký hoàn chỉnh lên mạng lưới toàn cầu thông qua các nhà cung cấp như Blockfrost hoặc Ogmios.
2. Chuẩn bị Người gửi (Sender) và Người nhận (Receiver)
Để thực hành, bạn cần chuẩn bị 2 địa chỉ ví trên mạng Testnet (Preprod).
-
Sender: Chính là chiếc ví bạn đã tạo và nhận Faucet ở các bài trước. Chúng ta cần nạp Private Key của ví này vào code để ký giao dịch.
-
Receiver: Bạn có thể tạo một ví mới, mượn địa chỉ ví của bạn bè, hoặc đơn giản là tự gửi lại cho chính mình (nhưng nhớ dùng một địa chỉ nhận khác để dễ quan sát).
Hãy tạo một file Python mới tên là send_ada.py và bắt đầu:
from pycardano import (
BlockFrostChainContext,
TransactionBuilder,
TransactionOutput,
PaymentSigningKey
)
# 1. Khởi tạo Context kết nối mạng
context = BlockFrostChainContext(
project_id="preprod_your_api_key_here",
base_url="https://cardano-preprod.blockfrost.io/api"
)
# 2. Setup Người gửi (Sender)
# Nạp Private Key để ký (Có thể lấy từ file .skey hoặc dẫn xuất từ HDWallet bài trước)
sender_sk = PaymentSigningKey.load("payment.skey")
sender_address = "addr_test1qyour_sender_address_here..."
# 3. Setup Người nhận (Receiver)
receiver_address = "addr_test1qyour_receiver_address_here..."
3. TransactionBuilder và Cơ chế “Change Address”
Trong mô hình tài khoản (Account Model) như Ethereum, nếu bạn có 100 ETH và gửi đi 10 ETH, hệ thống chỉ cần làm phép trừ đơn giản.
Nhưng Cardano sử dụng mô hình EUTxO. Hãy tưởng tượng bạn đi chợ mua mớ rau giá 10k bằng một tờ tiền 100k.
-
Bạn đưa tờ 100k (Đây gọi là Input).
-
Bà bán rau nhận 10k (Đây là Output 1).
-
Bạn nhận lại 90k tiền thối (Đây là Output 2, hay còn gọi là Change).
Công cụ TransactionBuilder của PyCardano sinh ra để giúp bạn tự động hóa hoàn toàn quy trình chọn “tờ tiền” (Coin Selection) và tính toán “tiền thối lại” này.
# 4. Khởi tạo Builder (Truyền context vào để hệ thống biết biểu phí mạng hiện tại)
builder = TransactionBuilder(context)
# 5. Khai báo đầu vào (Input)
# Chỉ cần cung cấp địa chỉ ví, PyCardano sẽ tự động tìm các UTxO hợp lệ để tiêu
builder.add_input_address(sender_address)
# 6. Khai báo đầu ra (Output)
# Gửi 5 ADA (Lưu ý: 1 ADA = 1,000,000 Lovelace)
send_amount = 5_000_000
builder.add_output(
TransactionOutput(address=receiver_address, amount=send_amount)
)
4. Thực thi: Build, Sign và Submit
Bây giờ, chúng ta sẽ gộp tất cả lại, dùng Private Key để ký và đẩy lên mạng lưới. Hàm build_and_sign là một hàm tiện lợi cực kỳ mạnh mẽ: nó tự động tính toán biểu phí (fee) và tự động trừ phí đó vào phần tiền thối lại của bạn.
print("Đang xây dựng giao dịch...")
# 7. Build và Sign cùng lúc
# - signing_keys: Danh sách chìa khóa dùng để mở khóa các UTxO đầu vào
# - change_address: Chỉ định nơi nhận lại "tiền thối" (thường là trả về lại Sender)
signed_tx = builder.build_and_sign(
signing_keys=[sender_sk],
change_address=sender_address
)
print("Giao dịch đã được ký thành công!")
print(f"ID Giao dịch (TxHash): {signed_tx.id}")
print(f"Phí mạng đã trả: {signed_tx.transaction_body.fee / 1000000} ADA")
# 8. Submit lên mạng lưới
context.submit_tx(signed_tx)
print("Đã gửi giao dịch lên mạng lưới Cardano thành công!")
5. Kiểm tra giao dịch và Xử lý lỗi thường gặp
Sau khi chạy đoạn code trên, console sẽ in ra một chuỗi ID Giao dịch (TxHash). Hãy copy mã này, truy cập vào Preprod Cardanoscan và dán vào ô tìm kiếm.
Ban đầu, giao dịch có thể ở trạng thái chờ (Mempool). Hãy kiên nhẫn đợi khoảng 20 – 40 giây để block mới được mạng lưới đóng lại. Khi thấy số Confirmations tăng lên, giao dịch của bạn đã chính thức được ghi nhận vĩnh viễn trên sổ cái!
🛠 Các lỗi phổ biến (Troubleshooting):
-
Lỗi
ValueNotSufficient/InsufficientFunds: Ví của bạn không đủ tiền trả cho số lượng gửi đi cộng với phí mạng. Cũng có thể do số UTxO bạn định dùng đang bị “kẹt” ở một giao dịch khác vừa gửi chưa được xác nhận. Hãy đợi Block mới đóng và thử lại. -
Lỗi
MinLovelace: Bạn đang cố gửi một số tiền quá nhỏ (ví dụ 0.5 ADA). Để chống spam, Cardano yêu cầu mỗi UTxO tồn tại trên mạng lưới phải chứa một lượng ADA tối thiểu (khoảng 1 – 1.5 ADA). Hãy thử gửi ít nhất 2 ADA. -
Lỗi
Key Mismatch: Bạn dùng địa chỉ của ví A làm đầu vào (Input) nhưng lại truyền nhầm Signing Key của ví B vào hàm ký. Hãy kiểm tra lại sự đồng nhất của các biến!
Lời kết: Xin chúc mừng! Bạn vừa chính thức thực hiện việc thay đổi trạng thái của một sổ cái phi tập trung toàn cầu bằng những dòng code Python đầu tiên.
Ở bài học tiếp theo, chúng ta sẽ nâng cấp độ khó lên một chút: Cách gửi giao dịch kèm theo siêu dữ liệu (Metadata/Ghi chú) và cách Mint (Đúc) các Native Assets (Token/NFT) mang dấu ấn cá nhân của bạn.
