ZBLOG

iOS Swift 接以太坊,从零构建去中心化应用(DApp)的完整指南

在区块链技术蓬勃发展的今天,去中心化应用(DApp)已从概念走向实践,作为全球第二大加密货币,以太坊凭借其智能合约功能和庞大的生态系统,成为DApp开发的核心平台,而iOS作为移动端主流操作系统,通过Swift语言与以太坊集成,能为开发者打开“移动+区块链”的创新大门,本文将详细介绍如何使用iOS Swift接以太坊,涵盖环境搭建、核心功能实现(如连接钱包、调用合约、交易签名)及实战注意事项,助你快速上手移动端DApp开发。

为什么选择Swift接以太坊?

Swift是苹果官方推荐的iOS开发语言,具备安全性高、性能优、语法简洁等特点,而以太坊作为支持智能合约的公链,其生态中的钱包(如MetaMask)、合约(如ERC-20代币、NFT)等资源丰富,将Swift与以太坊结合,可以实现:

  • 移动端钱包集成:让用户通过iOS原生App直接管理以太坊资产,无需跳转第三方浏览器;
  • DApp无缝交互:在App内调用智能合约,完成转账、投票、NFT交易等操作;
  • 安全可控:利用iOS沙盒机制和Swift的类型安全,降低区块链交互中的风险。

核心工具与库选择

要在Swift中与以太坊交互,离不开成熟的开发库支持,目前主流工具包括:

Web3.swift 以太坊交互库

Web3.swift 是一个基于Swift的以太坊协议实现,支持JSON-RPC与以太坊节点通信,可完成账户管理、交易签名、合约调用等核心功能,其API设计接近Web.js,便于前端开发者迁移。

Alchemy/Infura 节点服务

以太坊全节点部署成本高,开发者通常通过第三方节点服务(如Alchemy、Infura)接入网络,注册后可获取免费的HTTPS JSON-RPC节点地址,用于与以太坊网络交互。

WalletConnect 钱包连接协议

为让用户在App中管理私钥,需集成钱包连接协议,WalletConnect是开源的移动端-钱包通信标准,支持MetaMask、Trust Wallet等主流钱包,用户可通过扫码完成授权和交易签名。

合约交互工具

  • Solidity编译:使用Solidity语言编写智能合约,通过solc编译器生成ABI(应用二进制接口)和字节码(Bytecode);
  • 合约绑定库:如web3swift/ContractABI,可将ABI转换为Swift对象,简化合约方法调用。

环境搭建与项目初始化

创建iOS项目

打开Xcode,选择“App”模板,语言设为Swift,界面选项选“Storyboard”或“SwiftUI”(本文以SwiftUI为例)。

添加依赖库

通过CocoaPods或Swift Package Manager(SPM)集成核心库:

  • Web3.swift:用于以太坊节点交互;
  • WalletConnectSwift:实现钱包连接;
  • BigInt:处理以太坊中的大整数(如余额、Gas费)。

以SPM为例,在Xcode的“Package Dependencies”中添加以下仓库:

https://github.com/Boilertalk/Web3.swift  
https://github.com/WalletConnect/WalletConnectSwift  
https://github.com/attaswift/BigInt  

配置节点服务

注册Alchemy或Infura,获取以太坊主网或测试网(如Goerli)的JSON-RPC节点URL,在Info.plist中配置为常量:

<key>ETHEREUM_NODE_URL</key>  
<string>你的节点URL</string>  

核心功能实现:从连接钱包到合约调用

连接以太坊钱包(以WalletConnect为例)

WalletConnect的核心是建立App与钱包的WebSocket连接,用户通过钱包App完成交易签名。

步骤1:初始化WalletConnect

import WalletConnectSwift  
class WalletManager: NSObject, WalletConnectDelegate {  
    static let shared = WalletManager()  
    var connector: WalletConnect?  
    var account: String? // 用户钱包地址  
    func connect() {  
        let metadata = AppMetadata(name: "My DApp", description: "以太坊DApp示例", icons: ["https://example.com/icon.png"], url: "https://example.com", scheme: "mydapp")  
        connector = WalletConnect(metadata: metadata, bridge: "https://bridge.walletconnect.org")  
        connector?.delegate = self  
        connector?.connect(url: "wc:连接请求URL")  
    }  
    // 实现代理方法,监听连接状态  
    func didConnect(client: WalletConnectClient) {  
        print("钱包连接成功")  
        account = client.walletInfo?.accounts.first  
    }  
    func didFailToConnect(error: Error) {  
        print("连接失败:\(error.localizedDescription)")  
    }  
}  

步骤2:发起连接请求
在App界面添加按钮,点击后调用WalletManager.shared.connect(),用户手机会弹出MetaMask等钱包App,确认后完成连接。

查询账户余额

通过Web3.swift连接节点,查询指定地址的ETH或ERC-20代币余额。

示例:查询ETH余额

import Web3  
func getBalance(address: String, completion: @escaping (Result<String, Error>) -> Void) {  
    guard let nodeURL = Bundle.main.object(forInfoDictionaryKey: "ETHEREUM_NODE_URL") as? String else {  
        completion(.failure(NSError(domain: "节点URL未配置", code: 0)))  
        return  
    }  
    let web3 = Web3(url: URL(string: nodeURL)!)  
    web3.eth.getBalance(address: EthereumAddress(address)!) { result in  
        switch result {  
        case .success(let balance):  
            let ethBalance = Web3.Utils.formatToEther(balance)  
            completion(.success("\(ethBalance) ETH"))  
        case .failure(let error):  
            completion(.failure(error))  
        }  
    }  
}  

发送ETH交易

发送交易需指定接收地址、金额、Gas参数,并通过钱包签名。

步骤1:构建交易

func sendETH(to: String, amount: String, completion: @escaping (Result<String, Error>) -> Void) {  
    guard let nodeURL = Bundle.main.object(forInfoDictionaryKey: "ETHEREUM_NODE_URL") as? String,  
          let fromAddress = EthereumAddress(WalletManager.shared.account!),  
          let toAddress = EthereumAddress(to) else {  
        completion(.failure(NSError(domain: "地址无效", code: 0)))  
        return  
    }  
    let web3 = Web3(url: URL(string: nodeURL)!)  
    let transaction = EthereumTransaction(from: fromAddress, to: toAddress, value: Web3.Utils.toWei(amount, unit: .ether))  
    transaction.gasPrice = Web3.Utils.toWei("20", unit: .gwei) // 设置Gas价格  
    transaction.gasLimit = 21000 // ETH转账默认Gas限制  

步骤2:通过WalletConnect签名并发送

    // 假设已通过WalletConnect获取交易签名  
    guard let connector = WalletManager.shared.connector else {  
        completion(.failure(NSError(domain: "钱包未连接", code: 0)))  
        return  
    }  
    let txData = transaction.encode()  
    connector.sendTransaction(with: txData, from: fromAddress) { result in  
        switch result {  
        case .success(let txHash):  
            completion(.success("交易哈希:\(txHash)"))  
        case .failure(let error):  
            completion(.failure(error))  
        }  
    }  
}  

调用智能合约

以ERC-20代币的transfer方法为例,需传入合约ABI、字节码及方法参数。

步骤1:导入合约ABI
将编译后的ERC-20合约ABI转换为Swift对象(可使用web3swiftABI工具自动生成):

let erc20ABI = "[{\"constant\":true,\"inputs\":[],...}]" // 合约ABI字符串  
let contract = web3.contract(erc20ABI, at: EthereumAddress("合约地址")!)  

步骤2:调用合约方法

func transferToken(tokenAddress: String, to: String, amount: String, completion: @escaping (Result<String, Error>) -> Void) {  
    guard let fromAddress = EthereumAddress(WalletManager.shared.account!),  
          let toAddress = EthereumAddress(to),  
          let contract = web3.contract(ERC20ABI.abi, at: EthereumAddress(tokenAddress)!) else {  
        return  
    }  
    let parameters = [to
分享:
扫描分享到社交APP