本文已默認(rèn)閱讀者有一定基礎(chǔ)知識
一、介紹
Sui Gas Pool是一個服務(wù),它支持在Sui網(wǎng)絡(luò)上進(jìn)行大規(guī)模的贊助交易。它管理一個由贊助地址擁有的gas幣的數(shù)據(jù)庫,并提供API來預(yù)留gas幣和使用它們來支付交易費用。通過管理池中的大量gas幣對象,它實現(xiàn)了可伸縮性和高吞吐量,因此可以同時贊助大量交易。
二、安裝與啟動Sui Gas Pool服務(wù)
1. 環(huán)境配置
1)安裝Rust和Redis環(huán)境
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文件內(nèi)容,官方readme有個sidecar,太麻煩不用了,直接用內(nèi)存私鑰干
---
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
參數(shù)解釋:
- keypair: 用錢包私鑰可以轉(zhuǎn),下面會給方法
- rpc-host-ip: gas pool的rpc服務(wù)ip, 通常就是 0.0.0.0
- rpc-port: rpc服務(wù)端口
- metrics-port: 監(jiān)控服務(wù)可以訪問并獲取指標(biāo)數(shù)據(jù)和日志記錄的端口
- redis_url: redis服務(wù)地址
- fullnode-url: gas pool所處sui環(huán)境的rpc地址
- coin-init-config
-
target-init-balance: 每個gas的初始余額可以給 100000000
也就是 0.1 SUI, gas pool 會在初始化的時候把贊助錢包的幣按照這個進(jìn)行分割
image.png refresh-interval-sec: 定時查看贊助錢包的所有g(shù)as幣,看看是否有新增
-
- 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的鑒權(quán)token
在環(huán)境變量中加上export GAS_STATION_AUTH="你的token"即可,例如zsh就是修改~/.zshrc文件,修改完記得source ~/.zshrc
這塊就是在http請求時,需要加載header里,例如Authorization: Bearer 你的token
2. 啟動Sui Gas Pool
注意 使用一個新的錢包作為贊助錢包,這個錢包只用作贊助交易,不要進(jìn)行其他操作
別忘了啟動redis
redis-server
啟動sui-gas-station
./target/release/sui-gas-station --config-path ./sample.yaml
pm2部署執(zhí)行
pm2 start /root/sui-gas-pool/target/release/sui-gas-station -- --config-path /root/sui-gas-pool/sample.yaml

三、前端調(diào)用
示例代碼: https://github.com/klren0312/sui-gas-pool-frontend-example
1. Sui Gas Pool 提供的 rpc 接口
三個,分別是檢查服務(wù)狀態(tài),預(yù)留gas,贊助交易

我們要用的就是預(yù)留gas和贊助交易的接口,這兩個接口是相關(guān)聯(lián)的,在贊助交易之前,需要告訴Sui Gas Pool進(jìn)行g(shù)as預(yù)留,隨后使用預(yù)留gas接口返回的參數(shù)來配置贊助交易。
先看看兩個接口的傳參和返回值
1)預(yù)留gas接口(/v1/reserve_gas)
傳參:
{
"gas_budget": 1038456,
"reserve_duration_secs": 600
}
- gas_budget gas值
- reserve_duration_secs 失效時間,最高600秒
返回參數(shù):
{
"result": {
"sponsor_address": "0x0",
"reservation_id": 2,
"gas_coins": [
{
"objectId": "0x0",
"version": 313000180,
"digest": "fff"
}
]
},
"error": null
}
- sponsor_address 贊助交易的錢包地址
- reservation_id 預(yù)留gas的id
- gas_coins 用來給
setGasPayment用的 gas幣的數(shù)組
2)贊助交易接口(/v1/execute_tx)
傳參:
{
"reservation_id": 2,
"tx_bytes": "eee",
"user_sig": "eee"
}
- reservation_id 上面預(yù)留gas的id
- tx_bytes 交易字節(jié)
- user_sig 用戶簽名
返回參數(shù),關(guān)注"status": "success"即可,其他參數(shù)自己看
{
"effects": {
"messageVersion": "v1",
"status": {
"status": "success"
},
},
"error": null
}
2. 實戰(zhàn)
1)配代理
rpc接口有跨域問題,先在開發(fā)工具里配置接口代理
import { defineConfig } from '@farmfe/core';
export default defineConfig({
server: {
proxy: {
'/v1': {
target: 'http://localhost:9527',
changeOrigin: true,
}
}
}
});
2)封裝兩個請求方法
預(yù)留gas的請求方法,入?yún)⒕褪莋as值
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>
}
執(zhí)行贊助交易的請求方法,入?yún)⒕褪巧厦骖A(yù)留gas的id、交易字節(jié)和用戶簽名,交易字節(jié)和用戶簽名可以通過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)編寫交易(測試網(wǎng)運行)
測試的合約是 0x485e975299a5d5df56967462a9e585faeb1687ed79b11704ace090b5ac84f5af
server對象是0x8443d3ada68fd36b894e9e91019f8045ca6bd1f9a8db1ec5d1681c534b54d602
先構(gòu)建交易,然后通過client.devInspectTransactionBlock預(yù)估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
然后將預(yù)估的gas值傳入sui gas pool,獲得需要的贊助交易地址,gas幣數(shù)組以及預(yù)留gas的id
// 預(yù)留gas
const reserveGasRes = await doReserveGas(gasUsed)
if (reserveGasRes?.error) {
message.error('預(yù)留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
設(shè)置一些贊助交易的參數(shù)
// 設(shè)置贊助交易參數(shù)
txb.setSender(account?.address || '0x0')
txb.setGasPayment(gasCoins)
txb.setGasOwner(sponsorAddress)
對交易進(jìn)行簽名,簽名結(jié)果的 bytes, signature 加上上面獲取的gas預(yù)留id,可以傳入rpc的贊助交易接口,完成贊助交易
// 簽名
signTransaction(
{
transaction: txb,
},
{
onSuccess: async ({ bytes, signature }) => {
// 執(zhí)行贊助交易
const executeTxRes = await executeTx(reservationId, bytes, signature).finally(() => {
setLoading(false)
})
if (executeTxRes?.error) {
messageApi.error('執(zhí)行交易失敗')
return
}
setTxDigest(executeTxRes.effects.transactionDigest)
messageApi.success('贊助交易成功')
},
onError: (error) => {
setLoading(false)
messageApi.error('交易簽名失敗' + error.message)
}
}
)
4)結(jié)果展示
可以查看測試用戶錢包:0x00c46d25eb8612f783ad2f87e700f1c042629a0d0a31a59c0226ee80aa204718,Sui 為空。

執(zhí)行交易時可以看到錢包顯示

執(zhí)行贊助交易的digest:Q5Y1UsRTE3j3q5HV4g21LQnuG6XndzxgStAau6YwEur
可以看到gas是由贊助錢包支付

四、總結(jié)
官方開源的Sui Gas Pool雖然文檔寫的很難用,但是畢竟自建可以更加的安全和免費使用。當(dāng)然也可以使用收費的enoki(開發(fā)網(wǎng)和測試網(wǎng)有免費額度)。

