本文已默认阅读者有一定基础知识
一、介绍
Sui Gas Pool是一个服务,它支持在Sui网络上进行大规模的赞助交易。它管理一个由赞助地址拥有的gas币的数据库,并提供API来预留gas币和使用它们来支付交易费用。通过管理池中的大量gas币对象,它实现了可伸缩性和高吞吐量,因此可以同时赞助大量交易。
二、安装与启动Sui Gas Pool服务
1. 环境配置
1)安装Rust和Redis环境
2)编译Sui Gas Pool
拉取Sui Gas Pool代码
git clone https://github.com/MystenLabs/sui-gas-pool.git
打包代码
cd sui-gas-pool
cargo build --release
3)生成与修改配置文件
./target/release/tool generate-sample-config --config-path sample.yaml
可以看到sample.yaml
文件内容,官方readme有个sidecar,太麻烦不用了,直接用内存私钥干
---
signer-config:
local:
keypair:
rpc-host-ip: 0.0.0.0
rpc-port: 9527
metrics-port: 9184
gas-pool-config:
redis:
redis_url: "redis://127.0.0.1"
fullnode-url: "https://fullnode.testnet.sui.io:443"
coin-init-config:
target-init-balance: 100000000
refresh-interval-sec: 86400
daily-gas-usage-cap: 1500000000000
参数解释:
- keypair: 用钱包私钥可以转,下面会给方法
- rpc-host-ip: gas pool的rpc服务ip, 通常就是 0.0.0.0
- rpc-port: rpc服务端口
- metrics-port: 监控服务可以访问并获取指标数据和日志记录的端口
- redis_url: redis服务地址
- fullnode-url: gas pool所处sui环境的rpc地址
- coin-init-config
-
target-init-balance: 每个gas的初始余额可以给 100000000
也就是 0.1 SUI, gas pool 会在初始化的时候把赞助钱包的币按照这个进行分割
image.png refresh-interval-sec: 定时查看赞助钱包的所有gas币,看看是否有新增
-
- daily-gas-usage-cap: 每天允许使用的gas总量,作为安全上限
生成keypair的方法:
首先,从钱包或者命令行获取primarykey
然后,通过tssdk,生成keypair
import { decodeSuiPrivateKey } from "@mysten/sui/cryptography"
import { toBase64 } from "@mysten/sui/utils"
const sui_key_to_gas_station = (sui_priv_key: string) => {
const { schema, secretKey } = decodeSuiPrivateKey(sui_priv_key)
const flag =
schema === 'ED25519' ? 0x00 : schema === 'Secp256k1' ? 0x01 : 0x02
return toBase64(Uint8Array.from([flag, ...secretKey]))
}
const keypair = sui_key_to_gas_station('your private key')
console.log(keypair)
最后,将生成的keypair填入sample.yaml
中
4)配置rpc的鉴权token
在环境变量中加上export GAS_STATION_AUTH="你的token"
即可,例如zsh就是修改~/.zshrc
文件,修改完记得source ~/.zshrc
这块就是在http请求时,需要加载header里,例如Authorization: Bearer 你的token
2. 启动Sui Gas Pool
注意 使用一个新的钱包作为赞助钱包,这个钱包只用作赞助交易,不要进行其他操作
别忘了启动redis
redis-server
启动sui-gas-station
./target/release/sui-gas-station --config-path ./sample.yaml
pm2部署执行
pm2 start /root/sui-gas-pool/target/release/sui-gas-station -- --config-path /root/sui-gas-pool/sample.yaml
三、前端调用
示例代码: https://github.com/klren0312/sui-gas-pool-frontend-example
1. Sui Gas Pool 提供的 rpc 接口
三个,分别是检查服务状态,预留gas,赞助交易
我们要用的就是预留gas和赞助交易的接口,这两个接口是相关联的,在赞助交易之前,需要告诉Sui Gas Pool进行gas预留,随后使用预留gas接口返回的参数来配置赞助交易。
先看看两个接口的传参和返回值
1)预留gas接口(/v1/reserve_gas)
传参:
{
"gas_budget": 1038456,
"reserve_duration_secs": 600
}
- gas_budget gas值
- reserve_duration_secs 失效时间,最高600秒
返回参数:
{
"result": {
"sponsor_address": "0x0",
"reservation_id": 2,
"gas_coins": [
{
"objectId": "0x0",
"version": 313000180,
"digest": "fff"
}
]
},
"error": null
}
- sponsor_address 赞助交易的钱包地址
- reservation_id 预留gas的id
- gas_coins 用来给
setGasPayment
用的 gas币的数组
2)赞助交易接口(/v1/execute_tx)
传参:
{
"reservation_id": 2,
"tx_bytes": "eee",
"user_sig": "eee"
}
- reservation_id 上面预留gas的id
- tx_bytes 交易字节
- user_sig 用户签名
返回参数,关注"status": "success"
即可,其他参数自己看
{
"effects": {
"messageVersion": "v1",
"status": {
"status": "success"
},
},
"error": null
}
2. 实战
1)配代理
rpc接口有跨域问题,先在开发工具里配置接口代理
import { defineConfig } from '@farmfe/core';
export default defineConfig({
server: {
proxy: {
'/v1': {
target: 'http://localhost:9527',
changeOrigin: true,
}
}
}
});
2)封装两个请求方法
预留gas的请求方法,入参就是gas值
const doReserveGas = (gasUsed: string) => {
const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer zzespooltoken`
},
body: JSON.stringify({
'gas_budget': parseInt(gasUsed),
'reserve_duration_secs': 300
})
}
return fetch('/v1/reserve_gas', requestOptions).then((res) => res.json()).catch((error) => {
console.error(error)
return null
}) as Promise<ReserveGasResponse>
}
执行赞助交易的请求方法,入参就是上面预留gas的id、交易字节和用户签名,交易字节和用户签名可以通过useSignTransaction
的签名方法获取
const executeTx = (reservationId: number, txBytes: string, userSig: string) => {
const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer zzespooltoken`
},
body: JSON.stringify({
'reservation_id': reservationId,
'tx_bytes': txBytes,
'user_sig': userSig
})
}
return fetch('/v1/execute_tx', requestOptions).then((response) => response.json()).catch((error) => {
console.error(error)
return null
}) as Promise<ExecuteTxResponse>
}
3)编写交易(测试网运行)
测试的合约是 0x485e975299a5d5df56967462a9e585faeb1687ed79b11704ace090b5ac84f5af
server对象是0x8443d3ada68fd36b894e9e91019f8045ca6bd1f9a8db1ec5d1681c534b54d602
先构建交易,然后通过client.devInspectTransactionBlock
预估gas值
const txb = new Transaction()
txb.moveCall({
target: `${packageId}::week_one::create_profile`,
arguments: [
txb.pure.string('test' + Date.now()),
txb.pure.string('test' + Date.now()),
txb.object(server),
],
})
const result = await client.devInspectTransactionBlock({
transactionBlock: txb,
sender: account?.address || '0x0',
})
const gasUsed = result.effects.gasUsed.storageRebate
然后将预估的gas值传入sui gas pool,获得需要的赞助交易地址,gas币数组以及预留gas的id
// 预留gas
const reserveGasRes = await doReserveGas(gasUsed)
if (reserveGasRes?.error) {
message.error('预留gas失败')
return
}
const reservationId = reserveGasRes.result.reservation_id
const gasCoins = reserveGasRes.result.gas_coins
const sponsorAddress = reserveGasRes.result.sponsor_address
然后按照文档: https://sdk.mystenlabs.com/typescript/transaction-building/sponsored-transactions
设置一些赞助交易的参数
// 设置赞助交易参数
txb.setSender(account?.address || '0x0')
txb.setGasPayment(gasCoins)
txb.setGasOwner(sponsorAddress)
对交易进行签名,签名结果的 bytes, signature 加上上面获取的gas预留id,可以传入rpc的赞助交易接口,完成赞助交易
// 签名
signTransaction(
{
transaction: txb,
},
{
onSuccess: async ({ bytes, signature }) => {
// 执行赞助交易
const executeTxRes = await executeTx(reservationId, bytes, signature).finally(() => {
setLoading(false)
})
if (executeTxRes?.error) {
messageApi.error('执行交易失败')
return
}
setTxDigest(executeTxRes.effects.transactionDigest)
messageApi.success('赞助交易成功')
},
onError: (error) => {
setLoading(false)
messageApi.error('交易签名失败' + error.message)
}
}
)
4)结果展示
可以查看测试用户钱包:0x00c46d25eb8612f783ad2f87e700f1c042629a0d0a31a59c0226ee80aa204718,Sui 为空。
执行交易时可以看到钱包显示
执行赞助交易的digest:Q5Y1UsRTE3j3q5HV4g21LQnuG6XndzxgStAau6YwEur
可以看到gas是由赞助钱包支付
四、总结
官方开源的Sui Gas Pool虽然文档写的很难用,但是毕竟自建可以更加的安全和免费使用。当然也可以使用收费的enoki(开发网和测试网有免费额度)。