安装
Swift 包管理器
使用 Xcode 将其添加到项目中(文件 -> Swift 包),或将以下内容添加到您的 Package.swift
文件中
.package(url: "https://github.com/argentlabs/web3.swift", from: "1.1.0")
CocoaPods
将 web3.swift 添加到您的 Podfile
pod 'web3.swift'
然后运行以下命令:
$ pod install
使用方法
入门
使用 EthereumAccount
和 EthereumKeyStorage
提供者创建实例。这为 web3.swift 使用您的密钥提供了一个包装。**注意**:我们建议您实现自己的 KeyStorage 提供者,而不是依赖于提供的 EthereumKeyLocalStorage
类。这是为符合 EthereumSingleKeyStorageProtocol
提供的一个例子。
import web3
// This is just an example. EthereumKeyLocalStorage should not be used in production code
let keyStorage = EthereumKeyLocalStorage()
let account = try? EthereumAccount.create(replacing: keyStorage, keystorePassword: "MY_PASSWORD")
创建 EthereumHttpClient
或 EthereumWebSocketClient
实例。这将为您提供访问一组与区块链交互的功能。
EthereumHttpClient
guard let clientUrl = URL(string: "https://an-infura-or-similar-url.com/123") else { return }
let client = EthereumHttpClient(url: clientUrl)
或
EthereumWebSocketClient
guard let clientUrl = URL(string: "wss://goerli.infura.io/ws/v3//123") else { return }
let client = EthereumWebSocketClient(url: clientUrl)
然后您可以通过客户端方法进行交互,例如获取当前天然气价格
client.eth_gasPrice { (error, currentPrice) in
print("The current gas price is \(currentPrice)")
}
如果使用 async/await
,您可以对结果 await
let gasPrice = try await client.eth_gasPrice()
智能合约:静态类型
给定智能合约函数 ABI,如 ERC20 的 transfer
function transfer(address recipient, uint256 amount) public returns (bool)
然后您可以定义一个与相应的可编码 Swift 类型相对应的 ABIFunction
public struct Transfer: ABIFunction {
public static let name = "transfer"
public let gasPrice: BigUInt? = nil
public let gasLimit: BigUInt? = nil
public var contract: EthereumAddress
public let from: EthereumAddress?
public let to: EthereumAddress
public let value: BigUInt
public init(contract: EthereumAddress,
from: EthereumAddress? = nil,
to: EthereumAddress,
value: BigUInt) {
self.contract = contract
self.from = from
self.to = to
self.value = value
}
public func encode(to encoder: ABIFunctionEncoder) throws {
try encoder.encode(to)
try encoder.encode(value)
}
}
此函数可以用于生成合同调用事务以供客户端发送
let function = transfer(contract: "0xtokenaddress", from: "0xfrom", to: "0xto", value: 100)
let transaction = try function.transaction()
client.eth_sendRawTransaction(transaction, withAccount: account) { (error, txHash) in
print("TX Hash: \(txHash)")
}
如果使用 async/await
,您可以对结果 await
let txHash = try await client.eth_sendRawTransaction(transaction, withAccount: account)
从智能合约 ABI 文件生成 ABI
目前我们不支持代码生成,因为正确实现它是一个更大的项目,并且可能需要存在于这个仓库之外。
你可以尝试这个项目:imanrep/swiftabigen
数据类型
库提供了一些类型和辅助工具,以使与web3和Ethereum交互更加简单。
EthereumAddress
:用于表示地址,包括校验和支持。BigInt
和BigUInt
:使用BigInt库EthereumBlock
:表示区块,可以是RPC特定的定义,如"Earliest"或"Latest"。EthereumTransaction
:包装交易。编码器和解码器可以与它一起使用来生成正确的data
字段。
从Foundation类型到和从Foundation类型转换
所有扩展都命名空间于 '' .web3。例如,要将 Int
转换为十六进制字符串:
let gwei = 100
let hexgwei = gwei.web3.hexString
支持的转换
- 将十六进制字节字符串("0xabc")转换为
Data
- 将十六进制字节字符串("0xabc")转换为
Int
- 将十六进制字节字符串("0xabc")转换为
BigUInt
- 将
String
、Int
、BigUInt
、Data
转换为十六进制字节字符串("0xabc") - 在处理
String
时添加或删除十六进制前缀
ERC20
我们支持通过ERC20
结构查询ERC20令牌数据。调用允许:
- 获取令牌符号、名称和小数位数
- 获取令牌余额
- 检索
Transfer
事件
ERC721
我们支持通过ERC721
结构查询ERC721代币数据。包括
- 获取令牌符号、名称和小数位数
- 获取令牌余额
- 检索
Transfer
事件 - 解析标准JSON格式的NFT元数据。请注意,有些智能合约并非完全符合标准。
ZKSync Era
我们还包含额外的辅助程序,通过导入web3_zksync
与ZKSync Era交互。
请查看ZKSyncTransaction或直接使用ZKSyncClient(它与EthereumClient
具有相似的API)。
运行测试
一些测试需要私钥,私钥不在仓库中存储。您可以在本地测试时忽略这些,因为CI将使用GitHub中的加密密钥。
在开发过程中,最好只运行需要的测试,而不是整个测试套件。如果您需要在本地设置密钥,请查看TestConfig.swift
,在那里您可以手动设置。或者,您可以通过调用脚本setupKey.sh
并传递值(添加0x)来设置它,这样它会被写入一个忽略的文件。
依赖项
我们构建了web3.swift,尽可能使其轻量。然而,鉴于以太坊的加密特性,这个框架中包含了几个可靠的C库。
- keccak-tiny:根据FIPS-202定义的SHA-3和SHAKE函数的实现,代码量120行(156行)。
- Tiny AES:一个小型可移植的AES ECB、CTR和CBC加密算法的实现。
- secp256k1.swift
包依赖
对于Linux构建,我们无法使用Apple的加密API,因此我们嵌入了一个小的CryptoSwift子集(而不是导入整个库)。感谢Marcin Krzyżanowski。
贡献者
这个项目最初是由Argent团队制作的。然而,我们鼓励任何人帮助我们实现新功能,并保持这个库的最新动态。对于功能和修复,请将拉取请求提交到develop分支。请遵循这个项目的贡献指南。
对于错误报告和功能请求,请打开一个问题。
许可
在MIT许可下发布。