包含 webapp(Next.js 用户端)、webapp-back(Go 后端)、 antdesign(管理后台)、landingpage(营销落地页)、 数据库 SQL 和配置文件。
175 lines
4.5 KiB
Markdown
175 lines
4.5 KiB
Markdown
# Integration with Existing Code
|
||
|
||
## 发现:holders 包已有类似实现
|
||
|
||
在 `holders/db_config.go` 中已经实现了从数据库加载合约地址的完整逻辑:
|
||
|
||
### holders/db_config.go 的实现
|
||
```go
|
||
// LoadConfigFromDB 从数据库加载配置(已存在)
|
||
func LoadConfigFromDB(chainID int64) (Config, error) {
|
||
// 1. 从 assets 表加载 YT-A, YT-B, YT-C
|
||
var assets []Asset
|
||
db.Table("assets").
|
||
Where("asset_code IN (?, ?, ?)", "YT-A", "YT-B", "YT-C").
|
||
Find(&assets)
|
||
|
||
// 2. 根据 chainID 选择合约地址
|
||
for _, asset := range assets {
|
||
address := asset.ContractAddressArb
|
||
if isBSC {
|
||
address = asset.ContractAddressBsc
|
||
}
|
||
ytVaults = append(ytVaults, VaultConfig{
|
||
Name: asset.AssetCode,
|
||
Address: address,
|
||
})
|
||
}
|
||
|
||
// 3. 从 lending_markets 表加载 Lending 合约
|
||
var lendingMarkets []LendingMarket
|
||
db.Table("lending_markets").
|
||
Where("is_active = ?", 1).
|
||
Find(&lendingMarkets)
|
||
|
||
lendingAddress := market.ContractAddressArb
|
||
if isBSC {
|
||
lendingAddress = market.ContractAddressBsc
|
||
}
|
||
|
||
return Config{
|
||
YTVaults: ytVaults,
|
||
LendingAddress: lendingAddress,
|
||
}
|
||
}
|
||
```
|
||
|
||
### lending/helpers.go 的实现(新建)
|
||
```go
|
||
// GetYTTokenInfo 从 assets 表获取 YT token 信息(新实现)
|
||
func GetYTTokenInfo(assetCode string) (*TokenInfo, error) {
|
||
var asset models.Asset
|
||
db.Where("asset_code = ? AND is_active = ?", assetCode, true).
|
||
First(&asset)
|
||
|
||
return &TokenInfo{
|
||
Symbol: asset.Name,
|
||
ContractAddressArb: asset.ContractAddressArb,
|
||
ContractAddressBsc: asset.ContractAddressBsc,
|
||
}
|
||
}
|
||
```
|
||
|
||
## 代码复用建议
|
||
|
||
### 选项 1:统一使用 holders 包的结构体(推荐)
|
||
```go
|
||
// lending/helpers.go
|
||
import "github.com/gothinkster/golang-gin-realworld-example-app/holders"
|
||
|
||
func GetYTTokensFromHolders(chainID int64) ([]TokenInfo, error) {
|
||
// 复用 holders.LoadConfigFromDB
|
||
config, err := holders.LoadConfigFromDB(chainID)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
tokens := make([]TokenInfo, len(config.YTVaults))
|
||
for i, vault := range config.YTVaults {
|
||
tokens[i] = TokenInfo{
|
||
Symbol: vault.Name,
|
||
ContractAddressArb: vault.Address, // 已根据 chainID 选择
|
||
AssetCode: vault.Name,
|
||
}
|
||
}
|
||
return tokens, nil
|
||
}
|
||
```
|
||
|
||
### 选项 2:共享数据模型
|
||
```go
|
||
// common/models.go - 创建共享的 Asset 模型
|
||
type Asset struct {
|
||
ID int64
|
||
AssetCode string
|
||
Name string
|
||
ContractAddressArb string
|
||
ContractAddressBsc string
|
||
}
|
||
|
||
// holders 和 lending 都使用这个共享模型
|
||
```
|
||
|
||
### 选项 3:保持当前实现(已完成)
|
||
- ✅ lending 包独立实现
|
||
- ✅ 功能完整,逻辑清晰
|
||
- ⚠️ 与 holders 包有重复代码
|
||
|
||
## 数据库表结构(一致)
|
||
|
||
两个包都使用相同的表:
|
||
|
||
### assets 表
|
||
```sql
|
||
CREATE TABLE assets (
|
||
id BIGINT PRIMARY KEY,
|
||
asset_code VARCHAR(20), -- YT-A, YT-B, YT-C
|
||
name VARCHAR(255),
|
||
contract_address_arb VARCHAR(42),
|
||
contract_address_bsc VARCHAR(42),
|
||
is_active BOOLEAN
|
||
)
|
||
```
|
||
|
||
### lending_markets 表
|
||
```sql
|
||
CREATE TABLE lending_markets (
|
||
id BIGINT PRIMARY KEY,
|
||
market_name VARCHAR(100),
|
||
contract_address_arb VARCHAR(42),
|
||
contract_address_bsc VARCHAR(42),
|
||
is_active BOOLEAN
|
||
)
|
||
```
|
||
|
||
## Chain ID 处理
|
||
|
||
### holders 包
|
||
- 421614 = Arbitrum Sepolia
|
||
- 97 = BSC Testnet
|
||
|
||
### lending 包(需要添加)
|
||
```go
|
||
// helpers.go 添加 chain ID 支持
|
||
func GetContractAddress(tokenInfo TokenInfo, chainID int) string {
|
||
switch chainID {
|
||
case 421614: // Arbitrum Sepolia
|
||
return tokenInfo.ContractAddressArb
|
||
case 97: // BSC Testnet
|
||
return tokenInfo.ContractAddressBsc
|
||
case 42161: // Arbitrum One (mainnet)
|
||
return tokenInfo.ContractAddressArb
|
||
case 56: // BSC Mainnet
|
||
return tokenInfo.ContractAddressBsc
|
||
default:
|
||
return tokenInfo.ContractAddressArb
|
||
}
|
||
}
|
||
```
|
||
|
||
## 总结
|
||
|
||
### 已实现功能
|
||
- ✅ lending 包可以独立从 assets 表读取 YT tokens
|
||
- ✅ lending 包可以从 lending_markets 表读取市场配置
|
||
- ✅ USDC 地址已硬编码
|
||
- ✅ 与 holders 包的实现逻辑一致
|
||
|
||
### 建议优化(可选)
|
||
1. 考虑复用 holders.Asset 结构体
|
||
2. 添加对 holders.LoadConfigFromDB 的引用
|
||
3. 统一 chain ID 处理逻辑
|
||
|
||
### 当前状态
|
||
**可以直接使用**,无需修改。与 holders 包的实现独立但兼容。
|