
Web3.swift est une bibliothèque rapide pour la signature des transactions et l'interaction avec les contrats intelligents dans le réseau Ethereum.
Il vous permet de vous connecter à un nœud Geth ou Erigon Ethereum (comme ChainNodes) pour envoyer des transactions et lire les valeurs à partir de contrats intelligents sans avoir besoin d'écrire vos propres implémentations des protocoles.
Web3.Swift prend en charge iOS, MacOS, TVOS, Watchos et Linux avec Swift Package Manager.
Vérifiez l'utilisation ci-dessous ou examinez les tests des référentiels.
Il existe déjà une bibliothèque Web3 écrite dans Swift. Nous connaissons leurs forces et leurs faiblesses et pour notre cas d'utilisation, ils n'ont tout simplement pas fonctionné.
Web3.swift a été construit avec la modularité, la portabilité, la vitesse et l'efficacité à l'esprit.
Ok, merci pour les mots à la mode. Mais qu'est-ce que cela signifie réellement?
Web3.swift a été conçu pour être modulaire. Si vous installez / utilisez le produit SPM Web3 de base, vous avez accès aux fonctions les plus basiques telles que la signature de transaction et l'interaction avec un serveur RPC HTTP.
Si vous souhaitez ajouter la prise en charge du RPC IPC ou autre chose, vous pouvez créer simple une bibliothèque qui dépend de Web3 et implémente cette fonctionnalité exacte. En savoir plus à ce sujet plus tard.
Si vous souhaitez utiliser des extensions PromiseKit pour les appels Web3, vous pouvez soit utiliser le produit SPM Promisekit fourni ou créer le vôtre.
Si vous souhaitez analyser commodément JSON ABIS pour les contrats intelligents Ethereum, vous pouvez utiliser le produit ABI ABI SPM fourni.
Enfin, si vous souhaitez ajouter des fonctionnalités à Web3.swift qui n'est pas encore fournie, vous n'avez pas à attendre qu'il soit fusionné et publié dans une bosse de version. Vous pouvez simplement étendre / mettre à jour les fonctionnalités dans votre propre application car nos API sont conçues pour être très ouvertes aux modifications.
Par exemple, si vous souhaitez ajouter une méthode Web3 qui n'est pas encore fournie par Web3.swift (nous ne prendrons en charge que les méthodes prises en charge Infura), vous n'avez qu'ajouter quelques lignes de code (en fonction des paramètres d'entrée et de sortie de la méthode). L'ajout de prise en charge IPC RPC serait d'implémenter uniquement un protocole et de répondre aux demandes.
Comme vous pouvez le voir, tout est possible avec Web3.swift .
L'une des principales raisons pour lesquelles nous avons commencé à travailler sur ce projet est que nous voulions l'utiliser avec Swift Package Manager sur différentes plates-formes.
Pour cette raison, Web3.swift est disponible via Swift Package Manager sur iOS, MacOS, TVOS, WatchOS et Linux.
Remarque: Pour SPM, nous ne testons que iOS, MacOS et des distributions Linux en charge officiellement (actuellement Ubuntu 16.04 et 20.04), mais elle devrait être compatible avec tous les petits systèmes endian qui sont capables de compiler le compilateur Swift, la fondation et le GLIBC.
Nous essayons de rendre cette bibliothèque aussi rapidement que possible tout en essayant de fournir une API qui augmente votre flux de travail de développement de telle sorte que vous pouvez vous concentrer sur la création de grands DAPP au lieu de vous soucier des détails de l'implémentation.
Toutes nos API sont sûres et conçues pour être utilisées dans des applications très concurrentes.
Web3 est compatible avec Swift Package Manager v5 (Swift 5 et plus). Ajoutez-le simplement aux dépendances dans votre Package.swift .
dependencies: [
. package ( url : " https://github.com/Boilertalk/Web3.swift.git " , from : " 0.6.0 " )
]Puis l'ajoutez à vos dépendances cibles:
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 " ] )
]Remarque:
Web3PromiseKitetWeb3ContractABIsont facultatifs et vous n'avez qu'à les mettre dans vos dépendances cibles (et à les importer ultérieurement) si vous souhaitez les utiliser.
Après l'installation, vous pouvez importer Web3 dans vos fichiers .swift .
import Web3
// Optional
import Web3PromiseKit
import Web3ContractABIEn raison d'une décision interne, nous avons cessé de soutenir tous les gestionnaires de packages autres que SPM en commençant par la version 0.5.0.
Pour élaborer un peu sur cette décision: avec Xcode 11 et Swift 5.1, nous avons atteint un point avec Swift Package Manager où il a lentement commencé à rendre d'autres gestionnaires de package hors de propos. Vous pouvez déjà charger toutes vos dépendances dans le projet Xcode avec Swift Package Manager.
Avec plus de mises à jour, il est devenu encore plus répandu. Cocoapods et Carthage Haigers ont perdu tout intérêt pour leur projet et ont cessé de le maintenir. Il existe de nombreux problèmes non résolus, de nombreux problèmes, en particulier pour les développeurs de bibliothèques avec des cocoapodes.
Tant de tracas sans un réel gain. Les utilisateurs peuvent déjà mettre des dépendances qui prennent en charge SPM dans leur projet Xcode. Alors pourquoi s'embêter?
La réponse est simple. Certains utilisent toujours Xcode <11 et certains développeurs de bibliothèques dépendent de Web3 dans leurs propres pods / carthages.
La décision a été difficile et a pris un certain temps. Mais après avoir vu que la dernière version était déjà très stable et utilisée dans de nombreuses applications de production, nous avons décidé de commencer par cette décision maintenant.
Xcode 10 a déjà plus de 2 ans. La plupart des projets ont déjà mis à niveau, ceux qui n'avaient pas un problème beaucoup plus important que Web3.swift ne faisant pas de mises à jour pour cocoapodes ...
Les propriétaires de bibliothèques en fonction de Web3.swift sont également encouragés à abandonner les cocoapodes et le soutien de Carthage.
SPM est l'avenir. Pour tous les cocoapods et les utilisateurs de Carthage qui l'utilisent parce que de nombreuses bibliothèques ne sont pas encore passées à SPM: vous pouvez toujours ajouter Web3.swift en tant que produit SPM dans votre .xcworkspace ou .xcodeproj et conserver toutes vos autres dépendances à l'intérieur de Cocoapods / Carthage. Mais encore. Nous vous encourageons à basculer avec autant de dépendances possible au SPM. Mieux mieux que tard. Voir la section suivante sur la façon de procéder.
En utilisant XCode 11 ou version ultérieure (pour iOS, MacOS ou d'autres plates-formes Apple), vous pouvez ajouter des packages SPM très faciles.
Dans Xcode, sélectionnez votre projet, dans la liste déroulante Sélectionnez le projet, pas une seule cible, dans les onglets Sélectionnez Swift Packages .
Ensuite, vous pouvez cliquer sur l'icône + et mettre l'URL à ce référentiel (https://github.com/boilertalk/web3.swift).
Vous pouvez maintenant sélectionner tous les produits et cliquer sur Suivant jusqu'à ce que la dépendance soit ajoutée.
C'est ça. Si vous poussez vos modifications, même votre CI ne fera aucun problème. Pas de tracas avec des référentiels de spécifications obsolètes, pas de problèmes avec des erreurs de linker étranges qui ne se produisent que parfois / avec certaines dépendances.
Si vous avez besoin de conseils supplémentaires, rejoignez notre groupe télégramme et nous vous aiderons. https://t.me/web3_swift
Avec Web3.swift vous pouvez utiliser un nœud Ethereum sur un serveur pour communiquer avec Ethereum.
Vous pouvez envoyer des transactions signées, lire les données du contrat, appeler des fonctions de contrat et bien plus encore.
La classe de base pour toutes les méthodes disponibles est Web3 . Vous pouvez, par exemple, l'instancier avec un fournisseur HTTP:
let web3 = Web3 ( rpcURL : " https://mainnet.infura.io/<your_infura_id> " ) Toutes les méthodes web3_ sont disponibles directement à partir de la structure Web3 . Les méthodes net_ sont disponibles sous la structure net dans la structure web3 . Les méthodes eth_ sont disponibles sous la structure eth dans la structure web3 .
Veuillez consulter les exemples ci-dessous
Remarque: Pour que les exemples fonctionnent, vous devez d'abord importer web3 et promessekit d'abord
Renvoie la version client actuelle.
Paramètres
aucun
Rendements
String - la version client actuelle
firstly {
web3 . clientVersion ( )
} . done { version in
print ( version )
} . catch { error in
print ( " Error " )
} Renvoie l'ID réseau actuel.
Paramètres
aucun
Rendements
String - l'ID réseau actuel
firstly {
web3 . net . version ( )
} . done { version in
print ( version )
} . catch { error in
print ( " Error " )
} Renvoie le nombre de pairs actuellement connectés au client.
Paramètres
aucun
Rendements
EthereumQuantity - Bigint du nombre de pairs connectés.
firstly {
web3 . net . peerCount ( )
} . done { ethereumQuantity in
print ( ethereumQuantity . quantity )
} . catch { error in
print ( " Error " )
} Crée une nouvelle transaction d'appel de message ou une création de contrat pour les transactions signées.
Paramètres
EthereumTransaction : la transaction signéeRendements
EthereumData , 32 octets - le hachage de transaction, ou le hachage zéro si la transaction n'est pas encore disponible
Pour envoyer de l'ETH, vous devez d'abord obtenir le nombre de transactions actuel de l'expéditeur (NONCE), créez la transaction, signez-la puis envoyez-la.
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 )
} Pour plus d'exemples, lisez nos cas de test, la structure Web3 ou la documentation officielle du RPC JSON Ethereum.
Nous fournissons un module facultatif pour l'interaction avec les contrats intelligents. Pour l'utiliser, vous devez ajouter Web3ContractABI à vos dépendances cibles dans votre podfile (pour SPM). Assurez-vous d'abord de consulter les instructions d'installation.
Nous offrons deux options différentes pour créer des interfaces ABI contractuelles dans Swift. Soit vous définissez manuellement vos fonctions et événements (ou utilisez l'une de nos interfaces fournies comme ERC20 ou ERC721). Ou vous les analysez de la représentation JSON ABI comme dans web3.js.
Les contrats statiques sont des classes mettant en œuvre StaticContract . Ils fournissent un ensemble de fonctions et d'événements qu'ils souhaitent utiliser à partir du contrat intelligent d'origine. Consultez nos contrats statiques fournis comme point de départ (ERC20 ou ERC721).
Notre interface ERC20 statique est appelée GenericERC20Contract , le contrat ERC721 est appelé GenericERC721Contract . Les deux peuvent être sous-classés pour ajouter plus de fonctions pour les contrats personnalisés.
Avec ces types StaticContract , vous pouvez créer et utiliser votre contrat comme dans l'exemple suivant (nous utilisons à nouveau PromiseKit dans nos exemples).
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 )
}En créant vos propres interfaces, vous pouvez interagir avec n'importe quel contrat intelligent!
Si vous n'avez accès qu'au JSON ABI d'un contrat intelligent ou si vous ne souhaitez pas créer un modèle statique, vous pouvez utiliser notre API de contrat dynamique pour analyser la chaîne JSON dans un contrat utilisable pendant l'exécution . Voir l'exemple ci-dessous.
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 )
}En utilisant cette API, vous pouvez interagir avec n'importe quel contrat intelligent dans le réseau Ethereum!
Pour plus d'exemples, y compris la création de contrats (appel de constructeur), consultez nos tests.
Si vous obtenez cette erreur lorsque vous analysez votre ABI à partir d'un JSON, cela peut être dû au fait que votre contrat a une fonction de secours. Pour le résoudre, supprimez le fragment de votre ABI qui a les informations sur la fonction de secours. La pièce que vous devez supprimer peut ressembler à ceci:
{
"payable": false,
"stateMutability": "nonpayable",
"type": "fallback"
},
Jusqu'à ce que nous atteignions la version 1.0.0, notre API est soumise à des changements de rupture entre les sauts de version mineure. Il s'agit de s'assurer que nous pouvons nous concentrer sur la fourniture de la meilleure mise en œuvre pendant que nous sommes en développement lourd au lieu d'essayer de maintenir quelque chose qui est obsolète.
Cela étant dit, nous essaierons de minimiser les changements de rupture. Il n'y en aura certainement pas beaucoup.
Les gars géniaux de Boilertalk ⚗️
... et encore plus de membres géniaux de la communauté?
Consultez la liste des contributeurs pour une liste complète.
Web3 est disponible sous la licence MIT. Voir le fichier de licence pour plus d'informations.