web3.swift: Ethereum API for Swift

Swift

安装

Swift Package Manager

使用 Xcode 将其添加到项目中 (File -> Swift Packages) 或将其添加到您的 Package.swift 文件中

.package(url: "https://github.com/argentlabs/web3.swift", from: "1.1.0")

CocoaPods (不推荐)

将 web3.swift 添加到您的 Podfile

pod 'web3.swift'

然后运行以下命令

$ pod install

用法

入门

使用 EthereumKeyStorage 提供程序创建 EthereumAccount 的实例。 这为您的密钥提供了一个包装器,供 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")

创建 EthereumHttpClientEthereumWebSocketClient 的实例。 这将为您提供一组与区块链交互的函数。

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://sepolia.infura.io/ws/v3//123") else { return }
let client = EthereumWebSocketClient(url: clientUrl)

然后,您可以与客户端方法交互,例如获取当前的 gas price

client.eth_gasPrice { (error, currentPrice) in
    print("The current gas price is \(currentPrice)")
}

如果使用 async/await,您可以 await 结果

let gasPrice = try await client.eth_gasPrice()

智能合约:静态类型

给定一个类似 ERC20 transfer 的智能合约函数 ABI

function transfer(address recipient, uint256 amount) public returns (bool)

那么您可以定义一个 ABIFunction,并带有相应的可编码的 Swift 类型,如下所示

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 的交互更加容易。

与 Foundation 类型之间的转换

所有扩展都在 ''.web3 下命名。 例如,要将 Int 转换为十六进制字符串

let gwei = 100
let hexgwei = gwei.web3.hexString

支持的转换

ERC20

我们支持通过 ERC20 结构查询 ERC20 令牌数据。 调用允许

ERC721

我们支持通过 ERC721 结构查询 ERC721 令牌数据。 包括

ZKSync Era

我们还包括一些额外的助手来与 ZKSync Era 交互,通过导入 web3_zksync

查看 ZKSyncTransaction 或者直接使用 ZKSyncClient,它具有与 EthereumClient 相似的 API

运行测试

某些测试需要私钥,该私钥未存储在存储库中。 在本地测试时,您可以忽略这些,因为 CI 将使用来自 Github 的加密密钥。

最好只运行您需要的测试,而不是在开发时运行整个测试套件。 如果您需要本地设置密钥,请查看 TestConfig.swift,您可以在其中手动设置密钥。 或者,您可以通过调用脚本 setupKey.sh 并传递该值(添加 0x)来设置它,以便将其写入被忽略的文件。

依赖项

我们构建 web3.swift,使其尽可能轻量级。 然而,鉴于 Ethereum 的加密性质,您会发现有几个可靠的 C 库与此框架打包在一起

Package 依赖

此外,对于 Linux 构建,我们无法使用 Apple 加密 API,因此我们嵌入了 CryptoSwift 的一小部分(而不是导入整个库)。 感谢 Marcin Krzyżanowski

贡献者

最初的项目由 Argent 团队精心制作。 然而,我们鼓励任何人帮助实施新功能并保持此库的最新状态。 对于功能和修复,只需提交一个 pull request 到 develop 分支。 请遵循 贡献指南

对于错误报告和功能请求,请打开一个 issue

许可证

根据 MIT 许可证发布。