
Web3.Swift是一个迅速的库,用于签署交易并与以太坊网络中的智能合约进行交互。
它允许您连接到Geth或Erigon以太坊节点(如链节点),以发送交易和读取智能合约的值,而无需编写您自己的协议实现。
Web3.Swift支持Swift Package Manager,支持iOS,MACOS,TVOS,WatchOS和Linux。
检查下面的用法或查看存储库测试。
Swift已经写了一些Web3库。我们知道他们的优点和缺点,对于我们的用例,它们只是不起作用。
Web3.swift是考虑到模块化,可移植性,速度和效率的。
好的,谢谢您的流行语。但是这实际上是什么意思?
Web3.swift是模块化的。如果您安装/使用基本的Web3 SPM产品,则可以访问最基本的功能,例如交易签名和与HTTP RPC服务器进行交互。
如果要添加对IPC RPC或其他内容的支持,则可以简单地创建一个依赖于Web3库并实现此确切的功能。稍后会有更多信息。
如果您想对Web3调用使用PromiseKit扩展名,则可以使用提供的PromiseKit SPM产品或创建自己的PromiseKit SPM产品。
如果您想方便地解析Json Abis的以太坊智能合约,则可以使用提供的ABI解析SPM产品。
最后,如果您想在尚未提供的Web3.swift中添加功能,则不必等到它合并并以版本的颠簸发布。您可以在自己的应用程序中简单扩展/更新功能,因为我们的API非常开放以进行更改。
例如,如果要添加Web3.swift尚未提供的Web3方法(我们只支持支持INFURA支持的方法),则只需要添加3行代码(取决于方法的输入和输出参数)。添加IPC RPC支持仅是实现协议和回答请求。
就像您看到的那样, Web3.swift的一切可能。
我们开始从事此项目的主要原因之一是因为我们想在不同平台上与Swift Package Manager一起使用它。
因此, Web3.swift可通过Swift Package Manager在iOS,MACOS,TVOS,WatchOS和Linux上获得。
注意:对于SPM,我们仅测试iOS,MACOS和正式支持的Linux发行版(当前Ubuntu 16.04和20.04),但应与所有能够编译Swift Compiler,Foundation,Foundation和Glibc的所有小Endian系统兼容。
我们尝试使该库尽可能快地尝试提供API,从而增加您的开发工作流程,以便您可以专注于构建出色的DAPP,而不必担心实施细节。
我们所有的API都是线程安全的,设计用于高度并发应用。
Web3与Swift Package Manager V5(Swift 5及以上)兼容。只需将其添加到Package.swift中的依赖项。
dependencies: [
. package ( url : " https://github.com/Boilertalk/Web3.swift.git " , from : " 0.6.0 " )
]然后将其添加到您的目标依赖性中:
targets: [
. target (
name : " MyProject " ,
dependencies : [
. product ( name : " Web3 " , package : " Web3.swift " ) ,
. product ( name : " Web3PromiseKit " , package : " Web3.swift " ) ,
. product ( name : " Web3ContractABI " , package : " Web3.swift " ) ,
]
) ,
. testTarget (
name : " MyProjectTests " ,
dependencies : [ " MyProject " ] )
]注意:
Web3PromiseKit和Web3ContractABI是可选的,只需将它们放入目标依赖项(如果您想使用它们)。
安装后,您可以在.swift文件中导入Web3 。
import Web3
// Optional
import Web3PromiseKit
import Web3ContractABI由于内部决策,我们停止支持以0.5.0版本开头的SPM以外的任何软件包经理。
为了详细说明这一决定:使用Xcode 11和Swift 5.1,我们与Swift Package Manager达到了一个点,它慢慢开始使其他软件包经理无关紧要。您已经可以使用Swift Package Manager加载XCode项目中的所有依赖项。
随着更多更新,它变得更加普遍。可可蛋白鱼类和迦太基维护者对其项目失去了兴趣,并停止维护该项目。有许多未解决的问题,尤其是对于具有可可录的图书馆开发人员而言,许多问题。
这么多麻烦,没有真正的收益。用户已经可以将支持SPM的依赖项放入其Xcode项目中。那为什么要打扰呢?
答案很简单。有些仍然使用Xcode <11,一些库开发人员在自己的豆荚/迦太基中取决于Web3。
这个决定很难,花了一些时间。但是,在看到最后一个版本非常稳定并已经用于许多生产应用程序之后,我们决定现在开始此举。
Xcode 10已经超过2年了。大多数已经升级的项目都没有比Web3的问题要大得多。
图书馆的所有者根据Web3.Swift也被鼓励放弃Cocoapods和Carthage支持。
SPM是未来。对于所有使用它的可可录和迦太基用户,因为许多库还没有切换到SPM:您仍然可以将Web3.swift作为SPM产品添加到.xcworkspace或.xcodeproj中,并将所有其他依赖性保留在Cocoapopods/Carthage中。但仍然我们鼓励您使用尽可能多的依赖关系切换到SPM。比晚早。请参阅下一节有关如何执行此操作的部分。
使用Xcode 11或更高版本(对于iOS,MACOS或其他Apple平台),您可以非常简单地添加SPM软件包。
在Xcode中,从下拉列表中选择您的项目,选择项目,而不是单个目标,在选项卡中选择Swift Packages 。
然后,您可以单击 +图标并将其放入此存储库中(https://github.com/boilertalk/web3.swift)。
现在,您可以选择所有产品,然后单击下一步直到添加依赖关系。
就是这样。如果您推动更改,即使您的CI也不会遇到任何问题。没有过时的规格存储库的麻烦,某些怪异的链接器错误没有有时/与某些依赖关系发生的问题。
如果您需要进一步的指导,请加入我们的电报小组,我们将为您提供帮助。 https://t.me/web3_swift
使用Web3.swift您可以在服务器上使用以太坊节点与以太坊进行通信。
您可以发送签名的交易,读取合同数据,呼叫合同功能等等。
所有可用方法的基类是Web3 。例如,您可以将其与HTTP提供商进行实例化:
let web3 = Web3 ( rpcURL : " https://mainnet.infura.io/<your_infura_id> " )所有web3_方法均可直接从Web3 struct获得。 net_方法可在web3结构中的net结构下找到。 eth_方法可在web3结构中的eth结构下找到。
请参阅下面的示例
注意:要工作的示例,您需要首先导入Web3和PromiseKit
返回当前客户端版本。
参数
没有任何
返回
String - 当前客户版本
firstly {
web3 . clientVersion ( )
} . done { version in
print ( version )
} . catch { error in
print ( " Error " )
} 返回当前网络ID。
参数
没有任何
返回
String - 当前网络ID
firstly {
web3 . net . version ( )
} . done { version in
print ( version )
} . catch { error in
print ( " Error " )
} 返回当前连接到客户端的同行数量。
参数
没有任何
返回
EthereumQuantity - 连接的同龄人数量的巨大。
firstly {
web3 . net . peerCount ( )
} . done { ethereumQuantity in
print ( ethereumQuantity . quantity )
} . catch { error in
print ( " Error " )
} 创建新消息呼叫交易或为签名交易创建合同。
参数
EthereumTransaction :签名的交易返回
EthereumData ,32个字节 - 交易哈希或零哈希(如果尚未可用)
要发送一些ETH,您首先需要获得发件人(NONCE)的当前交易计数,创建交易,签名然后发送。
let privateKey = try ! EthereumPrivateKey ( hexPrivateKey : " 0xa26da69ed1df3ba4bb2a231d506b711eace012f1bd2571dfbfff9650b03375af " )
firstly {
web3 . eth . getTransactionCount ( address : privateKey . address , block : . latest )
} . then { nonce in
let tx = try EthereumTransaction (
nonce : nonce ,
gasPrice : EthereumQuantity ( quantity : 21 . gwei ) ,
gas : 21000 ,
to : EthereumAddress ( hex : " 0xC0866A1a0ed41e1aa75c932cA3c55fad847fd90D " , eip55 : true ) ,
value : EthereumQuantity ( quantity : 1 . eth )
)
return try tx . sign ( with : privateKey , chainId : 1 ) . promise
} . then { tx in
web3 . eth . sendRawTransaction ( transaction : tx )
} . done { hash in
print ( hash )
} . catch { error in
print ( error )
} firstly {
web3 . eth . getBlockTransactionCountByNumber ( block : . block ( 5397389 ) )
} . done { count in
print ( count ) // 88
} . catch { error in
print ( error )
} 有关更多示例,请阅读我们的测试用例,即Web3结构或官方的Ethereum JSON RPC文档。
我们提供了一个可选的模块,用于与智能合约互动。要使用它,您必须将Web3ContractABI添加到Podfile(SPM)中的目标依赖项中。确保首先检查安装说明。
我们提供了两个不同的选项,以在Swift中创建合同ABI接口。您要么手动定义功能和事件(或使用我们提供的界面之一,例如ERC20或ERC721)。或者,您就像在web3.js中一样从JSON ABI代表中解析它们。
静态合同是实施StaticContract类。他们提供了一套要从原始智能合约中使用的功能和事件。查看我们提供的静态合同作为起点(ERC20或ERC721)。
我们的静态ERC20接口称为GenericERC20Contract ,ERC721合同称为GenericERC721Contract 。两者都可以分类以添加自定义合同的更多功能。
使用这些StaticContract类型,您可以像以下示例中创建和使用合同(我们在示例中再次使用PromiseKit)。
let web3 = Web3 ( rpcURL : " https://mainnet.infura.io/<your_infura_id> " )
let contractAddress = try EthereumAddress ( hex : " 0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0 " , eip55 : true )
let contract = web3 . eth . Contract ( type : GenericERC20Contract . self , address : contractAddress )
// Get balance of some address
firstly {
try contract . balanceOf ( address : EthereumAddress ( hex : " 0x3edB3b95DDe29580FFC04b46A68a31dD46106a4a " , eip55 : true ) ) . call ( )
} . done { outputs in
print ( outputs [ " _balance " ] as? BigUInt )
} . catch { error in
print ( error )
}
// Send some tokens to another address (locally signing the transaction)
let myPrivateKey = try EthereumPrivateKey ( hexPrivateKey : " ... " )
firstly {
web3 . eth . getTransactionCount ( address : myPrivateKey . address , block : . latest )
} . then { nonce in
try contract . transfer ( to : EthereumAddress ( hex : " 0x3edB3b95DDe29580FFC04b46A68a31dD46106a4a " , eip55 : true ) , value : 100000 ) . createTransaction (
nonce : nonce ,
gasPrice : EthereumQuantity ( quantity : 21 . gwei ) ,
maxFeePerGas : nil ,
maxPriorityFeePerGas : nil ,
gasLimit : 100000 ,
from : myPrivateKey . address ,
value : 0 ,
accessList : [ : ] ,
transactionType : . legacy
) ! . sign ( with : myPrivateKey ) . promise
} . then { tx in
web3 . eth . sendRawTransaction ( transaction : tx )
} . done { txHash in
print ( txHash )
} . catch { error in
print ( error )
}
// Send some tokens to another address (signing will be done by the node)
let myAddress = try EthereumAddress ( hex : " 0x1f04ef7263804fafb839f0d04e2b5a6a1a57dc60 " , eip55 : true )
firstly {
web3 . eth . getTransactionCount ( address : myAddress , block : . latest )
} . then { nonce in
try contract . transfer ( to : EthereumAddress ( hex : " 0x3edB3b95DDe29580FFC04b46A68a31dD46106a4a " , eip55 : true ) , value : 100000 ) . send (
nonce : nonce ,
gasPrice : EthereumQuantity ( quantity : 21 . gwei ) ,
maxFeePerGas : nil ,
maxPriorityFeePerGas : nil ,
gasLimit : 150000 ,
from : myAddress ,
value : 0 ,
accessList : [ : ] ,
transactionType : . legacy
)
} . done { txHash in
print ( txHash )
} . catch { error in
print ( error )
}通过创建自己的界面,您可以与任何智能合约进行交互!
如果您只能访问智能合约的JSON ABI或不想创建静态模板,则可以使用我们的动态合同API将JSON字符串解析为运行时的可用合同。请参见下面的示例。
let web3 = Web3 ( rpcURL : " https://mainnet.infura.io/<your_infura_id> " )
let contractAddress = try EthereumAddress ( hex : " 0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0 " , eip55 : true )
let contractJsonABI = " <your contract ABI as a JSON string> " . data ( using : . utf8 ) !
// You can optionally pass an abiKey param if the actual abi is nested and not the top level element of the json
let contract = try web3 . eth . Contract ( json : contractJsonABI , abiKey : nil , address : contractAddress )
print ( contract . methods . count )
// Get balance of some address
firstly {
try contract [ " balanceOf " ] ! ( EthereumAddress ( hex : " 0x3edB3b95DDe29580FFC04b46A68a31dD46106a4a " , eip55 : true ) ) . call ( )
} . done { outputs in
print ( outputs [ " _balance " ] as? BigUInt )
} . catch { error in
print ( error )
}
// Send some tokens to another address (locally signing the transaction)
let myPrivateKey = try EthereumPrivateKey ( hexPrivateKey : " ... " )
guard let transaction = contract [ " transfer " ] ? ( EthereumAddress . testAddress , BigUInt ( 100000 ) ) . createTransaction (
nonce : 0 ,
gasPrice : EthereumQuantity ( quantity : 21 . gwei ) ,
maxFeePerGas : nil ,
maxPriorityFeePerGas : nil ,
gasLimit : 150000 ,
from : myPrivateKey . address ,
value : 0 ,
accessList : [ : ] ,
transactionType : . legacy
) ) else {
return
}
let signedTx = try transaction . sign ( with : myPrivateKey )
firstly {
web3 . eth . sendRawTransaction ( transaction : signedTx )
} . done { txHash in
print ( txHash )
} . catch { error in
print ( error )
}使用此API,您可以与以太坊网络中的任何智能合约进行交互!
有关更多示例,包括创建合同(构造函数),请查看我们的测试。
如果从JSON解析ABI时遇到此错误,则可能是因为您的合同具有后备功能。要解决它,请删除具有有关后备功能的信息的ABI片段。您应该删除的零件可能看起来像:
{
"payable": false,
"stateMutability": "nonpayable",
"type": "fallback"
},
在我们达到1.0.0版本之前,我们的API会受到次要版本跳跃之间的破坏变化。这是为了确保我们可以专注于在进行繁重发展时提供最佳的实施,而不是试图维护弃用的东西。
话虽如此,我们将尝试最大程度地减少破裂变化。最肯定的是不会有很多。
Boilertalk的真棒家伙⚗️
...还有更多来自社区的很棒的成员?
查看贡献者列表中的完整列表。
Web3可根据MIT许可证获得。有关更多信息,请参见许可证文件。