Skip to main content

Gửi giao dịch

Trên CrossFI Chain, bạn có thể gửi, ký và phát giao dịch theo các cách sau:

Sử dụng CLI

Cách tốt nhất để gửi giao dịch là sử dụng CLI, như chúng ta đã thấy trong trang trước khi giao tiếp với một node. Ví dụ, chạy lệnh sau

crossfid tx bank send $MY_VALIDATOR_ADDRESS $RECIPIENT 1000mpx

sẽ thực hiện các bước sau:

  • tạo một giao dịch với một Msg (x/bank's MsgSend), và in giao dịch đã tạo ra console.
  • hỏi người dùng xác nhận để gửi giao dịch từ tài khoản $MY_VALIDATOR_ADDRESS.
  • lấy $MY_VALIDATOR_ADDRESS từ keyring. Điều này khả thi vì chúng ta đã thiết lập keyring của CLI trong bước trước đó.
  • ký giao dịch đã tạo bằng tài khoản của keyring.
  • phát giao dịch đã ký lên mạng lưới. Điều này khả thi vì CLI kết nối với node thông qua điểm cuối Tendermint RPC.

CLI gói gọn tất cả các bước cần thiết vào một trải nghiệm người dùng dễ sử dụng. Tuy nhiên, có thể thực hiện tất cả các bước riêng rẽ.

Tạo một giao dịch

Việc tạo một giao dịch chỉ cần thực hiện bằng cách thêm cờ --generate-only vào bất kỳ lệnh tx nào, ví dụ:

crossfid tx bank send $MY_VALIDATOR_ADDRESS $RECIPIENT 1000mpx --generate-only

Điều này sẽ xuất giao dịch chưa ký dưới dạng JSON trong console. Chúng ta cũng có thể lưu giao dịch chưa ký vào một tệp (để dễ dàng chuyển tiếp giữa các người ký) bằng cách thêm > unsigned_tx.json vào lệnh trên.

Ký một giao dịch

Việc ký giao dịch bằng CLI yêu cầu giao dịch chưa ký được lưu trong một tệp. Giả sử giao dịch chưa ký nằm trong tệp có tên unsigned_tx.json trong thư mục hiện tại (xem đoạn văn trước về cách thực hiện điều đó). Sau đó, chỉ cần chạy lệnh sau:

crossfid tx sign unsigned_tx.json --from $MY_VALIDATOR_ADDRESS

Lệnh này sẽ giải mã giao dịch chưa ký và ký nó với SIGN_MODE_DIRECT với khóa của $MY_VALIDATOR_ADDRESS, mà chúng ta đã thiết lập trong keyring. Giao dịch đã ký sẽ được xuất dưới dạng JSON ra console, và giống như trên, chúng ta có thể lưu nó vào tệp bằng cách thêm > signed_tx.json.

Một số cờ hữu ích cần xem xét trong lệnh tx sign:

  • --sign-mode: bạn có thể sử dụng amino-json để ký giao dịch sử dụng SIGN_MODE_LEGACY_AMINO_JSON,
  • --offline: ký trong chế độ không kết nối. Điều này có nghĩa là lệnh tx sign không kết nối với node để lấy số tài khoản và chuỗi, cả hai đều cần thiết để ký. Trong trường hợp này, bạn phải tự cung cấp các cờ --account-number--sequence. Điều này hữu ích cho việc ký ngoại tuyến, tức là ký tại một môi trường an toàn không có truy cập internet.

Ký với nhiều người ký

Xin lưu ý rằng ký một giao dịch với nhiều người ký hoặc với tài khoản multisig, nơi ít nhất một người ký sử dụng SIGN_MODE_DIRECT, chưa thể thực hiện được. Bạn có thể theo dõi Github issue này để biết thêm thông tin.

Ký với nhiều người ký được thực hiện bằng lệnh tx multisign. Lệnh này giả định rằng tất cả các người ký sử dụng SIGN_MODE_LEGACY_AMINO_JSON. Quy trình này tương tự như quy trình của lệnh tx sign, nhưng thay vì ký một tệp giao dịch chưa ký, mỗi người ký sẽ ký tệp đã được người ký trước đó ký.

Lệnh tx multisign sẽ thêm chữ ký vào các giao dịch đã tồn tại. Điều quan trọng là các người ký ký giao dịch theo cùng thứ tự như được giao dịch chỉ định, điều này có thể truy xuất thông qua phương thức GetSigners().

Ví dụ, bắt đầu với unsigned_tx.json, và giả sử giao dịch có 4 người ký, chúng ta sẽ chạy:


# Để người ký thứ nhất ký tx chưa ký.
crossfid tx multisign unsigned_tx.json signer_key_1 > partial_tx_1.json

# Bây giờ người ký thứ nhất sẽ gửi partial_tx_1.json cho người ký thứ hai.

# Người ký thứ hai thêm chữ ký của họ:
crossfid tx multisign partial_tx_1.json signer_key_2 > partial_tx_2.json

# Người ký thứ hai gửi tệp partial_tx_2.json cho người ký thứ ba, người ký thứ ba có thể thêm chữ ký của mình:
crossfid tx multisign partial_tx_2.json signer_key_3 > partial_tx_3.json

Phát hành giao dịch

Phát hành một giao dịch được thực hiện bằng cách sử dụng lệnh sau:

crossfid tx broadcast tx_signed.json

Bạn có thể tùy chọn chuyển qua cờ --broadcast-mode để xác định phản hồi nào sẽ nhận từ node:

  • block: CLI chờ đợi tx được đưa vào một khối.
  • sync: CLI chỉ chờ đợi phản hồi CheckTx.
  • async: CLI trả về ngay lập tức (giao dịch có thể thất bại).

Mã hoá một giao dịch

Để phát hành một giao dịch thông qua các điểm cuối gRPC hoặc REST, cần mã hóa giao dịch trước. Điều này có thể thực hiện bằng CLI.

Mã hoá một giao dịch được thực hiện bằng cách sử dụng lệnh sau:

crossfid tx encode tx_signed.json

Điều này sẽ đọc giao dịch từ tệp, tuần tự hóa nó bằng Protobuf, và xuất các byte giao dịch dưới dạng base64 trong console.

Giải mã một giao dịch

CLI cũng có thể được sử dụng để giải mã byte giao dịch.

Giải mã một giao dịch được thực hiện bằng cách sử dụng lệnh sau:

crossfid tx decode [protobuf-byte-string]

Điều này sẽ giải mã byte giao dịch và xuất giao dịch dưới dạng JSON ra console. Bạn cũng có thể lưu giao dịch vào một tệp bằng cách thêm > tx.json vào lệnh trên.

Lập trình với Go

Có thể thao tác các giao dịch lập trình qua Go sử dụng Cosmos SDK's giao diện TxBuilder.

Tạo một giao dịch

Trước khi tạo một giao dịch, ta cần tạo một thể hiện mới của TxBuilder. Vì Cosmos SDK hỗ trợ cả giao dịch Amino và Protobuf, bước đầu tiên sẽ là quyết định sử dụng kiểu mã hóa nào. Tất cả các bước tiếp theo vẫn không thay đổi, bất kể bạn đang sử dụng Amino hay Protobuf, vì TxBuilder trừu tượng hóa các cơ chế mã hóa. Trong đoạn mã sau, chúng ta sẽ sử dụng Protobuf.

import (
"github.com/cosmos/cosmos-sdk/simapp"
)

func sendTx() error

Chúng ta cũng có thể thiết lập một số khóa và địa chỉ để gửi và nhận giao dịch. Ở đây, nhằm mục đích của hướng dẫn, chúng ta sẽ sử dụng một số dữ liệu giả định để tạo khóa.

import (
"github.com/cosmos/cosmos-sdk/testutil/testdata"
)

priv1, _, addr1 := testdata.KeyTestPubAddr()
priv2, _, addr2 := testdata.KeyTestPubAddr()
priv3, _, addr3 := testdata.KeyTestPubAddr()

Việc điền vào TxBuilder có thể được thực hiện thông qua các phương thức của nó:

import (
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)

func sendTx() error

txBuilder.SetGasLimit(...)
txBuilder.SetFeeAmount(...)
txBuilder.SetMemo(...)
txBuilder.SetTimeoutHeight(...)
}

Tại thời điểm này, giao dịch ngầm của TxBuilder đã sẵn sàng để được ký.

Ký một giao dịch

Chúng tôi thiết lập cấu hình mã hóa để sử dụng Protobuf, điều này sẽ sử dụng SIGN_MODE_DIRECT theo mặc định. Theo ADR-020, mỗi người ký cần phải ký SignerInfos của tất cả các người ký khác. Điều này có nghĩa là chúng ta cần thực hiện hai bước tuần tự:

  • đối với mỗi người ký, điền SignerInfo của người ký bên trong TxBuilder,
  • một khi tất cả SignerInfo đã được điền vào, đối với mỗi người ký, ký SignDoc (nội dung cần được ký).

Trong API hiện tại của TxBuilder, cả hai bước được thực hiện bằng cùng một phương thức: SetSignatures(). API hiện tại yêu cầu chúng ta đầu tiên thực hiện một lượt SetSignatures() với các chữ ký trống, chỉ để điền SignerInfo, và một lượt thứ hai của SetSignatures() để thực sự ký nội dung đúng.

import (
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
)

func sendTx() error
accNums:= []uint64 // Các số tài khoản của các tài khoản
accSeqs:= []uint64 // Các chuỗi số của các tài khoản

// Vòng đầu tiên: chúng tôi thu thập tất cả thông tin người ký. Chúng tôi sử dụng "chữ ký trống
// signature" thích ứng để làm điều đó.
var sigsV2 []signing.SignatureV2
for i, priv := range privs ,
Sequence: accSeqs[i],
}

sigsV2 = append(sigsV2, sigV2)
}
err := txBuilder.SetSignatures(sigsV2...)
if err != nil

// Vòng thứ hai: tất cả thông tin người ký đã được đặt, vì vậy mỗi người ký có thể ký.
sigsV2 = []signing.SignatureV2{}
for i, priv := range privs
sigV2, err := tx.SignWithPrivKey(
encCfg.TxConfig.SignModeHandler().DefaultMode(), signerData,
txBuilder, priv, encCfg.TxConfig, accSeqs[i])
if err != nil

sigsV2 = append(sigsV2, sigV2)
}
err = txBuilder.SetSignatures(sigsV2...)
if err != nil
}

TxBuilder hiện nay đã được điền chính xác. Để in nó, bạn có thể sử dụng giao diện TxConfig từ cấu hình mã hóa ban đầu encCfg:

func sendTx() error

// Tạo một chuỗi JSON.
txJSONBytes, err := encCfg.TxConfig.TxJSONEncoder()(txBuilder.GetTx())
if err != nil
txJSON := string(txJSONBytes)
}

Sử dụng gRPC

Không thể tạo hoặc ký giao dịch bằng gRPC, chỉ có thể phát một giao dịch. Để phát một giao dịch qua gRPC, bạn sẽ cần tạo, ký và mã hóa giao dịch bằng CLI hoặc lập trình qua Go.

Phát một giao dịch

Phát đi một giao dịch qua điểm cuối gRPC có thể được thực hiện bằng cách gửi một yêu cầu BroadcastTx như sau, nơi txBytes là các byte mã hóa protobuf của một giao dịch đã ký:

grpcurl -plaintext \
-d '}","mode":"BROADCAST_MODE_SYNC"}' \
localhost:9090 \
cosmos.tx.v1beta1.Service/BroadcastTx

Sử dụng REST

Không thể tạo hoặc ký giao dịch bằng REST, chỉ có thể phát một giao dịch. Để phát một giao dịch qua REST, bạn sẽ cần tạo, ký, và mã hóa giao dịch bằng CLI hoặc lập trình với Go.

Phát một giao dịch

Phát một giao dịch qua điểm cuối REST (được phục vụ bởi gRPC-gateway) có thể được thực hiện bằng cách gửi một yêu cầu POST như sau, nơi txBytes là các byte mã hóa protobuf của một giao dịch đã ký:

curl -X POST \
-H "Content-Type: application/json" \
-d'}","mode":"BROADCAST_MODE_SYNC"}' \
localhost:1317/cosmos/tx/v1beta1/txs

Sử dụng CosmJS (JavaScript & TypeScript)

CosmJS nhằm xây dựng các thư viện khách hàng bằng JavaScript có thể nhúng trong các ứng dụng web. Vui lòng xem https://cosmos.github.io/cosmjs để biết thêm thông tin. Tính đến tháng một 2021, tài liệu CosmJS vẫn đang trong quá trình phát triển.