1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
| // SBT(灵魂绑定代币)是不可转移的NFT
import { ethers } from 'ethers'
// SBT合约ABI
const SBT_ABI = [
'function issue(address to, uint256 tokenId, string uri) external',
'function revoke(address from, uint256 tokenId) external',
'function tokenURI(uint256 tokenId) view returns (string)',
'function balanceOf(address) view returns (uint256)',
'function tokenOfOwnerByIndex(address owner, uint256 index) view returns (uint256)'
]
class SoulboundManager {
private sbtContract: ethers.Contract
constructor(contractAddress: string, privateKey: string) {
const provider = new ethers.JsonRpcProvider('https://eth.llamarpc.com')
const wallet = new ethers.Wallet(privateKey, provider)
this.sbtContract = new ethers.Contract(
contractAddress,
SBT_ABI,
wallet
)
}
async issueSBT(
recipient: string,
tokenId: number,
metadataURI: string
): Promise<string> {
const tx = await this.sbtContract.issue(
recipient,
tokenId,
metadataURI
)
const receipt = await tx.wait()
return receipt.transactionHash
}
async getSBTsByAddress(address: string): Promise<number[]> {
const balance = await this.sbtContract.balanceOf(address)
const tokens = []
for (let i = 0; i < balance.toNumber(); i++) {
const tokenId = await this.sbtContract.tokenOfOwnerByIndex(address, i)
tokens.push(tokenId.toNumber())
}
return tokens
}
async getSBTMetadata(tokenId: number): Promise<object> {
const uri = await this.sbtContract.tokenURI(tokenId)
// 从IPFS获取metadata
const response = await fetch(uri)
const metadata = await response.json()
return metadata
}
}
// 使用示例
const sbtManager = new SoulboundManager(
'0x...', // SBT合约地址
process.env.PRIVATE_KEY
)
// 发行SBT凭证
await sbtManager.issueSBT(
'0x用户地址',
1,
'ipfs://Qm...' // metadata URI
)
// 查询用户的SBT
const tokens = await sbtManager.getSBTsByAddress('0x用户地址')
for (const tokenId of tokens) {
const metadata = await sbtManager.getSBTMetadata(tokenId)
console.log('SBT:', metadata)
// {
// name: "大学学历凭证",
// description: "计算机科学学士学位",
// image: "ipfs://...",
// attributes: [
// { trait_type: "大学", value: "示例大学" },
// { trait_type: "专业", value: "计算机科学" },
// { trait_type: "学位", value: "学士" }
// ]
// }
}
|