gotron-sdk的简要介绍
gotron-sdk是基于gRPC的Go SDK实现和cli工具
这东西看起来大多数人都是作cli使用,如果想要拿来当go-ethereum
,没有任何文档的可以用来参考,唯一能做的,只能翻源码……
为了让更多人少踩坑,特作此简易教程,愿能帮助到深受波场毒害的科学家们(
连接到gRPC节点
gotron-sdk
仅支持gRPC方式的连接
NewGrpcClient
方法可以传入gRPC地址,默认将Start
时使用grpc.trongrid.io:50051
,返回GrpcClient
实例
请注意,NewGrpcClient
并不会真正建立RPC连接,需要调用Start
方法,可变参为grpc.DialOption
import "github.com/fbsobreira/gotron-sdk/pkg/client"
rpcClient := client.NewGrpcClient("")
err := rpcClient.Start(grpc.WithInsecure())
地址转换
波场地址以大写字母 T 开头,是以太坊地址前增加字节 0x41 后 Base58check
得到的,共34位字符
import "github.com/fbsobreira/gotron-sdk/pkg/address"
addr, err := address.Base58ToAddress("TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t")
log.Println(addr.String())
另:gotron-sdk
中大多数对外方法都使用string
,并且在每个方法中都调用Base58ToAddress
私钥导入
需要注意下列方法导入并非临时使用,而是真的导入了本地存储,之后可以凭借钱包地址与密码直接使用
import "github.com/fbsobreira/gotron-sdk/pkg/account"
accountName, err := account.ImportFromPrivateKey(privateKey, "", accountPassword)
accountName, err := account.ImportKeyStore("keystoreFilePath", "", accountPassword)
TODO
:目前没有找到临时使用的方法
合约调用
调用无参constant方法
调用TRC20代币的name()
查询代币名称,这里以USDT为例
为展示TRC20Call的用法,这里不使用已经封装好的TRC20GetName
import "github.com/fbsobreira/gotron-sdk/pkg/common"
// 获得方法名的SHA-3
nameSign := common.BytesToHexString(abi.Signature("name()"))
result, err := rpcClient.TRC20Call("", "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", nameSign, true, 0)
if err != nil {
log.Println(err)
return
}
data, _ := rpcClient.ParseTRC20StringProperty(common.BytesToHexString(result.GetConstantResult()[0]))
log.Println(data)
调用有参与需要签名的方法
没有文档,真的坑啊!这里演示如何与有参数、需要签名的方法进行交互
参数的构建
在client的TriggerContract
方法里,有jsonString
这样一个奇怪的参数……常规来说,这肯定是ABI的参数,但是,怎么用,这是个问题(
阅读abi.LoadFromJSON
与abi.GetPaddedParam
的源码,可以确定,这个jsonString应该长成这样:
// ABI(有简化
{
"inputs": [
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transfer"
}
// jsonString是以类型为key,值为value的数组,且uint应使用字符串类型
[
{
"address": "TWRhFW2AQg8Ae2j8BynFnGNfj7xg95qhvQ"
},
{
"uint256": "100000"
}
]
以transfer为例
本例调用USDT的transfer方法对其他地址进行转账,直接上代码,为了简洁err省略,实际使用还请认真处理
一定要注意,TriggerContract
方法并不会发送Tx,这可以说是这个包最坑的地方了
// 携带的数据
triggerData := "[{\"address\":\"TWRhFW2AQg8Ae2j8BynFnGNfj7xg95qhvQ\"},{\"uint256\":\"100000\"}]"
// 构建Tx,注意,此处只是构造,tx并没有被发送
// 参数分别为 发送者地址 合约地址 调用方法(正常字符串) gas Tx发送的TRX数量 Tx发送的TRC20代币 代币数量
tx, _ := rpcClient.TriggerContract(wallet, contract, "transfer(address,uint256)", triggerData, 300000000, 0, "", 0)
// 获得keystore与account
ks, acct, _ := store.UnlockedKeystore(wallet, accountPassword)
// 封装Tx
ctrlr := transaction.NewController(rpcClient, ks, acct, tx.Transaction)
// 真正执行Tx,并判断执行结果
if err = ctrlr.ExecuteTransaction(); err != nil {
log.Println(err.Error())
return
}
// 此时Tx才上链
log.Println(common.BytesToHexString(tx.GetTxid()))
log.Println(common.BytesToHexString(tx.GetResult().GetMessage()))
调用 btcec 的 PrivKeyFromBytes() 来临时使用 私钥, 而不导入本地.
Eric 2024-11-09 18:30
看了Trc20Send,貌似可以手动构建data然后调用Trc20Call,谢谢楼主
Aptx 2023-10-26 07:18
调用transferFrom其中有两个address参数如何编写jsonString啊
Aptx 2023-10-26 07:15
TODO:目前没有找到临时使用的方法
可以调用account.RemoveAccount(name)删除本地存储的account
黄 2023-03-14 18:08