使用Go语言构建TronLink钱包SDK-完整指南与源码
使用Go语言构建TronLink钱包SDK-完整指南与源码
本文将详细介绍如何使用Go语言构建一个与TronLink兼容的钱包SDK。这个实现将允许你的Go应用程序与Tron区块链交互,包括创建账户、查询余额、发送TRX和TRC20代币等功能。
什么是TronLink钱包?
TronLink是波场(TRON)区块链上最受欢迎的钱包之一,类似于以太坊的MetaMask。它允许用户在浏览器中管理TRON账户,并与DApps交互。本文将展示如何用Go语言构建一个类似功能的SDK。
准备工作
在开始之前,确保你已经安装了以下工具:
1.Go1.16或更高版本
2.TronGridAPI密钥(可从https://www.trongrid.io/获取)
3.基本的区块链和加密知识
核心功能实现
1.项目结构
首先创建项目目录结构:
tronlink-go/
├──go.mod
├──go.sum
├──main.go
├──wallet/
│├──account.go
│├──client.go
│├──contract.go
│└──transaction.go
└──utils/
├──crypto.go
└──helper.go
2.初始化Go模块
gomodinitgithub.com/yourusername/tronlink-go
3.核心代码实现
wallet/account.go-账户管理
packagewallet
import(
"crypto/ecdsa"
"encoding/hex"
"fmt"
"log"
"github.com/ethereum/go-ethereum/crypto"
"github.com/fbsobreira/gotron-sdk/pkg/address"
"github.com/fbsobreira/gotron-sdk/pkg/common"
)
//AccountrepresentsaTRONaccount
typeAccountstruct{
PrivateKeyecdsa.PrivateKey
Addressaddress.Address
}
//NewAccountcreatesanewTRONaccount
funcNewAccount()(Account,error){
privateKey,err:=crypto.GenerateKey()
iferr!=nil{
returnnil,fmt.Errorf("failedtogenerateprivatekey:%v",err)
}
return&Account{
PrivateKey:privateKey,
Address:address.PubkeyToAddress(privateKey.PublicKey),
},nil
}
//FromPrivateKeycreatesanaccountfromexistingprivatekey
funcFromPrivateKey(hexKeystring)(Account,error){
privateKey,err:=crypto.HexToECDSA(hexKey)
iferr!=nil{
returnnil,fmt.Errorf("invalidprivatekey:%v",err)
}
return&Account{
PrivateKey:privateKey,
Address:address.PubkeyToAddress(privateKey.PublicKey),
},nil
}
//GetAddressreturnsthebase58encodedaddress
func(aAccount)GetAddress()string{
returna.Address.String()
}
//GetPrivateKeyreturnsthehexencodedprivatekey
func(aAccount)GetPrivateKey()string{
returnhex.EncodeToString(crypto.FromECDSA(a.PrivateKey))
}
//GetPublicKeyreturnsthehexencodedpublickey
func(aAccount)GetPublicKey()string{
returnhex.EncodeToString(crypto.FromECDSAPub(&a.PrivateKey.PublicKey))
}
//PrintAccountInfodisplaysaccountdetails
func(aAccount)PrintAccountInfo(){
log.Println("TRONAccountInformation:")
log.Println("Address(Base58):",a.GetAddress())
log.Println("Address(Hex):",common.BytesToHexString(a.Address.Bytes()))
log.Println("PrivateKey:",a.GetPrivateKey())
log.Println("PublicKey:",a.GetPublicKey())
}
wallet/client.go-TRON网络交互
packagewallet
import(
"context"
"fmt"
"log"
"math/big"
"time"
"github.com/fbsobreira/gotron-sdk/pkg/client"
"github.com/fbsobreira/gotron-sdk/pkg/proto/api"
"github.com/fbsobreira/gotron-sdk/pkg/proto/core"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
//TronClientrepresentsaconnectiontotheTRONnetwork
typeTronClientstruct{
client.GrpcClient
APIKeystring
}
//NewTronClientcreatesanewTRONclient
funcNewTronClient(nodeURL,apiKeystring)(TronClient,error){
conn:=client.NewGrpcClient(nodeURL)
iferr:=conn.Start(grpc.WithTransportCredentials(insecure.NewCredentials()));err!=nil{
returnnil,fmt.Errorf("failedtoconnecttoTRONnode:%v",err)
}
return&TronClient{
GrpcClient:conn,
APIKey:apiKey,
},nil
}
//GetAccountBalancereturnstheTRXbalanceofanaccount
func(tcTronClient)GetAccountBalance(addressstring)(big.Int,error){
acc,err:=tc.GetAccount(address)
iferr!=nil{
returnnil,fmt.Errorf("failedtogetaccount:%v",err)
}
ifacc==nil||acc.Balance==0{
returnbig.NewInt(0),nil
}
returnbig.NewInt(acc.Balance),nil
}
//GetTRC20BalancereturnsthebalanceofaTRC20token
func(tcTronClient)GetTRC20Balance(contractAddress,walletAddressstring)(big.Int,error){
ctx,cancel:=context.WithTimeout(context.Background(),10time.Second)
defercancel()
param:=&core.TriggerSmartContract{
ContractAddress:address.HexToAddress(contractAddress).Bytes(),
OwnerAddress:address.HexToAddress(walletAddress).Bytes(),
Data:[]byte("balanceOf(address)"),
}
result,err:=tc.TriggerConstantContract(ctx,param)
iferr!=nil{
returnnil,fmt.Errorf("failedtotriggercontract:%v",err)
}
ifresult.ConstantResult==nil||len(result.ConstantResult)==0{
returnbig.NewInt(0),nil
}
balance:=new(big.Int).SetBytes(result.ConstantResult[0])
returnbalance,nil
}
//GetBlockNumberreturnsthelatestblocknumber
func(tcTronClient)GetBlockNumber()(int64,error){
block,err:=tc.GetNowBlock()
iferr!=nil{
return0,fmt.Errorf("failedtogetcurrentblock:%v",err)
}
returnblock.BlockHeader.RawData.Number,nil
}
//GetTransactionInforetrievestransactiondetails
func(tcTronClient)GetTransactionInfo(txIDstring)(core.TransactionInfo,error){
tx,err:=tc.GetTransactionInfoByID(txID)
iferr!=nil{
returnnil,fmt.Errorf("failedtogettransactioninfo:%v",err)
}
returntx,nil
}
wallet/transaction.go-交易处理
packagewallet
import(
"context"
"crypto/ecdsa"
"fmt"
"math/big"
"time"
"github.com/ethereum/go-ethereum/crypto"
"github.com/fbsobreira/gotron-sdk/pkg/address"
"github.com/fbsobreira/gotron-sdk/pkg/common"
"github.com/fbsobreira/gotron-sdk/pkg/proto/core"
"google.golang.org/protobuf/proto"
)
//SendTRXsendsTRXfromoneaccounttoanother
func(tcTronClient)SendTRX(fromAccount,toAddressstring,amountbig.Int)(string,error){
to:=address.HexToAddress(toAddress)
ifto==nil{
return"",fmt.Errorf("invalidrecipientaddress")
}
tx,err:=tc.Transfer(from.Address.String(),to.String(),amount.Int64())
iferr!=nil{
return"",fmt.Errorf("failedtocreatetransfertransaction:%v",err)
}
signedTx,err:=SignTransaction(tx.Transaction,from.PrivateKey)
iferr!=nil{
return"",fmt.Errorf("failedtosigntransaction:%v",err)
}
result,err:=tc.Broadcast(context.Background(),signedTx)
iferr!=nil{
return"",fmt.Errorf("failedtobroadcasttransaction:%v",err)
}
ifresult.Code!=api.Return_SUCCESS{
return"",fmt.Errorf("transactionfailed:%s",result.Message)
}
returncommon.BytesToHexString(tx.GetTxid()),nil
}
//SignTransactionsignsaTRONtransaction
funcSignTransaction(txcore.Transaction,privateKeyecdsa.PrivateKey)(core.Transaction,error){
rawData,err:=proto.Marshal(tx.GetRawData())
iferr!=nil{
returnnil,fmt.Errorf("failedtomarshaltransactionrawdata:%v",err)
}
h256h:=crypto.Keccak256(rawData)
signature,err:=crypto.Sign(h256h,privateKey)
iferr!=nil{
returnnil,fmt.Errorf("failedtosigntransaction:%v",err)
}
tx.Signature=append(tx.Signature,signature)
returntx,nil
}
//SendTRC20sendsTRC20tokens
func(tcTronClient)SendTRC20(fromAccount,contractAddress,toAddressstring,amountbig.Int)(string,error){
ctx,cancel:=context.WithTimeout(context.Background(),10time.Second)
defercancel()
param:=&core.TriggerSmartContract{
ContractAddress:address.HexToAddress(contractAddress).Bytes(),
OwnerAddress:from.Address.Bytes(),
Data:generateTRC20TransferData(toAddress,amount),
}
result,err:=tc.TriggerContract(ctx,param)
iferr!=nil{
return"",fmt.Errorf("failedtotriggercontract:%v",err)
}
ifresult.Result.Code!=core.Transaction_Result_SUCCESS{
return"",fmt.Errorf("contractexecutionfailed:%s",result.Result.Message)
}
signedTx,err:=SignTransaction(result.Transaction,from.PrivateKey)
iferr!=nil{
return"",fmt.Errorf("failedtosigntransaction:%v",err)
}
broadcastResult,err:=tc.Broadcast(context.Background(),signedTx)
iferr!=nil{
return"",fmt.Errorf("failedtobroadcasttransaction:%v",err)
}
ifbroadcastResult.Code!=api.Return_SUCCESS{
return"",fmt.Errorf("transactionfailed:%s",broadcastResult.Message)
}
returncommon.BytesToHexString(result.Transaction.GetTxid()),nil
}
funcgenerateTRC20TransferData(toAddressstring,amountbig.Int)[]byte{
methodID:=[]byte{0xa9,0x05,0x9c,0xbb}//transfer(address,uint256)
toAddr:=common.HexToAddress(toAddress)
paddedTo:=common.LeftPadBytes(toAddr.Bytes(),32)
paddedAmount:=common.LeftPadBytes(amount.Bytes(),32)
data:=append(methodID,paddedTo...)
data=append(data,paddedAmount...)
returndata
}
utils/crypto.go-加密工具
packageutils
import(
"crypto/ecdsa"
"encoding/hex"
"fmt"
"github.com/ethereum/go-ethereum/crypto"
"github.com/fbsobreira/gotron-sdk/pkg/address"
)
//PrivateKeyToAddressconvertsaprivatekeytoTRONaddress
funcPrivateKeyToAddress(privateKeyHexstring)(string,error){
privateKey,err:=crypto.HexToECDSA(privateKeyHex)
iferr!=nil{
return"",fmt.Errorf("invalidprivatekey:%v",err)
}
addr:=address.PubkeyToAddress(privateKey.PublicKey)
returnaddr.String(),nil
}
//ValidateAddresschecksifaTRONaddressisvalid
funcValidateAddress(addrstring)bool{
_,err:=address.Base58ToAddress(addr)
returnerr==nil
}
//HexToPrivateKeyconvertshexstringtoECDSAprivatekey
funcHexToPrivateKey(hexKeystring)(ecdsa.PrivateKey,error){
returncrypto.HexToECDSA(hexKey)
}
//PrivateKeyToHexconvertsECDSAprivatekeytohexstring
funcPrivateKeyToHex(privateKeyecdsa.PrivateKey)string{
returnhex.EncodeToString(crypto.FromECDSA(privateKey))
}
4.主程序示例
packagemain
import(
"fmt"
"log"
"math/big"
"github.com/yourusername/tronlink-go/wallet"
)
funcmain(){
//1.InitializeTRONclient
//UseTronGridmainnetnode
tronClient,err:=wallet.NewTronClient("grpc.trongrid.io:50051","your-api-key")
iferr!=nil{
log.Fatalf("FailedtocreateTRONclient:%v",err)
}
defertronClient.Stop()
//2.Createanewaccount
newAccount,err:=wallet.NewAccount()
iferr!=nil{
log.Fatalf("Failedtocreatenewaccount:%v",err)
}
newAccount.PrintAccountInfo()
//3.Orimportexistingaccount
//privateKey:="your_private_key_hex"
//existingAccount,err:=wallet.FromPrivateKey(privateKey)
//iferr!=nil{
//log.Fatalf("Failedtoimportaccount:%v",err)
//}
//4.Checkbalance
balance,err:=tronClient.GetAccountBalance(newAccount.GetAddress())
iferr!=nil{
log.Fatalf("Failedtogetbalance:%v",err)
}
fmt.Printf("Accountbalance:%sTRX\n",balance.String())
//5.Example:SendTRX(needtofundtheaccountfirst)
//recipient:="TRON_RECIPIENT_ADDRESS"
//amount:=big.NewInt(1000000)//1TRX=1,000,000sun
//txID,err:=tronClient.SendTRX(newAccount,recipient,amount)
//iferr!=nil{
//log.Fatalf("FailedtosendTRX:%v",err)
//}
//fmt.Printf("Transactionsent!TXID:%s\n",txID)
//6.Example:CheckTRC20tokenbalance
//usdtContract:="TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"//USDTcontractonTRON
//tokenBalance,err:=tronClient.GetTRC20Balance(usdtContract,newAccount.GetAddress())
//iferr!=nil{
//log.Fatalf("FailedtogetTRC20balance:%v",err)
//}
//fmt.Printf("USDTbalance:%s\n",tokenBalance.String())
}
功能扩展
1.添加TRC20代币支持
//wallet/contract.go
packagewallet
import(
"math/big"
"strings"
"github.com/fbsobreira/gotron-sdk/pkg/address"
"github.com/fbsobreira/gotron-sdk/pkg/common"
)
//TRC20TokenrepresentsaTRC20tokencontract
typeTRC20Tokenstruct{
ContractAddressstring
Namestring
Symbolstring
Decimalsuint8
ClientTronClient
}
//NewTRC20TokencreatesanewTRC20Tokeninstance
funcNewTRC20Token(contractAddressstring,clientTronClient)(TRC20Token,error){
token:=&TRC20Token{
ContractAddress:contractAddress,
Client:client,
}
//Fetchtokendetails
varerrerror
token.Name,err=token.getName()
iferr!=nil{
returnnil,fmt.Errorf("failedtogettokenname:%v",err)
}
token.Symbol,err=token.getSymbol()
iferr!=nil{
returnnil,fmt.Errorf("failedtogettokensymbol:%v",err)
}
decimals,err:=token.getDecimals()
iferr!=nil{
returnnil,fmt.Errorf("failedtogettokendecimals:%v",err)
}
token.Decimals=decimals
returntoken,nil
}
func(tTRC20Token)getName()(string,error){
data:=[]byte("name()")
result,err:=t.Client.triggerConstantContract(t.ContractAddress,data)
iferr!=nil{
return"",err
}
returnstring(result),nil
}
func(tTRC20Token)getSymbol()(string,error){
data:=[]byte("symbol()")
result,err:=t.Client.triggerConstantContract(t.ContractAddress,data)
iferr!=nil{
return"",err
}
returnstrings.TrimSpace(string(result)),nil
}
func(tTRC20Token)getDecimals()(uint8,error){
data:=[]byte("decimals()")
result,err:=t.Client.triggerConstantContract(t.ContractAddress,data)
iferr!=nil{
return0,err
}
returnuint8(new(big.Int).SetBytes(result).Uint64()),nil
}
func(tTRC20Token)BalanceOf(addressstring)(big.Int,error){
data:=generateBalanceOfData(address)
result,err:=t.Client.triggerConstantContract(t.ContractAddress,data)
iferr!=nil{
returnnil,err
}
returnnew(big.Int).SetBytes(result),nil
}
funcgenerateBalanceOfData(addressstring)[]byte{
methodID:=[]byte{0x70,0xa0,0x82,0x31}//balanceOf(address)
addr:=common.HexToAddress(address)
paddedAddr:=common.LeftPadBytes(addr.Bytes(),32)
returnappend(methodID,paddedAddr...)
}
func(tTRC20Token)Transfer(fromAccount,toAddressstring,amountbig.Int)(string,error){
returnt.Client.SendTRC20(from,t.ContractAddress,toAddress,amount)
}
2.添加事件监听功能
//wallet/
转载请注明出处: TronLink官网下载-TRON-TRX-波场-波比-波币-波宝|官网-钱包-苹果APP|安卓-APP-下载
本文的链接地址: https://tianjinfa.org/post/3273
扫描二维码,在手机上阅读
文章作者:
文章标题:使用Go语言构建TronLink钱包SDK-完整指南与源码
文章链接:https://tianjinfa.org/post/3273
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明来自 !
文章标题:使用Go语言构建TronLink钱包SDK-完整指南与源码
文章链接:https://tianjinfa.org/post/3273
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明来自 !
打赏
如果觉得文章对您有用,请随意打赏。
您的支持是我们继续创作的动力!
微信扫一扫
支付宝扫一扫
您可能对以下文章感兴趣
-
TronLink钱包集成开发指南
12小时前
-
TronLink钱包集成指南:使用JavaScript连接TRON区块链
4小时前
-
TronLink钱包HTML5实现方案-原创SEO优化教程
4小时前
-
使用Go语言实现TronLink钱包功能
4小时前
-
原创TronLink钱包HTML5实现方案-SEO优化版
12小时前
-
TronLink钱包集成开发指南:使用PHP+CSS+JS+HTML5+JSON实现
12小时前
-
使用Go语言构建TronLink钱包:完整源码与实现指南
13小时前
-
TronLink钱包Web版实现(无MySQL)
13小时前
-
TronLink钱包集成开发指南
6小时前
-
使用JavaScript开发TRONLink钱包集成指南
8小时前