Skip to main content

Bài 2: Trái phiếu Zero-Coupon Sử dụng Giao diện Dòng lệnh của Marlowe Runtime

Trước khi chạy sổ ghi chép này, bạn có thể muốn sử dụng chức năng "xóa đầu ra" của Jupyter để xóa kết quả thực hiện trước đó của sổ ghi chép này. Điều đó sẽ làm rõ hơn những gì đã được thực thi trong phiên hiện tại.

Ví dụ về trái phiếu không INTEREST là một hợp đồng Marlowe đơn giản trong đó người cho vay cung cấp tiền gốc cho người đi vay, người này sẽ hoàn trả lại số tiền đó cùng với tiền lãi.

Trong phần trình diễn này, chúng ta sử dụng giao diện dòng lệnh của Marlowe Runtime, marlowe-runtime-cli, để chạy hợp đồng này trên mạng thử nghiệm công khai preprod của Cardano. Hợp đồng Marlowe có thể sử dụng địa chỉ hoặc vai trò token để ủy quyền: ở đây chúng ta sử dụng địa chỉ.

Một video hoạt động thông qua notebook Jupyter này.

Bạn có thể đặt câu hỏi về Marlowe trong kênh #ask-marlowe trên IOG Discord hoặc đăng các vấn đề với bài học này lên danh sách các vấn đề của Bộ công cụ dành cho người mới bắt đầu Marlowe kho lưu trữ github.

Trong Marlowe Playground, hợp đồng có dạng như sau ở định dạng Blockly.

Hợp đồng Marlowe trái phiếu không có phiếu thưởng

Ở định dạng Marlowe, nó xuất hiện dưới dạng

When
[Case
(Deposit
(Address "$LENDER_ADDR")
(Address "$LENDER_ADDR")
(Token "" "")
(ConstantParam "$PRINCIPAL")
)
(Pay
(Address "$LENDER_ADDR")
(Party (Address "$BORROWER_ADDR"))
(Token "" "")
(ConstantParam "$PRINCIPAL")
(When
[Case
(Deposit
(Address "$BORROWER_ADDR")
(Address "$BORROWER_ADDR")
(Token "" "")
(AddValue
(ConstantParam "$INTEREST")
(ConstantParam "$PRINCIPAL")
)
)
(Pay
(Address "$BORROWER_ADDR")
(Party (Address "$LENDER_ADDR"))
(Token "" "")
(AddValue
(ConstantParam "$INTEREST")
(ConstantParam "$PRINCIPAL")
)
Close
)]
(TimeParam "$BORROWER_DEADLINE")
Close
)
)]
(TimeParam "$LENDER_DEADLINE")
Close

Chuẩn bị

Xem Chuẩn bị để biết thông tin về cách thiết lập môi trường của một người để sử dụng hướng dẫn này.

Bài học giả định rằng các biến môi trường sau đây đã được thiết lập.

  • CARDANO_NODE_SOCKET_PATH: vị trí socket của node Cardano.
  • CARDANO_TESTNET_MAGIC: số magic testnet.
  • MARLOWE_RT_HOST: Địa chỉ IP của máy chủ proxy Marlowe Runtime.
  • MARLOWE_RT_PORT: Số cổng cho máy chủ proxy Marlowe Runtime.

Nó cũng giả định rằng các bên Bên cho vay và Bên vay có địa chỉ, khóa ký và tiền.

  • Người cho vay
    • keys/lender.address: Địa chỉ Cardano của người cho vay
    • keys/lender.skey: vị trí ký tệp khóa cho bên cho vay
  • Người vay
    • keys/borrower.address: Địa chỉ Cardano cho người vay
    • keys/borrower.skey: vị trí ký file key cho bên vay

Truy cập vào node Cardano và Runtimes Marlowe

Nếu chúng ta đang sử dụng tiện ích mở rộng Cardano Marlowe Runtime của demeter.run, thì chúng ta đã có quyền truy cập vào Cardano Node và Marlowe Runtime. Các lệnh sau sẽ đặt các biến môi trường cần thiết để sử dụng triển khai docker cục bộ trên các cổng mặc định. Nó cũng sẽ thiết lập một số biến môi trường bổ sung.

    if [[ -z "$MARLOWE_RT_PORT" ]]
then

# Only required for `marlowe-cli` and `cardano-cli`.
export CARDANO_NODE_SOCKET_PATH="$(docker volume inspect marlowe-starter-kit_shared | jq -r '.[0].Mountpoint')/node.socket"
export CARDANO_TESTNET_MAGIC=1 # Note that preprod=1 and preview=2. Do not set this variable if using mainnet.

# Only required for `marlowe-runtime-cli`.
export MARLOWE_RT_HOST="127.0.0.1"
export MARLOWE_RT_PORT=3700

fi

# FIXME: This should have been inherited from the parent environment.
if [[ -z "$CARDANO_NODE_SOCKET_PATH" ]]
then
export CARDANO_NODE_SOCKET_PATH=/ipc/node.socket
fi

# FIXME: This should have been set in the parent environment.
if [[ -z "$CARDANO_TESTNET_MAGIC" ]]
then
export CARDANO_TESTNET_MAGIC=$CARDANO_NODE_MAGIC
fi

case "$CARDANO_TESTNET_MAGIC" in
1)
export "EXPLORER_URL=https://preprod.cardanoscan.io"
;;
2)
export "EXPLORER_URL=https://preview.cardanoscan.io"
;;
*)
# Use `mainnet` as the default.
export "EXPLORER_URL=https://cardanoscan.io"
;;
esac

echo "CARDANO_NODE_SOCKET_PATH = $CARDANO_NODE_SOCKET_PATH"
echo "CARDANO_TESTNET_MAGIC = $CARDANO_TESTNET_MAGIC"
echo "MARLOWE_RT_HOST = $MARLOWE_RT_HOST"
echo "MARLOWE_RT_PORT = $MARLOWE_RT_PORT"
    CARDANO_NODE_SOCKET_PATH = ~/.local/share/containers/storage/volumes/marlowe-starter-kit_shared/_data/node.socket
CARDANO_TESTNET_MAGIC = 1
MARLOWE_RT_HOST = 127.0.0.1
MARLOWE_RT_PORT = 3700

Lưu ý số magic mạng thử nghiệm:

  • preprod = 1
  • xem trước = 2

Địa chỉ và quỹ của bên cho vay

Kiểm tra xem địa chỉ và khóa đã được tạo cho người cho vay chưa. Nếu không, hãy xem phần "Tạo địa chỉ và khóa ký" trong Chuẩn bị.

    LENDER_SKEY=keys/lender.skey
LENDER_ADDR=$(cat keys/lender.address)
echo "LENDER_ADDR = $LENDER_ADDR"
LENDER_ADDR = addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

Kiểm tra xem người cho vay có ít nhất một trăm ADA không.

cardano-cli query utxo --testnet-magic "$CARDANO_TESTNET_MAGIC" --address "$LENDER_ADDR"
                               TxHash                                 TxIx        Amount
--------------------------------------------------------------------------------------
8461a35e612b38d4cb592e4ba1b7f13c2ff2825942d66e7200acc575cd4c8f1c 1 1000000000 lovelace + TxOutDatumNone

Người ta có thể xem địa chỉ trên Cardano explorer. Đôi khi phải mất ba mươi giây hoặc lâu hơn để giao dịch hiển thị trong explorer.

echo "$EXPLORER_URL"/address/"$LENDER_ADDR"

https://preprod.cardanoscan.io/address/addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

Địa chỉ và tiền của người vay

Kiểm tra xem địa chỉ và khóa đã được tạo cho người mượn chưa. Nếu không, hãy xem phần "Tạo địa chỉ và khóa ký" trong Chuẩn bị.

BORROWER_SKEY=keys/borrower.skey
BORROWER_ADDR=$(cat keys/borrower.address)
echo "BORROWER_ADDR = $BORROWER_ADDR"

BORROWER_ADDR = addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

Kiểm tra xem người vay có ít nhất một trăm ADA không.

cardano-cli query utxo --testnet-magic "$CARDANO_TESTNET_MAGIC" --address "$BORROWER_ADDR"

TxHash TxIx Amount
--------------------------------------------------------------------------------------
8461a35e612b38d4cb592e4ba1b7f13c2ff2825942d66e7200acc575cd4c8f1c 2 1000000000 lovelace + TxOutDatumNone

Người ta có thể xem địa chỉ trên Cardano explorer. Đôi khi phải mất ba mươi giây hoặc lâu hơn để giao dịch hiển thị trong explorer.

echo "$EXPLORER_URL"/address/"$BORROWER_ADDR"

https://preprod.cardanoscan.io/address/addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

Thiết kế hợp đồng

Bạn có thể tải xuống hợp đồng trái phiếu không nhận phiếu thưởng từ Marlowe Playground dưới dạng tệp JSON hoặc có thể tạo bằng cách sử dụng Marlowe CLI bằng cách sử dụng lệnh marlowe-cli template.

Ở đây chúng ta tạo hợp đồng bằng Marlowe CLI.

Đầu tiên, đặt tiền gốc của khoản vay là 80 ADA và tiền lãi của nó là 5 ADA.

    ADA=1000000  # 1 ada = 1,000,000 lovelace

PRINCIPAL=$((80 * ADA))
INTEREST=$((5 * ADA))

echo "PRINCIPAL = $PRINCIPAL lovelace"
echo "INTEREST = $INTEREST lovelace"
PRINCIPAL = 80000000 lovelace
INTEREST = 5000000 lovelace

Trên blockchain Cardano, các tham số giao thức yêu cầu mỗi UTxO chứa ít nhất một số ADA. Ở đây chúng ta sẽ bắt đầu hợp đồng với 2 ADA.

MIN_LOVELACE="$((2 * ADA))"
echo "MIN_LOVELACE = $MIN_LOVELACE dây buộc tình yêu"

MIN_LOVELACE = 2000000 ren yêu

Tiếp theo, tìm thời gian hiện tại, được đo bằng POSIX mili giây.

SECOND=1000 # 1 second = 1000 milliseconds
MINUTE=$((60 * SECOND)) # 1 minute = 60 seconds
HOUR=$((60 * MINUTE)) # 1 hour = 60 minutes

NOW="$((`date -u +%s` * SECOND))"
echo NOW = "$NOW" POSIX milliseconds = "`date -d @$((NOW / SECOND))`"

NOW = 1679602725000 POSIX milliseconds = Thu Mar 23 02:18:45 PM MDT 2023

Hợp đồng có thời hạn cho vay và thời hạn trả nợ. Để thuận tiện trong ví dụ này, hãy đặt thời hạn cho tương lai gần.

    LENDER_DEADLINE="$((NOW + 1 * HOUR))"
BORROWER_DEADLINE="$((NOW + 3 * HOUR))"
echo LENDER_DEADLINE = "$LENDER_DEADLINE" POSIX milliseconds = "`date -d @$((LENDER_DEADLINE / SECOND))`"
echo BORROWER_DEADLINE = "$BORROWER_DEADLINE" POSIX milliseconds = "`date -d @$((BORROWER_DEADLINE / SECOND))`"
LENDER_DEADLINE = 1679606325000 POSIX milliseconds = Thu Mar 23 03:18:45 PM MDT 2023
BORROWER_DEADLINE = 1679613525000 POSIX milliseconds = Thu Mar 23 05:18:45 PM MDT 2023

Bây giờ hãy tạo tệp JSON cho hợp đồng, zcb-contract.json.

    marlowe-cli template zcb 
--minimum-ada "$MIN_LOVELACE"
--lender "$LENDER_ADDR"
--borrower "$BORROWER_ADDR"
--principal "$PRINCIPAL"
--interest "$INTEREST"
--lending-deadline "$LENDER_DEADLINE"
--repayment-deadline "$BORROWER_DEADLINE"
--out-contract-file zcb-contract.json
--out-state-file zcb-state.json

Các tùy chọn dòng lệnh khác nhau được mô tả bởi hệ thống trợ giúp.

marlowe-cli template zcb --help
    Usage: marlowe-cli template zcb --minimum-ada INTEGER --lender PARTY
--borrower PARTY --principal INTEGER
--interest INTEGER --lending-deadline TIMEOUT
--repayment-deadline TIMEOUT

Create a zero-coupon bond.

Available options:
--minimum-ada INTEGER Lovelace that the lender contributes to the initial
state.
--lender PARTY The lender.
--borrower PARTY The borrower.
--principal INTEGER The principal, in lovelace.
--interest INTEGER The interest, in lovelace.
--lending-deadline TIMEOUT
The lending deadline. POSIX milliseconds or duration:
`INTEGER[s|m|d|w|h]`.
--repayment-deadline TIMEOUT
The repayment deadline. POSIX milliseconds or
duration: `INTEGER[s|m|d|w|h]`.
-h,--help Show this help text

Kiểm tra hợp đồng

Xem tệp hợp đồng dưới dạng YAML.

json2yaml zcb-hợp đồng.json
    timeout: 1679606325000
timeout_continuation: close
when:
- case:
deposits: 80000000
into_account:
address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck
of_token:
currency_symbol: ''
token_name: ''
party:
address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck
then:
from_account:
address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck
pay: 80000000
then:
timeout: 1679613525000
timeout_continuation: close
when:
- case:
deposits:
add: 80000000
and: 5000000
into_account:
address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d
of_token:
currency_symbol: ''
token_name: ''
party:
address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d
then:
from_account:
address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d
pay:
add: 80000000
and: 5000000
then: close
to:
party:
address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck
token:
currency_symbol: ''
token_name: ''
to:
party:
address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d
token:
currency_symbol: ''
token_name: ''

Cũng xem trạng thái ban đầu của hợp đồng. Lưu ý rằng Runtimes Marlowe ghi đè trạng thái này bằng trạng thái mà nó tạo.

json2yaml zcb-state.json
    accounts:
- - - address: addr_test1vz3w7jtrmx550r4eqfqxnka8c9r763z9hxc6s3hc5wl68qq0kxt5e
- currency_symbol: ''
token_name: ''
- 2000000
boundValues: []
choices: []
minTime: 1

[Không bắt buộc, nhưng nên dùng] Kiểm tra mức độ an toàn của hợp đồng

Nếu chúng ta đang chạy hợp đồng trên Cardano mainnet, thì chúng ta muốn kiểm tra tính an toàn của nó trước khi tạo nó, để không có khả năng chúng ta có thể mất tiền.

Dưới đây là các bước để kiểm tra mức độ an toàn của hợp đồng:

  1. Hiểu Ngôn ngữ Marlowe.
  2. Hiểu [Mô hình UTxO mở rộng] của Cardano(https://docs.cardano.org/learn/eutxo-explainer).
  3. Đọc và hiểu Hướng dẫn về các phương pháp hay nhất của Marlowe.
  4. Đọc và hiểu Hướng dẫn bảo mật của Marlowe.
  5. Sử dụng Marlowe Playground để gắn cờ cảnh báo, thực hiện phân tích tĩnh và mô phỏng hợp đồng.
  6. Sử dụng Marlowe CLI's công cụ marlowe-cli run analysis để nghiên cứu xem hợp đồng có thể chạy trên mạng Cardano hay không.
  7. Chạy tất cả đường dẫn thực thi của hợp đồng trên Cardano testnet.

Ở đây, chúng ta sẽ thực hiện bước 6. Đầu tiên, chúng ta gộp hợp đồng và trạng thái ban đầu của nó vào một tệp duy nhất.

marlowe-cli run initialize \
--permanently-without-staking \
--contract-file zcb-contract.json \
--state-file zcb-state.json \
--out-file zcb-marlowe.json

Bây giờ chúng ta phân tích hợp đồng và đường dẫn thực hiện của nó.

marlowe-cli chạy phân tích  
--marlowe-file zcb-marlowe.json
LNote that path-based analysis ignore the initial state of the contract and instead start with an empty state.
Starting search for execution paths . . .
. . . found 3 execution paths.
- Preconditions:
Duplicate accounts: []
Duplicate bound values: []
Duplicate choices: []
Invalid account parties: []
Invalid account tokens: []
Invalid choice parties: []
Invalid roles currency: false
Non-positive account balances: []
- Role names:
Blank role names: false
Invalid role names: []
- Tokens:
Invalid tokens: []
- Maximum value:
Actual: 88
Invalid: false
Maximum: 5000
Percentage: 1.76
Unit: byte
- Minimum UTxO:
Requirement:
lovelace: 1120600
- Execution cost:
Memory:
Actual: 6588250
Invalid: false
Maximum: 14000000
Percentage: 47.058928571428574
Steps:
Actual: 1767311958
Invalid: false
Maximum: 10000000000
Percentage: 17.67311958
- Transaction size:
Actual: 1630
Invalid: false
Maximum: 16384
Percentage: 9.94873046875

Trong báo cáo trên, chúng ta thấy rằng hợp đồng không có bất kỳ giá trị trùng lặp hoặc không hợp lệ nào và nó không vượt quá bất kỳ tham số giao thức nào của blockchain. Cụ thể, hãy lưu ý rằng giá trị MIN_LOVELACE của 2 ADA đã chọn trước đó của chúng ta lớn hơn 1,120600 ADA mà công cụ phân tích cho là cần thiết. Do đó, việc thực hiện bất kỳ đường dẫn nào trong hợp đồng là an toàn.

Giao dịch 1. Tạo Hợp đồng

Lệnh của Marlowe Runtime marlowe-runtime-cli create sẽ tạo giao dịch tạo cho hợp đồng Marlowe. Chúng ta cung cấp cho nó tệp JSON chứa hợp đồng và cho nó biết giá trị MIN_LOVELACE mà chúng ta đã chọn trước đó. Bất kỳ ai cũng có thể tạo hợp đồng, nhưng trong ví dụ này, người cho vay sẽ làm như vậy, vì vậy chúng ta cung cấp địa chỉ của họ để tài trợ cho giao dịch và nhận tiền thay đổi từ đó.

marlowe-runtime-cli tạo --help
Usage: marlowe-runtime-cli create --change-address ADDRESS [-a|--address ADDRESS] 
[--collateral-utxo UTXO] --manual-sign FILE_PATH
[-m|--metadata-file FILE_PATH] [--tags-file FILE_PATH]
[--v1]
[(-r|--role ROLE=ADDRESS) |
--roles-config-file FILE_PATH |
--role-token-policy-id POLICY_ID]
(--core-file FILE_PATH | --contract-file FILE_PATH
[--args-file FILE_PATH |
[--timeout-arg NAME=POSIX_TIMESTAMP]
[--value-arg NAME=INTEGER]]) --min-utxo LOVELACE

Create a new Marlowe Contract

Available options:
--change-address ADDRESS The address to which the change of the transaction
should be sent.
-a,--address ADDRESS An address whose UTXOs can be used as inputs to the
transaction
--collateral-utxo UTXO A UTXO which may be used as a collateral input
--manual-sign FILE_PATH Sign the transaction manually. Writes the CBOR bytes
of the unsigned transaction to the specified file for
manual signing. Use the submit command to submit the
signed transaction.
-m,--metadata-file FILE_PATH
A JSON file containing a map of integer indexes to
arbitrary JSON values that will be added to the
transaction's metadata.
--tags-file FILE_PATH A JSON file containing a map of tags indexes to
optional JSON-encoded metadata values that will be
added to the transaction's 1564 metadata key. Note
that the entire 1564 key will be overridden if also
specified in --metadata-file.
--v1 Run command in Marlowe V1
-r,--role ROLE=ADDRESS The name of a role in the contract with the address
to send the token to
--roles-config-file FILE_PATH
A JSON file containing a map of role token names to a
roles configuration object. The roles configuration
object has two keys, "address" and "metadata", where
"address" is the address to send the newly minted
role token and "metadata" is the CIP-25 metadata
object to associate with the token.
--role-token-policy-id POLICY_ID
The hexadecimal-encoded policy ID of the role tokens
for this contract. This option is used to support
role tokens minted in a separate transaction.
--core-file FILE_PATH A file containing the Core Marlowe JSON definition of
the contract to create.
--contract-file FILE_PATH
A file containing the Extended Marlowe JSON
definition of the contract to create.
--args-file FILE_PATH A file containing the Extended Marlowe arguments to
apply to the contract.
--timeout-arg NAME=POSIX_TIMESTAMP
The name of a timeout parameter in the contract and a
value to assign to it (in POSIX milliseconds).
--value-arg NAME=INTEGER The name of a numeric parameter in the contract and a
value to assign to it.
--min-utxo LOVELACE An amount which should be used as min ADA requirement
for the Contract UTxO.
-h,--help Show this help text
    CONTRACT_ID=$(
marlowe-runtime-cli create \
--core-file zcb-contract.json \
--min-utxo "$MIN_LOVELACE" \
--change-address "$LENDER_ADDR" \
--manual-sign tx-1.unsigned \
| jq -r 'fromjson | .contractId' \
)
echo "CONTRACT_ID = $CONTRACT_ID"
CONTRACT_ID = 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895#1

Marlowe Runtime sử dụng UTxO (sáng tạo) đầu tiên của hợp đồng để xác định nó trong suốt vòng đời của nó.

Kết quả của việc xây dựng giao dịch là mã định danh cho hợp đồng và tệp tx-1.unsigned, chứa giao dịch chưa được ký của Cardano để tạo hợp đồng, ở định dạng phong bì văn bản.

json2yaml tx-1.unsigned
    cborHex: 86a400818258208461a35e612b38d4cb592e4ba1b7f13c2ff2825942d66e7200acc575cd4c8f1c010182a200581d601b120d7221aa5e7db58fd8e0753e156cf8c38742546a907e8104cc59011a3b793fffa300581d702ed2631dbb277c84334453c5c437b86325d371f0835a28b910a91a6e011a001e84800282005820a3d7e66932dd99e0a1ca6eb6f3f72d1ac2810f04f62571ed817f9559ad12feb1021a000305810b58206f2e3fee174fcd550f939e9badb11bf3cf549203070c67bc7ddc376926f9f98d9fff81d8799fd8799f40ffd8799fa1d8799fd8799fd87980d8799fd8799f581c1b120d7221aa5e7db58fd8e0753e156cf8c38742546a907e8104cc59ffd87a80ffffd8799f4040ffff1a001e8480a0a000ffd87c9f9fd8799fd8799fd8799fd87980d8799fd8799f581c1b120d7221aa5e7db58fd8e0753e156cf8c38742546a907e8104cc59ffd87a80ffffd8799fd87980d8799fd8799f581c1b120d7221aa5e7db58fd8e0753e156cf8c38742546a907e8104cc59ffd87a80ffffd8799f4040ffd87a9f1a04c4b400ffffd87a9fd8799fd87980d8799fd8799f581c1b120d7221aa5e7db58fd8e0753e156cf8c38742546a907e8104cc59ffd87a80ffffd87a9fd8799fd87980d8799fd8799f581c4959d439bd61c63c94a102be0defd6a54b36071d6789f05b7b0224a1ffd87a80ffffffd8799f4040ffd87a9f1a04c4b400ffd87c9f9fd8799fd8799fd8799fd87980d8799fd8799f581c4959d439bd61c63c94a102be0defd6a54b36071d6789f05b7b0224a1ffd87a80ffffd8799fd87980d8799fd8799f581c4959d439bd61c63c94a102be0defd6a54b36071d6789f05b7b0224a1ffd87a80ffffd8799f4040ffd87c9fd87a9f1a04c4b400ffd87a9f1a004c4b40ffffffd87a9fd8799fd87980d8799fd8799f581c4959d439bd61c63c94a102be0defd6a54b36071d6789f05b7b0224a1ffd87a80ffffd87a9fd8799fd87980d8799fd8799f581c1b120d7221aa5e7db58fd8e0753e156cf8c38742546a907e8104cc59ffd87a80ffffffd8799f4040ffd87c9fd87a9f1a04c4b400ffd87a9f1a004c4b40ffffd87980ffffff1b0000018710c47c08d87980ffffffff1b0000018710569f08d87980ffff80f5f6
description: ''
type: TxBodyBabbage

Có nhiều cách để ký và gửi giao dịch Cardano:

  • cardano-cli tại dòng lệnh
  • cardano-wallet tại dòng lệnh hoặc dưới dạng dịch vụ REST
  • cardano-hw-cli đối với ví phần cứng tại dòng lệnh
  • ví CIP-30 tương thích với Babbage trong trình duyệt web
  • marlowe-cli tại dòng lệnh

Để thuận tiện, ở đây chúng ta sử dụng marlowe-cli giao dịch gửi. Người ta có thể phải đợi một phút hoặc lâu hơn để các giao dịch được xác nhận trên blockchain.

    TX_1=$(
marlowe-cli transaction submit \
--tx-body-file tx-1.unsigned \
--required-signer "$LENDER_SKEY" \
--timeout 600 \
| sed -e 's/^TxId "\(.*\)"$/\1/' \
)
echo "TX_1 = $TX_1"
TX_1 = 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895

Người ta có thể xem giao dịch trên Cardano explorer. Đôi khi phải mất ba mươi giây hoặc lâu hơn để giao dịch hiển thị trong explorer.

    echo "$EXPLORER_URL"/giao dịch/"$TX_1?tab=utxo"
https://preprod.cardanoscan.io/transaction/3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895?tab=utxo

Người ta cũng có thể kiểm tra UTxO của hợp đồng bằng cách sử dụng cardano-cli.

cardano-cli query utxo --testnet-magic "$CARDANO_TESTNET_MAGIC" --tx-in "$TX_1#1"

TxHash TxIx Amount
--------------------------------------------------------------------------------------
3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895 1 2000000 lovelace + TxOutDatumHash ScriptDataInBabbageEra "a3d7e66932dd99e0a1ca6eb6f3f72d1ac2810f04f62571ed817f9559ad12feb1"

Xem chi tiết của hợp đồng trên blockchain

Lệnh marlowe-runtime-cli log của Marlowe Runtime có thể tìm nạp hợp đồng từ blockchain và in thông tin về hợp đồng đó.

marlowe-runtime-cli log --show-contract "$CONTRACT_ID"
transaction 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895 (creation)
ContractId: 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895#1
SlotNo: 23920017
BlockNo: 755074
BlockId: 3235ba612d6df4e536da88890b39cc0fbb96ff3313643dd999ef31ed699f3af2
ScriptAddress: addr_test1wqhdyccahvnheppng3fut3phhp3jt5m37zp4529ezz535ms2u9jqv
Marlowe Version: 1

When [
(Case
(Deposit (Address "addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck") (Address "addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck")
(Token "" "")
(Constant 80000000))
(Pay (Address "addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck")
(Party (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d"))
(Token "" "")
(Constant 80000000)
(When [
(Case
(Deposit (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d") (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d")
(Token "" "")
(AddValue
(Constant 80000000)
(Constant 5000000)))
(Pay (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d")
(Party (Address "addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck"))
(Token "" "")
(AddValue
(Constant 80000000)
(Constant 5000000)) Close))] 1679613525000 Close)))] 1679606325000 Close

Bạn có thể truy xuất thêm chi tiết bằng cách sử dụng marlowe-pipe.

echo '{"request" : "get", "contractId" : "'"$CONTRACT_ID"'"}' | marlowe-pipe 2> /dev/null | json2yaml
    creation:
output:
address: 702ed2631dbb277c84334453c5c437b86325d371f0835a28b910a91a6e
assets:
ada: 2000000
tokens: []
datum:
marloweContract:
timeout: 1679606325000
timeout_continuation: close
when:
- case:
deposits: 80000000
into_account:
address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck
of_token:
currency_symbol: ''
token_name: ''
party:
address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck
then:
from_account:
address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck
pay: 80000000
then:
timeout: 1679613525000
timeout_continuation: close
when:
- case:
deposits:
add: 80000000
and: 5000000
into_account:
address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d
of_token:
currency_symbol: ''
token_name: ''
party:
address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d
then:
from_account:
address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d
pay:
add: 80000000
and: 5000000
then: close
to:
party:
address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck
token:
currency_symbol: ''
token_name: ''
to:
party:
address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d
token:
currency_symbol: ''
token_name: ''
marloweParams:
rolesCurrency: ''
marloweState:
accounts:
- - - address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck
- currency_symbol: ''
token_name: ''
- 2000000
boundValues: []
choices: []
minTime: 0
utxo:
txId: 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895
txIx: 1
payoutValidatorHash: e165610232235bbbbeff5b998b233daae42979dec92a6722d9cda989
response: info
steps: []

Giao dịch 2. Người cho vay gửi tiền gốc

Người cho vay gửi 80 ADA tiền gốc của họ vào hợp đồng bằng cách sử dụng lệnh marlowe-runtime-cli deposit của Marlowe Runtime. Người cho vay đang cung cấp vốn cho và nhận tiền thay đổi từ giao dịch này, vì vậy chúng ta cung cấp địa chỉ của họ. Chúng ta cung cấp số nhận dạng hợp đồng và lưu giao dịch chưa ký trong tệp tx-2.unsigned.

marlowe-runtime-cli deposit --help
   Usage: marlowe-runtime-cli deposit --change-address ADDRESS [-a|--address ADDRESS] 
[--collateral-utxo UTXO] --manual-sign FILE_PATH
[-m|--metadata-file FILE_PATH] [--tags-file FILE_PATH]
(-c|--contract CONTRACT_ID) --to-party ROLE_NAME|ADDRESS
--from-party ROLE_NAME|ADDRESS
((-c|--currency MINTING_POLICY_ID)
(-n|--token-name TOKEN_NAME) (-q|--quantity INTEGER) |
(-l|--lovelace INTEGER))
[--continuation-file FILE_PATH]
[-l|--validity-lower-bound TIMESTAMP]
[-u|--validity-upper-bound TIMESTAMP]

Deposit funds into a contract

Available options:
--change-address ADDRESS The address to which the change of the transaction
should be sent.
-a,--address ADDRESS An address whose UTXOs can be used as inputs to the
transaction
--collateral-utxo UTXO A UTXO which may be used as a collateral input
--manual-sign FILE_PATH Sign the transaction manually. Writes the CBOR bytes
of the unsigned transaction to the specified file for
manual signing. Use the submit command to submit the
signed transaction.
-m,--metadata-file FILE_PATH
A JSON file containing a map of integer indexes to
arbitrary JSON values that will be added to the
transaction's metadata.
--tags-file FILE_PATH A JSON file containing a map of tags indexes to
optional JSON-encoded metadata values that will be
added to the transaction's 1564 metadata key. Note
that the entire 1564 key will be overridden if also
specified in --metadata-file.
-c,--contract CONTRACT_ID
The ID of the Marlowe contract to deposit funds into
--to-party ROLE_NAME|ADDRESS
The party into whose account to deposit the funds.
--from-party ROLE_NAME|ADDRESS
The party depositing the funds.
-c,--currency MINTING_POLICY_ID
The minting policy ID of the token(s) to deposit.
-n,--token-name TOKEN_NAME
The name of the token(s) to deposit.
-q,--quantity INTEGER The quantity of tokens to deposit.
-l,--lovelace INTEGER The quantity of lovelace to deposit.
--continuation-file FILE_PATH
A file containing the continuation contract JSON for
making a choice in a Merkleized contract.
-l,--validity-lower-bound TIMESTAMP
The lower bound of the transaction validity interval
in POSIX milliseconds. If not specified, the current
time (as determined by the Cardano node) will be
used.
-u,--validity-upper-bound TIMESTAMP
The upper bound of the transaction validity interval
in POSIX milliseconds. If not specified, the next
timeout in the contract will be used (bounded by the
maximum value allowed by the Cardano node).
-h,--help Show this help text
    TX_2=$(
marlowe-runtime-cli deposit \
--contract "$CONTRACT_ID" \
--from-party "$LENDER_ADDR" \
--to-party "$LENDER_ADDR" \
--lovelace "$PRINCIPAL" \
--change-address "$LENDER_ADDR" \
--manual-sign tx-2.unsigned \
| jq -r 'fromjson | .txId' \
)
echo "TX_2 = $TX_2"
TX_2 = bc286bb53f50a7355e2765462546e03d17cabde30420b6bfd1531617386facf4

Lưu ý rằng nếu giao dịch vi phạm logic của hợp đồng Marlowe, người ta sẽ nhận được thông báo lỗi. Ví dụ: giả sử chúng ta gửi số tiền không chính xác hoặc gửi số tiền đó vào tài khoản nội bộ của bên sai.

    marlowe-runtime-cli deposit \
--contract "$CONTRACT_ID" \
--from-party "$LENDER_ADDR" \
--to-party "$LENDER_ADDR" \
--lovelace 80 \
--change-address "$LENDER_ADDR" \
--manual-sign /dev/null
ApplyFailed (ApplyInputsConstraintsBuildupFailed (MarloweComputeTransactionFailed "TEApplyNoMatchError"))
    marlowe-runtime-cli deposit \
--contract "$CONTRACT_ID" \
--from-party "$LENDER_ADDR" \
--to-party "$BORROWER_ADDR" \
--lovelace "$PRINCIPAL"\
--change-address "$LENDER_ADDR" \
--manual-sign /dev/null
ApplyFailed (ApplyInputsConstraintsBuildupFailed (MarloweComputeTransactionFailed "TEApplyNoMatchError"))

Sách hướng dẫn gỡ lỗi Marlowe hướng dẫn giải thích các thông báo lỗi. Ngoài ra, người ta có thể xác định các hành động có thể thực hiện đối với hợp đồng ở giai đoạn thực hiện hiện tại bằng cách nghiên cứu trạng thái hiện tại của hợp đồng hoặc bằng cách sử dụng sân chơi Marlowe để mô phỏng hợp đồng.

Mô phỏng hợp đồng trái phiếu không INTEREST trong Sân chơi Marlowe

Một lần nữa, hãy sử dụng marlowe-cli để gửi giao dịch rồi đợi xác nhận.

    marlowe-cli transaction submit \
--tx-body-file tx-2.unsigned \
--required-signer "$LENDER_SKEY" \
--timeout 600
TxId "bc286bb53f50a7355e2765462546e03d17cabde30420b6bfd1531617386facf4"

Người ta có thể xem giao dịch trên Cardano explorer. Đôi khi phải mất ba mươi giây hoặc lâu hơn để giao dịch hiển thị trong explorer.

echo "$EXPLORER_URL"/transaction/"$TX_2?tab=utxo"

https://preprod.cardanoscan.io/transaction/bc286bb53f50a7355e2765462546e03d17cabde30420b6bfd1531617386facf4?tab=utxo

Người ta có thể thấy rằng người cho vay có ít hơn 82 ADA so với ban đầu. Hai ADA đã được gửi vào hợp đồng khi nó được tạo ra và 80 ADA đã được trả cho người vay trong giao dịch thứ hai.

cardano-cli query utxo --testnet-magic "$CARDANO_TESTNET_MAGIC" --address "$LENDER_ADDR"

TxHash TxIx Amount
--------------------------------------------------------------------------------------
bc286bb53f50a7355e2765462546e03d17cabde30420b6bfd1531617386facf4 0 917043702 lovelace + TxOutDatumNone

Người vay hiện có thêm 80 ADA (tiền gốc của khoản vay).

cardano-cli query utxo --testnet-magic "$CARDANO_TESTNET_MAGIC" --address "$BORROWER_ADDR"

TxHash TxIx Amount
--------------------------------------------------------------------------------------
8461a35e612b38d4cb592e4ba1b7f13c2ff2825942d66e7200acc575cd4c8f1c 2 1000000000 lovelace + TxOutDatumNone
bc286bb53f50a7355e2765462546e03d17cabde30420b6bfd1531617386facf4 2 80000000 lovelace + TxOutDatumNone

Hợp đồng Marlowe vẫn có 2 ADA từ khi tạo ra nó.

cardano-cli query utxo --testnet-magic "$CARDANO_TESTNET_MAGIC" --tx-in "$TX_2#1"

TxHash TxIx Amount
--------------------------------------------------------------------------------------
bc286bb53f50a7355e2765462546e03d17cabde30420b6bfd1531617386facf4 1 2000000 lovelace + TxOutDatumHash ScriptDataInBabbageEra "a93e880b40ff61cda04fd23696b1abe3d8ee13591896aaad3f42441ced75f5b2"

Xem thêm tiến độ của hợp đồng trên blockchain

Lệnh marlowe-runtime-cli log của Marlowe Runtime có thể tìm nạp hợp đồng từ blockchain và in thông tin về hợp đồng đó.

marlowe-runtime-cli log --show-contract "$CONTRACT_ID"
transaction 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895 (creation)
ContractId: 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895#1
SlotNo: 23920017
BlockNo: 755074
BlockId: 3235ba612d6df4e536da88890b39cc0fbb96ff3313643dd999ef31ed699f3af2
ScriptAddress: addr_test1wqhdyccahvnheppng3fut3phhp3jt5m37zp4529ezz535ms2u9jqv
Marlowe Version: 1

When [
(Case
(Deposit (Address "addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck") (Address "addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck")
(Token "" "")
(Constant 80000000))
(Pay (Address "addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck")
(Party (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d"))
(Token "" "")
(Constant 80000000)
(When [
(Case
(Deposit (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d") (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d")
(Token "" "")
(AddValue
(Constant 80000000)
(Constant 5000000)))
(Pay (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d")
(Party (Address "addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck"))
(Token "" "")
(AddValue
(Constant 80000000)
(Constant 5000000)) Close))] 1679613525000 Close)))] 1679606325000 Close

transaction bc286bb53f50a7355e2765462546e03d17cabde30420b6bfd1531617386facf4
ContractId: 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895#1
SlotNo: 23920533
BlockNo: 755085
BlockId: afb9ca1ee1d06282e65943ae57d09622ca8d648a63d69eab1dd186fa5b3b7bc4
Inputs: [NormalInput (IDeposit "\"addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck\"" "\"addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck\"" (Token "" "") 80000000)]

When [
(Case
(Deposit (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d") (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d")
(Token "" "")
(AddValue
(Constant 80000000)
(Constant 5000000)))
(Pay (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d")
(Party (Address "addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck"))
(Token "" "")
(AddValue
(Constant 80000000)
(Constant 5000000)) Close))] 1679613525000 Close

Bạn có thể truy xuất thêm chi tiết bằng cách sử dụng marlowe-pipe.

echo '{"request" : "get", "contractId" : "'"$CONTRACT_ID"'"}' | marlowe-pipe 2> /dev/null | json2yaml
creation:

  output:

    address: 702ed2631dbb277c84334453c5c437b86325d371f0835a28b910a91a6e

    assets:

      ada: 2000000

      tokens: []

    datum:

      marloweContract:

        timeout: 1679606325000

        timeout_continuation: close

        when:

        - case:

            deposits: 80000000

            into_account:

              address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

            of_token:

              currency_symbol: ''

              token_name: ''

            party:

              address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

          then:

            from_account:

              address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

            pay: 80000000

            then:

              timeout: 1679613525000

              timeout_continuation: close

              when:

              - case:

                  deposits:

                    add: 80000000

                    and: 5000000

                  into_account:

                    address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

                  of_token:

                    currency_symbol: ''

                    token_name: ''

                  party:

                    address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

                then:

                  from_account:

                    address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

                  pay:

                    add: 80000000

                    and: 5000000

                  then: close

                  to:

                    party:

                      address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

                  token:

                    currency_symbol: ''

                    token_name: ''

            to:

              party:

                address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

            token:

              currency_symbol: ''

              token_name: ''

      marloweParams:

        rolesCurrency: ''

      marloweState:

        accounts:

        - - - address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

            - currency_symbol: ''

              token_name: ''

          - 2000000

        boundValues: []

        choices: []

        minTime: 0

    utxo:

      txId: 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895

      txIx: 1

  payoutValidatorHash: e165610232235bbbbeff5b998b233daae42979dec92a6722d9cda989

response: info

steps:

- contractId: 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895#1

  payouts: []

  redeemer:

  - input_from_party:

      address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

    into_account:

      address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

    of_token:

      currency_symbol: ''

      token_name: ''

    that_deposits: 80000000

  scriptOutput:

    address: 702ed2631dbb277c84334453c5c437b86325d371f0835a28b910a91a6e

    assets:

      ada: 2000000

      tokens: []

    datum:

      marloweContract:

        timeout: 1679613525000

        timeout_continuation: close

        when:

        - case:

            deposits:

              add: 80000000

              and: 5000000

            into_account:

              address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

            of_token:

              currency_symbol: ''

              token_name: ''

            party:

              address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

          then:

            from_account:

              address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

            pay:

              add: 80000000

              and: 5000000

            then: close

            to:

              party:

                address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

            token:

              currency_symbol: ''

              token_name: ''

      marloweParams:

        rolesCurrency: ''

      marloweState:

        accounts:

        - - - address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

            - currency_symbol: ''

              token_name: ''

          - 2000000

        boundValues: []

        choices: []

        minTime: 1679603355000

    utxo:

      txId: bc286bb53f50a7355e2765462546e03d17cabde30420b6bfd1531617386facf4

      txIx: 1

  step: apply

  txId: bc286bb53f50a7355e2765462546e03d17cabde30420b6bfd1531617386facf4

Giao dịch 3. Người vay hoàn trả khoản vay

Sau một thời gian, người vay trả lại tiền gốc cộng với tiền lãi. Vì vậy, họ tài trợ cho giao dịch và nhận tiền thay đổi tại địa chỉ của họ.

TX_3=$(
marlowe-runtime-cli deposit \
--contract "$CONTRACT_ID" \
--from-party "$BORROWER_ADDR" \
--to-party "$BORROWER_ADDR" \
--lovelace "$((PRINCIPAL+INTEREST))" \
--change-address "$BORROWER_ADDR" \
--manual-sign tx-3.unsigned \
| jq -r 'fromjson | .txId' \
)
echo "TX_3 = $TX_3"
TX_3 = d159062c1321707d12d7abe14cfaca1881a7b1e3c65bb4d637070e4fc0da08c3

Một lần nữa, hãy sử dụng marlowe-cli để gửi giao dịch rồi chờ xác nhận.

marlowe-cli transaction submit \
--tx-body-file tx-3.unsigned \
--required-signer "$BORROWER_SKEY" \
--timeout 600
TxId "d159062c1321707d12d7abe14cfaca1881a7b1e3c65bb4d637070e4fc0da08c3"

Người ta có thể xem giao dịch trên Cardano explorer. Đôi khi phải mất ba mươi giây hoặc lâu hơn để giao dịch hiển thị trong explorer.

echo "$EXPLORER_URL"/giao dịch/"$TX_3?tab=utxo"

https://preprod.cardanoscan.io/transaction/d159062c1321707d12d7abe14cfaca1881a7b1e3c65bb4d637070e4fc0da08c3?tab=utxo

Người ta có thể thấy rằng người cho vay đã nhận lại 80 ADA tiền gốc và 2 ADA PRINCIPAL khi hợp đồng được tạo, cùng với 5 ADA tiền lãi bổ sung, tổng cộng là 87 ADA.

cardano-cli query utxo --testnet-magic "$CARDANO_TESTNET_MAGIC" --address "$LENDER_ADDR"
                           TxHash                                 TxIx        Amount
--------------------------------------------------------------------------------------
bc286bb53f50a7355e2765462546e03d17cabde30420b6bfd1531617386facf4 0 917043702 lovelace + TxOutDatumNone
d159062c1321707d12d7abe14cfaca1881a7b1e3c65bb4d637070e4fc0da08c3 1 87000000 lovelace + TxOutDatumNone

Người vay bây giờ có ít hơn khoảng 5 ADA (tiền lãi của khoản vay) so với ban đầu.

cardano-cli query utxo --testnet-magic "$CARDANO_TESTNET_MAGIC" --address "$BORROWER_ADDR"
                           TxHash                                 TxIx        Amount
--------------------------------------------------------------------------------------
bc286bb53f50a7355e2765462546e03d17cabde30420b6bfd1531617386facf4 2 80000000 lovelace + TxOutDatumNone
d159062c1321707d12d7abe14cfaca1881a7b1e3c65bb4d637070e4fc0da08c3 0 914430977 lovelace + TxOutDatumNone

Hợp đồng Marlowe đã đóng, vì vậy không có đầu ra nào cho địa chỉ tập lệnh của nó.

Xem việc hoàn thành hợp đồng trên blockchain

Lệnh marlowe-runtime-cli log của Marlowe Runtime có thể tìm nạp hợp đồng từ blockchain và in thông tin về hợp đồng đó.

marlowe-runtime-cli log --show-contract "$CONTRACT_ID"
transaction 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895 (creation)
ContractId: 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895#1
SlotNo: 23920017
BlockNo: 755074
BlockId: 3235ba612d6df4e536da88890b39cc0fbb96ff3313643dd999ef31ed699f3af2
ScriptAddress: addr_test1wqhdyccahvnheppng3fut3phhp3jt5m37zp4529ezz535ms2u9jqv
Marlowe Version: 1

When [
(Case
(Deposit (Address "addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck") (Address "addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck")
(Token "" "")
(Constant 80000000))
(Pay (Address "addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck")
(Party (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d"))
(Token "" "")
(Constant 80000000)
(When [
(Case
(Deposit (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d") (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d")
(Token "" "")
(AddValue
(Constant 80000000)
(Constant 5000000)))
(Pay (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d")
(Party (Address "addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck"))
(Token "" "")
(AddValue
(Constant 80000000)
(Constant 5000000)) Close))] 1679613525000 Close)))] 1679606325000 Close

transaction bc286bb53f50a7355e2765462546e03d17cabde30420b6bfd1531617386facf4
ContractId: 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895#1
SlotNo: 23920533
BlockNo: 755085
BlockId: afb9ca1ee1d06282e65943ae57d09622ca8d648a63d69eab1dd186fa5b3b7bc4
Inputs: [NormalInput (IDeposit "\"addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck\"" "\"addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck\"" (Token "" "") 80000000)]

When [
(Case
(Deposit (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d") (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d")
(Token "" "")
(AddValue
(Constant 80000000)
(Constant 5000000)))
(Pay (Address "addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d")
(Party (Address "addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck"))
(Token "" "")
(AddValue
(Constant 80000000)
(Constant 5000000)) Close))] 1679613525000 Close

transaction d159062c1321707d12d7abe14cfaca1881a7b1e3c65bb4d637070e4fc0da08c3 (close)
ContractId: 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895#1
SlotNo: 23920774
BlockNo: 755092
BlockId: a844fdf2efe9508fa24c34f0a095e8de691e0e16df815e55b95acb5e217151de
Inputs: [NormalInput (IDeposit "\"addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d\"" "\"addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d\"" (Token "" "") 85000000)]

Bạn có thể truy xuất thêm chi tiết bằng cách sử dụng marlowe-pipe.

echo '{"request" : "get", "contractId" : "'"$CONTRACT_ID"'"}' | marlowe-pipe 2> /dev/null | json2yaml
creation:

  output:

    address: 702ed2631dbb277c84334453c5c437b86325d371f0835a28b910a91a6e

    assets:

      ada: 2000000

      tokens: []

    datum:

      marloweContract:

        timeout: 1679606325000

        timeout_continuation: close

        when:

        - case:

            deposits: 80000000

            into_account:

              address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

            of_token:

              currency_symbol: ''

              token_name: ''

            party:

              address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

          then:

            from_account:

              address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

            pay: 80000000

            then:

              timeout: 1679613525000

              timeout_continuation: close

              when:

              - case:

                  deposits:

                    add: 80000000

                    and: 5000000

                  into_account:

                    address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

                  of_token:

                    currency_symbol: ''

                    token_name: ''

                  party:

                    address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

                then:

                  from_account:

                    address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

                  pay:

                    add: 80000000

                    and: 5000000

                  then: close

                  to:

                    party:

                      address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

                  token:

                    currency_symbol: ''

                    token_name: ''

            to:

              party:

                address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

            token:

              currency_symbol: ''

              token_name: ''

      marloweParams:

        rolesCurrency: ''

      marloweState:

        accounts:

        - - - address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

            - currency_symbol: ''

              token_name: ''

          - 2000000

        boundValues: []

        choices: []

        minTime: 0

    utxo:

      txId: 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895

      txIx: 1

  payoutValidatorHash: e165610232235bbbbeff5b998b233daae42979dec92a6722d9cda989

response: info

steps:

- contractId: 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895#1

  payouts: []

  redeemer:

  - input_from_party:

      address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

    into_account:

      address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

    of_token:

      currency_symbol: ''

      token_name: ''

    that_deposits: 80000000

  scriptOutput:

    address: 702ed2631dbb277c84334453c5c437b86325d371f0835a28b910a91a6e

    assets:

      ada: 2000000

      tokens: []

    datum:

      marloweContract:

        timeout: 1679613525000

        timeout_continuation: close

        when:

        - case:

            deposits:

              add: 80000000

              and: 5000000

            into_account:

              address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

            of_token:

              currency_symbol: ''

              token_name: ''

            party:

              address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

          then:

            from_account:

              address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

            pay:

              add: 80000000

              and: 5000000

            then: close

            to:

              party:

                address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

            token:

              currency_symbol: ''

              token_name: ''

      marloweParams:

        rolesCurrency: ''

      marloweState:

        accounts:

        - - - address: addr_test1vqd3yrtjyx49uld43lvwqaf7z4k03su8gf2x4yr7syzvckgfzm4ck

            - currency_symbol: ''

              token_name: ''

          - 2000000

        boundValues: []

        choices: []

        minTime: 1679603355000

    utxo:

      txId: bc286bb53f50a7355e2765462546e03d17cabde30420b6bfd1531617386facf4

      txIx: 1

  step: apply

  txId: bc286bb53f50a7355e2765462546e03d17cabde30420b6bfd1531617386facf4

- contractId: 3bd6f3011ebabd0d55182aa657a7b841faa9f4b823d1fd76a215d917d0c61895#1

  payouts: []

  redeemer:

  - input_from_party:

      address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

    into_account:

      address: addr_test1vpy4n4peh4suv0y55yptur0066j5kds8r4ncnuzm0vpzfgg0dhz6d

    of_token:

      currency_symbol: ''

      token_name: ''

    that_deposits: 85000000

  scriptOutput: null

  step: apply

  txId: d159062c1321707d12d7abe14cfaca1881a7b1e3c65bb4d637070e4fc0da08c3

Xem thêm video


Nguồn bài viết tại đây


Picture