LapTrinhBlockchain

Chia sẻ kiến thức về Lập Trình Blockchain

Kiến thức lập trình, Lập trình Blockchain, Lập Trình DApp, Lập trình GoLang, Lập trình NodeJs

Hướng dẫn đóng gói các giao dịch TRON sử dụng ngôn ngữ Go (go lang)

Hướng dẫn đóng gói các giao dịch TRON sử dụng ngôn ngữ Go (go lang)

Hướng dẫn đóng gói các giao dịch TRON sử dụng ngôn ngữ Go (go lang)

Chia sẻ bài viết
5
(68)

Trong phần này tôi sử dụng tài khoản TCuWX3Az4D23vWKcDU442eXFQBm2rsCRke với private key là “9499BF78CE4A0217EC48F69AFDBAC19E10E10ACA14C8B278F08A213FA92FC498“. Đây là tài khoản dùng để test trên mạng lưới Nile Testnet, tuyệt đối không được sử dụng tài khoản này trên Mainnet. Trên Testnet, để có thể chạy test được, bạn phải chuyển ít TRX trên Nile Testnet vào địa chỉ này trước nhé. Bạn có thể lấy TRX miễn phí từ địa chỉ: https://nileex.io/join/getJoinPage

Bài viết này tôi tập trung vào giải pháp tạo ra một giao dịch đóng gói đầy đủ bao gồm cả chữ ký sử dụng ngôn ngữ Go. Với dữ liệu đóng gói này, chúng ta có thể sử dụng bất kỳ ngôn ngữ nào để đẩy giao dịch đó lên blockchain.

Về cơ bản nguyên tắc chung đóng gói gồm:

  • B1: Tạo giao dịch với thông tin cần thiết. Từ thông tin giao dịch này ta encode để được dữ liệu d0 dạng mảng byte.
  • B2: Từ dữ liệu d0, ta thực hiện băm bằng SHA256 ta được dữ liệu hash, là Transaction Hash hay TxId của giao dịch.
  • B3: Ta dùng Private Key để ký lên dữ liệu hash ta được s, đây là chữa ký của giao dịch.
  • B4: Ta kết hợp giữa d0 s ta được d1, đây là dữ liệu đóng gói cho toàn bộ giao dịch. Gửi d1 lên blockchain thì giao dịch sẽ được thực hiện.

Và tôi đã tìm được một thư viện tron-sdk để làm được việc này, thư viện này là một phần của thư viện go-wallet-sdk của OKX (OKEX) lên khá uy tín. Trong thư viện này có một số hàm quan trọng sau (Xem thêm tron_test.go):

  • Hàm SignStart(): Hàm này thực hiện băm giao dịch bằng SHA256 để được hash.
  • Hàm Sign(): Hàm này dùng để ký hash tạo được ở trên
  • Hàm SignEnd(): Hàm này đóng gọi giao dịch bao gồm cả chữ ký.

Thêm nữa, trong thông tin giao dịch trên TRON, bạn cần phải cung cấp refBlock (Block tham chiếu), bạn có thể lấy từ thông tin block mới nhất trên Nile Scan. Nếu thông tin refBlock lớn hơn block hiện tại, hoặc nhỏ hơn block hiện tại 65535 block thì bạn sẽ nhận được lỗi “Tapos check error“.

Đóng gói giao dịch chuyển TRX bằng ngôn ngữ Go

Bây giờ chúng ta sẽ thực hiện đóng gói 1 giao dịch chuyển 0.01 TRX từ địa chỉ TCuWX3Az4D23vWKcDU442eXFQBm2rsCRke tới địa chỉ TWXKV19GnweWQzFPJckKHbCgeSRUMMowHz.

Đầu tiên chúng ta vào Nile Scan để lấy thông tin block mới nhất:

Bạn sẽ thấy thông tin này được inline trực tiếp trong code. Bạn cũng thế viết code để lấy thông tin này, nhưng để đơn giản tôi sẽ inline trực tiếp trong code. Khi các bạn chạy nhớ cập nhật lại thông tin này.

Trong thư viện có sẵn hàm newTransfer() để tạo một giao dịch transfer TRX, nhưng do tên hàm bắt đầu bằng chữ thường nên nó là hàm private, chỉ sử dụng được trong cùng package, package khác không thể gọi được. Vì thế tôi sẽ viết lại hàm này. Ngoài ra bạn có thể sử dụng hàm tron.ParseTxStr() để chuyển dữ liệu mảng byte sang thông tin giao dịch.

Bây giờ chúng ta sẽ tạo tệp transfer-trx.go với nội dung như sau:

// https://pkg.go.dev/github.com/okx/go-wallet-sdk/coins/tron
// https://github.com/okx/go-wallet-sdk/blob/main/coins/tron/tron_test.go
package main

import (
        "encoding/binary"
        "encoding/hex"
        "fmt"
        "time"

        "github.com/btcsuite/btcd/btcec/v2"
        "github.com/golang/protobuf/proto"
        "github.com/golang/protobuf/ptypes"
        "github.com/okx/go-wallet-sdk/coins/tron"
        "github.com/okx/go-wallet-sdk/coins/tron/pb"
)

func NewTransfer(fromAddress string, toAddress string, amount int64, refBlockBytes string, refBlockHash string, expiration int64, timestamp int64) (string, error) {
        owner, err := tron.GetAddressHash(fromAddress)
        if err != nil {
                return "", err
        }
        to, err := tron.GetAddressHash(toAddress)
        if err != nil {
                return "", err
        }
        transferContract := &pb.TransferContract{OwnerAddress: owner, ToAddress: to, Amount: amount}
        param, err := ptypes.MarshalAny(transferContract)
        if err != nil {
                return "", err
        }
        contract := &pb.Transaction_Contract{Type: pb.Transaction_Contract_TransferContract, Parameter: param}
        raw := new(pb.TransactionRaw)
        refBytes, err := hex.DecodeString(refBlockBytes)
        if err != nil {
                return "", err
        }
        raw.RefBlockBytes = refBytes
        refHash, err := hex.DecodeString(refBlockHash)
        if err != nil {
                return "", err
        }
        raw.RefBlockHash = refHash
        raw.Expiration = expiration
        raw.Timestamp = timestamp
        raw.Contract = []*pb.Transaction_Contract{contract}
        trans := pb.Transaction{RawData: raw}
        data, err := proto.Marshal(&trans)
        if err != nil {
                return "", err
        }
        return hex.EncodeToString(data), nil
}

func TransferTrx() {
        currentTime := time.Now()
        pkHex, _ := hex.DecodeString("9499BF78CE4A0217EC48F69AFDBAC19E10E10ACA14C8B278F08A213FA92FC498")
        pk, _ := btcec.PrivKeyFromBytes(pkHex)
        pubKey := pk.PubKey()
        fromAddr := tron.GetAddress(pubKey)
        fmt.Printf("From Address: %s\n", fromAddr)
        fmt.Println("----------------------------------")

        k1 := make([]byte, 8)
        binary.BigEndian.PutUint64(k1, 45900131)
        k2, _ := hex.DecodeString("0000000002bc61630b86cbb9989fa37dbfaa95b01e2c1201a4c723d636041e8c")
        d0, _ := NewTransfer(
                fromAddr,
                "TWYrgz7RDP2NpumQRPY1jBmPKLWVSnrzWZ",
                int64(10000), // 0.01 TRX
                hex.EncodeToString(k1[6:8]),
                hex.EncodeToString(k2[8:16]),
                currentTime.Unix()*1000+3600*1000,
                currentTime.UnixMilli())
        //fmt.Printf("Transfer Raw Data: %s\n", d0)
        fmt.Println("----------------------------------")

        txData0, _ := tron.ParseTxStr(d0)
        fmt.Printf("Transaction Info0: %v\n", txData0)
        fmt.Println("----------------------------------")

        txId, _ := tron.SignStart(d0)
        fmt.Printf("TxId: %s\n", txId)
        fmt.Println("----------------------------------")

        s, _ := tron.Sign(txId, pk)
        fmt.Printf("Signature: %v\n", s)
        fmt.Println("----------------------------------")

        d1, _ := tron.SignEnd(d0, s)
        fmt.Printf("Signed Transaction: %s\n", d1)
        fmt.Println("----------------------------------")

        txData1, _ := tron.ParseTxStr(d1)
        fmt.Printf("Transaction Info1: %v\n", txData1)
        fmt.Println("----------------------------------")
}

func main() {
        TransferTrx()
}

Bây giờ chúng ta chạy tệp này bằng lệnh:

# Cập nhật thư viện (Chỉ cần làm 1 lần)
go mod init tron-go
go mod tidy

# Chạy ứng dụng
go run transfer-trx.go

Sau khi chạy ta được dữ liệu d1 (Signed Transaction): 0a84010a02616322080b86cbb9989fa37d40d0b5ceb4ec315a66080112620a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412310a1541203555fb15bebbdc1a8551a8164e2f6ecebff67a121541e1bfb3fe1dc96903414e8d158b98e52586f3fa4818904e70eedff2b2ec311241269d97ca94717606310b451b3a50f12ed0165fdcb96d52d036d12a69a2edc2024e6eca447185fe55f66b199f03c967ebad4bb0965e99f04136bedd7c7c20139e01

Đóng gói giao dịch transfer TRX

Bây giờ chúng ta viết tệp public-transaction.js bằng NodeJs với nội dung như sau:

// Must using tronweb@5.0.0 trở lên
cconst TronWeb = require('tronweb');

const nodeLink = "https://nile.trongrid.io";

function getTronWeb() {
    let opts = {
        fullNode: nodeLink,
        solidityNode: nodeLink,
        eventServer: nodeLink,
        privateKey: ""
    };
    let tronWeb = new TronWeb(opts);
    return tronWeb;
}

async function publicTransaction(signedData) {
    try {
        let tronWeb = getTronWeb("https://nile.trongrid.io");
        let transaction = await tronWeb.trx.sendHexTransaction(signedData);
        console.log("Transaction:", transaction);
    } catch(ex) {
        console.error("Unable to send signed transaction", ex);
    }
}

async function main() {
    if (process.argv.length<3) {
        console.log("Please run command as below:");
        console.log("    node public-transaction.js <Signed-Data>");
        return 0;
    }

    let signedData = process.argv[2];
    console.log("Signed Data", signedData);
    await publicTransaction(signedData);
}

main();

Chúng ta chạy bằng lệnh sau để đẩy giao dịch lên blockchain:

# Cài đặt thư viện, chỉ cần làm 1 lần
npm i tronweb@5.0.0

# Chạy file để public giao dịch
node public-transaction.js 0a84010a02616322080b86cbb9989fa37d40d0b5ceb4ec315a66080112620a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412310a1541203555fb15bebbdc1a8551a8164e2f6ecebff67a121541e1bfb3fe1dc96903414e8d158b98e52586f3fa4818904e70eedff2b2ec311241269d97ca94717606310b451b3a50f12ed0165fdcb96d52d036d12a69a2edc2024e6eca447185fe55f66b199f03c967ebad4bb0965e99f04136bedd7c7c20139e01

Ta được giao dịch 069e4e55131435012fe6d2b8b82bfd555e5f6c3ddedb07a333402250ca127260

Đẩy giao dịch Transfer TRX lên Nile blockchain

Đóng gói giao dịch chuyển token TRC20 bằng ngôn ngữ Go

Đầu tiên chúng ta cần có TRC20, chúng ta vào link https://nileex.io/join/getJoinPage và thực hiện claim token BTT. Ta có contract token BTT trên Nile: TVSvjZdyDSNocHm7dP3jvCmMNsCnMTPa5W. Bạn nhớ dùng ví trên để claim, hoặc claim bằng ví khác sau đó chuyển BTT vào ví TCuWX3Az4D23vWKcDU442eXFQBm2rsCRke

Chúng ta viết tệp transfer-trc20.go với mã lệnh như sau:

// https://pkg.go.dev/github.com/okx/go-wallet-sdk/coins/tron
// https://github.com/okx/go-wallet-sdk/blob/main/coins/tron/tron_test.go
package main

import (
        "encoding/binary"
        "encoding/hex"
        "fmt"
        "math/big"
        "time"

        "github.com/btcsuite/btcd/btcec/v2"
        "github.com/golang/protobuf/proto"
        "github.com/golang/protobuf/ptypes"
        "github.com/okx/go-wallet-sdk/coins/tron"
        "github.com/okx/go-wallet-sdk/coins/tron/pb"
        "github.com/okx/go-wallet-sdk/coins/tron/token"
)

func NewTRC20TokenTransfer(fromAddress string, toAddress string, contractAddress string, amount *big.Int, feeLimit int64, refBlockBytes string, refBlockHash string, expiration int64, timestamp int64) (string, error) {
        raw := new(pb.TransactionRaw)
        refBytes, err := hex.DecodeString(refBlockBytes)
        if err != nil {
                return "", err
        }
        raw.RefBlockBytes = refBytes
        refHash, err := hex.DecodeString(refBlockHash)
        if err != nil {
                return "", err
        }
        raw.RefBlockHash = refHash
        raw.Expiration = expiration
        raw.Timestamp = timestamp

        fromAddressHash, err := tron.GetAddressHash(fromAddress)
        if err != nil {
                return "", err
        }
        toAddressHash, err := tron.GetAddressHash(toAddress)
        if err != nil {
                return "", err
        }
        contractAddressHash, err := tron.GetAddressHash(contractAddress)
        if err != nil {
                return "", err
        }
        input, err := token.Transfer(hex.EncodeToString(toAddressHash), amount)
        if err != nil {
                return "", err
        }
        transferContract := &pb.TriggerSmartContract{OwnerAddress: fromAddressHash, ContractAddress: contractAddressHash, CallValue: 0, CallTokenValue: 0, Data: input}
        param, err := ptypes.MarshalAny(transferContract)
        if err != nil {
                return "", err
        }

        contract := &pb.Transaction_Contract{Type: pb.Transaction_Contract_TriggerSmartContract, Parameter: param}
        raw.FeeLimit = feeLimit

        raw.Contract = []*pb.Transaction_Contract{contract}
        trans := pb.Transaction{RawData: raw}
        data, err := proto.Marshal(&trans)
        if err != nil {
                return "", err
        }
        return hex.EncodeToString(data), nil
}

func TransferTrc20() {
        currentTime := time.Now()
        pkHex, _ := hex.DecodeString("9499BF78CE4A0217EC48F69AFDBAC19E10E10ACA14C8B278F08A213FA92FC498")
        pk, _ := btcec.PrivKeyFromBytes(pkHex)
        pubKey := pk.PubKey()
        fromAddr := tron.GetAddress(pubKey)
        fmt.Printf("From Address: %s\n", fromAddr)
        fmt.Println("----------------------------------")

        // Amount: 8 BTT (8*10^18)
        amount := big.NewInt(10)
        amount.Exp(amount, big.NewInt(18), nil)
        amount.Mul(amount, big.NewInt(8))

        k1 := make([]byte, 8)
        binary.BigEndian.PutUint64(k1, 45903239)
        k2, _ := hex.DecodeString("0000000002bc6d873f0c8de58a60c81183362cd78a7bd9528e783fecdf111be4")
        contractAddress := "TVSvjZdyDSNocHm7dP3jvCmMNsCnMTPa5W" // BTT
        d0, _ := NewTRC20TokenTransfer(
                fromAddr,
                "TWXKV19GnweWQzFPJckKHbCgeSRUMMowHz",
                contractAddress,
                amount,
                int64(100000000),
                hex.EncodeToString(k1[6:8]),
                hex.EncodeToString(k2[8:16]),
                currentTime.Unix()*1000+3600*1000,
                currentTime.UnixMilli())
        fmt.Printf("Transfer Raw Data: %s\n", d0)
        fmt.Println("----------------------------------")

        txData0, _ := tron.ParseTxStr(d0)
        fmt.Printf("Transaction Info0: %v\n", txData0)
        fmt.Println("----------------------------------")

        txId, _ := tron.SignStart(d0)
        fmt.Printf("TxId: %s\n", txId)
        fmt.Println("----------------------------------")

        s, _ := tron.Sign(d0, pk)
        fmt.Printf("Signature: %v\n", s)
        d1, _ := tron.SignEnd(d0, s)
        fmt.Printf("Signed Transaction: %s\n", d1)
        fmt.Println("----------------------------------")

        txData1, _ := tron.ParseTxStr(d1)
        fmt.Printf("Transaction Info1: %v\n", txData1)
        fmt.Println("----------------------------------")
}

func main() {
        TransferTrc20()
}

Đánh lệnh sau để chạy:

go run transfer-trc20.go

Sau khi chạy ta được dữ liệu d1 (Signed Transaction):

0ad3010a0270012208ff0df89c11ae035240e0e7f2b9ec315aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a1541203555fb15bebbdc1a8551a8164e2f6ecebff67a121541d5a8752a5fc64a1ce09df7b195df6b669d09271f2244a9059cbb000000000000000000000041e1753cb82b1a4ab5b872e44a3de4bac5530298740000000000000000000000000000000000000000000000006f05b59d3b20000070f18c97b8ec31900180c2d72f124125fba935e01699597d470cffabaa9d9ad5b61a8ef63d9cc57691145c5a778f387ec0b5685686a353378011d692dd5ce2aa9b83a77a2378c5bb9ba97abca9897701

Ta chạy ứng dụng node để gửi giao dịch lên blockchain:

node public-transaction.js 0ad3010a0270012208ff0df89c11ae035240e0e7f2b9ec315aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a1541203555fb15bebbdc1a8551a8164e2f6ecebff67a121541d5a8752a5fc64a1ce09df7b195df6b669d09271f2244a9059cbb000000000000000000000041e1753cb82b1a4ab5b872e44a3de4bac5530298740000000000000000000000000000000000000000000000006f05b59d3b20000070f18c97b8ec31900180c2d72f124125fba935e01699597d470cffabaa9d9ad5b61a8ef63d9cc57691145c5a778f387ec0b5685686a353378011d692dd5ce2aa9b83a77a2378c5bb9ba97abca9897701

Ta được giao dịch b05b3234bc235c7435d5f3ef2e4e65622361c340871b0ab3a87995e408a0332e

Đóng gói giao dịch swap bằng ngôn ngữ Go

Bây giờ chúng ta sẽ thực hiện một giao dịch swap từ 100 TRX sang USDT trên SunswapRouterV2 thông qua hàm swapExactETHForTokens(). Chúng ta cần biết một số địa chỉ:

Đầu tiên chúng ta nhớ chuyển 200 TRX tới địa chỉ TCuWX3Az4D23vWKcDU442eXFQBm2rsCRke, sau đó chúng ta encode hàm swapExactETHForTokens():
swapExactETHForTokens(0, [TYsbWxNnyTgsZaTFaue9hqpxkU3Fkco94a, TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf], TCuWX3Az4D23vWKcDU442eXFQBm2rsCRke, “9999999999999”)
Ta được:
7ff36ab500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000203555fb15bebbdc1a8551a8164e2f6ecebff67a000000000000000000000000000000000000000000000000000009184e729fff0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000fb3b3134f13ccd2c81f4012e53024e8135d58fee000000000000000000000000eca9bc828a3005b9a3b909f2cc5c2a54794de05f
Dữ liệu này sẽ được sử dụng trong code.

Bây giờ ta tạo tệp tron-swap.go với mã lệnh như sau:

// https://pkg.go.dev/github.com/okx/go-wallet-sdk/coins/tron
// https://github.com/okx/go-wallet-sdk/blob/main/coins/tron/tron_test.go
package main

import (
        "encoding/binary"
        "encoding/hex"
        "fmt"
        "time"

        "github.com/btcsuite/btcd/btcec/v2"
        "github.com/golang/protobuf/proto"
        "github.com/golang/protobuf/ptypes"
        "github.com/okx/go-wallet-sdk/coins/tron"
        "github.com/okx/go-wallet-sdk/coins/tron/pb"
)

func NewTransaction(fromAddress string, contractAddress string, callValue int64, inputData string, feeLimit int64, refBlockBytes string, refBlockHash string, expiration int64, timestamp int64) (string, error) {
        raw := new(pb.TransactionRaw)
        refBytes, err := hex.DecodeString(refBlockBytes)
        if err != nil {
                return "", err
        }
        raw.RefBlockBytes = refBytes
        refHash, err := hex.DecodeString(refBlockHash)
        if err != nil {
                return "", err
        }
        raw.RefBlockHash = refHash
        raw.Expiration = expiration
        raw.Timestamp = timestamp

        fromAddressHash, err := tron.GetAddressHash(fromAddress)
        if err != nil {
                return "", err
        }
        contractAddressHash, err := tron.GetAddressHash(contractAddress)
        if err != nil {
                return "", err
        }
        input, err := hex.DecodeString(inputData)
        if err != nil {
                return "", err
        }
        transactionContract := &pb.TriggerSmartContract{OwnerAddress: fromAddressHash, ContractAddress: contractAddressHash, CallValue: callValue, CallTokenValue: 0, Data: input}
        param, err := ptypes.MarshalAny(transactionContract)
        if err != nil {
                return "", err
        }

        contract := &pb.Transaction_Contract{Type: pb.Transaction_Contract_TriggerSmartContract, Parameter: param}
        raw.FeeLimit = feeLimit

        raw.Contract = []*pb.Transaction_Contract{contract}
        trans := pb.Transaction{RawData: raw}
        data, err := proto.Marshal(&trans)
        if err != nil {
                return "", err
        }
        return hex.EncodeToString(data), nil
}

// Swap from TRX to USDT on SunSwapV2 on Nile
func SwapToken() {
        currentTime := time.Now()
        pkHex, _ := hex.DecodeString("9499BF78CE4A0217EC48F69AFDBAC19E10E10ACA14C8B278F08A213FA92FC498")
        pk, _ := btcec.PrivKeyFromBytes(pkHex)
        pubKey := pk.PubKey()
        fromAddr := tron.GetAddress(pubKey)
        fmt.Printf("From Address: %s\n", fromAddr)
        fmt.Println("----------------------------------")

        // swapExactETHForTokens(0, [TYsbWxNnyTgsZaTFaue9hqpxkU3Fkco94a, TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf], TCuWX3Az4D23vWKcDU442eXFQBm2rsCRke, "9999999999999")
        data := "7ff36ab500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000203555fb15bebbdc1a8551a8164e2f6ecebff67a000000000000000000000000000000000000000000000000000009184e729fff0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000fb3b3134f13ccd2c81f4012e53024e8135d58fee000000000000000000000000eca9bc828a3005b9a3b909f2cc5c2a54794de05f"

        k1 := make([]byte, 8)
        binary.BigEndian.PutUint64(k1, 45905108)
        k2, _ := hex.DecodeString("0000000002bc74d4cc668e76adb0c91a03ee8136b0a315dc3d49a8d0a0f76d73")
        contractAddress := "TMn1qrmYUMSTXo9babrJLzepKZoPC7M6Sy" // UniswapV2Router02
        d0, _ := NewTransaction(
                fromAddr,
                contractAddress,
                int64(100000000), // 100 TRX
                data,
                int64(75000000), // Fee Limit: 75 TRX
                hex.EncodeToString(k1[6:8]),
                hex.EncodeToString(k2[8:16]),
                currentTime.Unix()*1000+3600*1000,
                currentTime.UnixMilli())
        fmt.Printf("Transaction Raw Data: %s\n", d0)
        fmt.Println("----------------------------------")

        txData0, _ := tron.ParseTxStr(d0)
        fmt.Printf("Transaction Info0: %v\n", txData0)
        fmt.Println("----------------------------------")

        txId, _ := tron.SignStart(d0)
        fmt.Printf("TxId: %s\n", txId)
        fmt.Println("----------------------------------")

        s, _ := tron.Sign(txId, pk)
        fmt.Printf("Signature: %v\n", s)
        fmt.Println("----------------------------------")

        d1, _ := tron.SignEnd(d0, s)
        fmt.Printf("Signed Transaction: %s\n", d1)
        fmt.Println("----------------------------------")

        txData1, _ := tron.ParseTxStr(d1)
        fmt.Printf("Transaction Info1: %v\n", txData1)
        fmt.Println("----------------------------------")
}

func main() {
        SwapToken()
}

Ta đánh lệnh sau để chạy:

go run tron-swap.go

Sau khi chạy ta được dữ liệu d1 (Signed Transaction):

0afa020a0274d42208cc668e76adb0c91a409880c0bcec315ad502081f12d0020a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e7472616374129a020a1541203555fb15bebbdc1a8551a8164e2f6ecebff67a12154181839e7bccdc7d5f50419bc34209d8ae5969ef661880c2d72f22e4017ff36ab500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000203555fb15bebbdc1a8551a8164e2f6ecebff67a000000000000000000000000000000000000000000000000000009184e729fff0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000fb3b3134f13ccd2c81f4012e53024e8135d58fee000000000000000000000000eca9bc828a3005b9a3b909f2cc5c2a54794de05f7092a4e4baec319001c0d1e1231241f6b3c6f4a966ddf2024a8dc61bad55281e980609b87032d3308138ca790202745789f86120f2b7b8af71962a0eacf53758686a9ca9ffed05c632c588bc2619d001

Ta chạy ứng dụng node để gửi giao dịch lên blockchain:

node public-transaction.js 0afa020a0274d42208cc668e76adb0c91a409880c0bcec315ad502081f12d0020a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e7472616374129a020a1541203555fb15bebbdc1a8551a8164e2f6ecebff67a12154181839e7bccdc7d5f50419bc34209d8ae5969ef661880c2d72f22e4017ff36ab500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000203555fb15bebbdc1a8551a8164e2f6ecebff67a000000000000000000000000000000000000000000000000000009184e729fff0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000fb3b3134f13ccd2c81f4012e53024e8135d58fee000000000000000000000000eca9bc828a3005b9a3b909f2cc5c2a54794de05f7092a4e4baec319001c0d1e1231241f6b3c6f4a966ddf2024a8dc61bad55281e980609b87032d3308138ca790202745789f86120f2b7b8af71962a0eacf53758686a9ca9ffed05c632c588bc2619d001

Ta được giao dịch: 56051aa9e249279877b8bd49d228a17ba782bebee49e2bfa1b3007917da3be26

Bài viết này có hữu ích với bạn?

Kích vào một biểu tượng ngôi sao để đánh giá bài viết!

Xếp hạng trung bình 5 / 5. Số phiếu: 68

Bài viết chưa có đánh giá! Hãy là người đầu tiên đánh giá bài viết này.

Trả lời

Giao diện bởi Anders Norén