
Web3.Swift เป็นไลบรารีที่รวดเร็วสำหรับการลงนามในการทำธุรกรรมและโต้ตอบกับสัญญาอัจฉริยะในเครือข่าย Ethereum
ช่วยให้คุณเชื่อมต่อกับโหนด Geth หรือ Erigon Ethereum (เช่น chainnodes) เพื่อส่งธุรกรรมและอ่านค่าจากสัญญาอัจฉริยะโดยไม่จำเป็นต้องเขียนการใช้งานของคุณเอง
Web3.Swift รองรับ iOS, MacOS, TVOS, WatchOs และ Linux ด้วย Swift Package Manager
ตรวจสอบการใช้งานด้านล่างหรือดูการทดสอบที่เก็บ
มีห้องสมุด Web3 อยู่แล้วที่เขียนไว้ใน Swift เรารู้จุดแข็งและจุดอ่อนของพวกเขาและสำหรับกรณีการใช้งานของเราพวกเขาไม่ได้ทำงาน
Web3.swift ถูกสร้างขึ้นด้วยโมดูลาร์ความสามารถในการพกพาความเร็วและประสิทธิภาพในใจ
โอเคขอบคุณสำหรับ buzzwords แต่สิ่งนี้หมายถึงอะไร?
Web3.swift ถูกสร้างขึ้นเป็นโมดูลาร์ หากคุณติดตั้ง/ใช้ผลิตภัณฑ์ Web3 SPM พื้นฐานคุณจะได้รับการเข้าถึงฟังก์ชั่นพื้นฐานที่สุดเช่นการลงนามในธุรกรรมและโต้ตอบกับเซิร์ฟเวอร์ HTTP RPC
หากคุณต้องการเพิ่มการสนับสนุนสำหรับ IPC RPC หรืออย่างอื่นคุณสามารถสร้างไลบรารีที่ขึ้นอยู่กับ Web3 และใช้ฟังก์ชั่นที่แน่นอนนี้ได้อย่างง่ายดาย เพิ่มเติมเกี่ยวกับเรื่องนั้นในภายหลัง
หากคุณต้องการใช้ส่วนขยาย PromiseKit สำหรับการโทร Web3 คุณสามารถใช้ผลิตภัณฑ์ PromiseKit SPM ที่ให้ไว้หรือสร้างของคุณเอง
หากคุณต้องการแยกวิเคราะห์ JSON ABIS สำหรับสัญญาอัจฉริยะ Ethereum อย่างสะดวกคุณสามารถใช้ผลิตภัณฑ์ ABI Parsing SPM ที่ให้ไว้
ในที่สุดหากคุณต้องการเพิ่มฟังก์ชันการทำงานให้กับ Web3.swift ซึ่งยังไม่ได้ให้ไว้คุณไม่ต้องรอจนกว่าจะถูกรวมเข้าด้วยกันและปล่อยออกมาในเวอร์ชันชน คุณสามารถขยายฟังก์ชั่นการขยาย/อัปเดตได้อย่างง่ายภายในแอพของคุณเองเนื่องจาก API ของเราเปิดให้บริการสำหรับการเปลี่ยนแปลง
ตัวอย่างเช่นหากคุณต้องการเพิ่มเมธอด Web3 ซึ่งยังไม่ได้ให้โดย Web3.swift (เราจะรองรับวิธีการที่รองรับ 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) แต่ควรเข้ากันได้กับระบบ endian เล็ก ๆ ทั้งหมดที่สามารถรวบรวม Swift Compiler, Foundation และ Glibc
เราพยายามทำให้ห้องสมุดนี้เร็วที่สุดเท่าที่จะเป็นไปได้ในขณะที่พยายามจัดหา 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เป็นทางเลือกและคุณจะต้องใส่ลงในการพึ่งพาเป้าหมายของคุณ (และนำเข้าในภายหลัง) หากคุณต้องการใช้
หลังจากการติดตั้งคุณสามารถนำเข้า Web3 ในไฟล์ .swift ของคุณ
import Web3
// Optional
import Web3PromiseKit
import Web3ContractABIเนื่องจากการตัดสินใจภายในเราจึงหยุดสนับสนุนผู้จัดการแพ็คเกจอื่น ๆ นอกเหนือจาก SPM เริ่มต้นด้วยเวอร์ชัน 0.5.0
ในการอธิบายรายละเอียดเล็กน้อยเกี่ยวกับการตัดสินใจครั้งนี้ด้วย XCode 11 และ Swift 5.1 เรามาถึงจุดหนึ่งด้วย Swift Package Manager ซึ่งเริ่มทำให้ผู้จัดการแพ็คเกจอื่น ๆ ไม่เกี่ยวข้อง คุณสามารถโหลดการพึ่งพาทั้งหมดของคุณในโครงการ XCode ด้วย Swift Package Manager
ด้วยการอัปเดตเพิ่มเติมมันก็ยิ่งแพร่หลายมากขึ้น Cocoapods และผู้ดูแลคาร์เธจสูญเสียความสนใจในโครงการของพวกเขาและหยุดการบำรุงรักษา มีปัญหาที่ไม่ได้รับการแก้ไขมากมายปัญหามากมายโดยเฉพาะอย่างยิ่งสำหรับนักพัฒนาห้องสมุดที่มี cocoapods
ยุ่งยากมากสำหรับการไม่ได้รับจริง ผู้ใช้สามารถใส่การพึ่งพาซึ่งรองรับ SPM ลงในโครงการ XCODE ของพวกเขา แล้วทำไมต้องกังวล?
คำตอบนั้นง่าย บางคนยังคงใช้ xcode <11 และนักพัฒนาห้องสมุดบางคนขึ้นอยู่กับ Web3 ในพ็อด/คาร์เธจของตนเอง
การตัดสินใจนั้นยากและใช้เวลาสักครู่ แต่หลังจากเห็นว่าเวอร์ชันสุดท้ายมีความเสถียรมากและใช้ในแอพการผลิตจำนวนมากอยู่แล้วเราตัดสินใจที่จะเริ่มต้นด้วยการเคลื่อนไหวนี้ตอนนี้
Xcode 10 มีอายุมากกว่า 2 ปีแล้ว โครงการส่วนใหญ่อัพเกรดแล้วโครงการที่ไม่มีปัญหาใหญ่ไปกว่า Web3.swift ไม่ได้ทำการอัปเดตสำหรับ Cocoapods ...
เจ้าของห้องสมุดขึ้นอยู่กับ Web3.Swift ได้รับการสนับสนุนให้วาง cocoapods และ carthage สนับสนุนเช่นกัน
SPM คืออนาคต สำหรับผู้ใช้ Cocoapods และ Carthage ทั้งหมดที่ใช้เพราะห้องสมุดหลายแห่งยังไม่เปลี่ยนเป็น SPM: คุณยังสามารถเพิ่ม web3.swift เป็นผลิตภัณฑ์ SPM ลงใน .xcworkspace หรือ .xcodeproj และเก็บการพึ่งพาอื่น ๆ ทั้งหมดไว้ใน cocoapods/carthage แต่ยัง. เราขอแนะนำให้คุณสลับกับการพึ่งพามากที่สุดเท่าที่จะเป็นไปได้ที่จะ SPM ดีกว่าเร็วกว่าในภายหลัง ดูหัวข้อถัดไปเกี่ยวกับวิธีการทำเช่นนี้
การใช้ XCode 11 หรือใหม่กว่า (สำหรับ iOS, MacOS หรือแพลตฟอร์ม Apple อื่น ๆ ) คุณสามารถเพิ่มแพ็คเกจ SPM ได้ง่ายมาก
ใน XCode เลือกโครงการของคุณจากแบบเลื่อนลงเลือกโครงการไม่ใช่เป้าหมายเดียวในแท็บเลือก Swift Packages
จากนั้นคุณสามารถคลิกไอคอน + และใส่ใน URL ไปยังที่เก็บนี้ (https://github.com/boilertalk/web3.swift)
ตอนนี้คุณสามารถเลือกผลิตภัณฑ์ทั้งหมดและคลิกถัดไปจนกว่าจะมีการเพิ่มการพึ่งพา
แค่นั้นแค่นั้น หากคุณผลักดันการเปลี่ยนแปลงแม้กระทั่ง CI ของคุณจะไม่ทำให้เกิดปัญหาใด ๆ ไม่มีความยุ่งยากกับที่เก็บข้อมูลจำเพาะที่ล้าสมัยไม่มีปัญหากับข้อผิดพลาดของตัวเชื่อมโยงแปลก ๆ ซึ่งบางครั้งเกิดขึ้น/มีการพึ่งพาบางอย่าง
หากคุณต้องการคำแนะนำเพิ่มเติมเข้าร่วมกลุ่มโทรเลขของเราและเราจะช่วยคุณ https://t.me/web3_swift
ด้วย Web3.swift คุณสามารถใช้โหนด Ethereum บนเซิร์ฟเวอร์เพื่อสื่อสารกับ Ethereum
คุณสามารถส่งธุรกรรมที่ลงนามอ่านข้อมูลสัญญาฟังก์ชั่นการโทรและอื่น ๆ อีกมากมาย
คลาสพื้นฐานสำหรับวิธีการทั้งหมดที่มีอยู่คือ Web3 ตัวอย่างเช่นคุณสามารถสร้างอินสแตนซ์ด้วยผู้ให้บริการ HTTP:
let web3 = Web3 ( rpcURL : " https://mainnet.infura.io/<your_infura_id> " ) วิธีการ web3_ ทั้งหมดมีให้บริการโดยตรงจาก Web3 struct วิธีการ net_ มีอยู่ภายใต้โครงสร้าง net ใน web3 struct วิธี eth_ มีอยู่ภายใต้โครงสร้าง eth ใน web3 struct
โปรดดูตัวอย่างด้านล่าง
หมายเหตุ: สำหรับตัวอย่างการทำงานคุณต้องนำเข้า Web3 และ PromiseKit ก่อน
ส่งคืนเวอร์ชันไคลเอนต์ปัจจุบัน
พารามิเตอร์
ไม่มี
ผลตอบแทน
String - เวอร์ชันไคลเอนต์ปัจจุบัน
firstly {
web3 . clientVersion ( )
} . done { version in
print ( version )
} . catch { error in
print ( " Error " )
} ส่งคืนรหัสเครือข่ายปัจจุบัน
พารามิเตอร์
ไม่มี
ผลตอบแทน
String - รหัสเครือข่ายปัจจุบัน
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 struct หรือเอกสาร Ethereum JSON RPC อย่างเป็นทางการ
เรากำลังจัดทำโมดูลเสริมสำหรับการโต้ตอบกับสัญญาอัจฉริยะ ในการใช้งานคุณต้องเพิ่ม Web3ContractABI ไปยังการพึ่งพาเป้าหมายของคุณใน podfile ของคุณ (สำหรับ SPM) ตรวจสอบให้แน่ใจว่าคุณตรวจสอบคำแนะนำการติดตั้งก่อน
เรากำลังจัดหาตัวเลือกที่แตกต่างกันสองแบบเพื่อสร้างอินเทอร์เฟซ ABI ใน Swift ไม่ว่าคุณจะกำหนดฟังก์ชั่นและกิจกรรมของคุณด้วยตนเอง (หรือใช้หนึ่งในอินเทอร์เฟซที่เราให้ไว้เช่น ERC20 หรือ ERC721) หรือคุณแยกพวกเขาจากการเป็นตัวแทน JSON ABI เช่นเดียวกับใน Web3.Js
สัญญาคงที่คือคลาสที่ใช้งาน StaticContract พวกเขามีชุดของฟังก์ชั่นและเหตุการณ์ที่พวกเขาต้องการใช้จากสัญญาอัจฉริยะดั้งเดิม ตรวจสอบสัญญาคงที่ของเราเป็นจุดเริ่มต้น (ERC20 หรือ ERC721)
อินเทอร์เฟซ ERC20 แบบคงที่ของเราเรียกว่า GenericERC20Contract , สัญญา ERC721 เรียกว่า GenericERC721Contract ทั้งสองสามารถ subclassed เพื่อเพิ่มฟังก์ชั่นเพิ่มเติมสำหรับสัญญาที่กำหนดเอง
ด้วยประเภท 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 นี้คุณสามารถโต้ตอบกับสัญญาอัจฉริยะในเครือข่าย Ethereum!
สำหรับตัวอย่างเพิ่มเติมรวมถึงการสร้างสัญญา (การเรียกตัวสร้าง) ตรวจสอบการทดสอบของเรา
หากคุณได้รับข้อผิดพลาดนี้เมื่อแยกวิเคราะห์ ABI ของคุณจาก JSON อาจเป็นเพราะสัญญาของคุณมีฟังก์ชั่นทางเลือก ในการแก้ปัญหาให้ลบส่วนของ ABI ของคุณที่มีข้อมูลเกี่ยวกับฟังก์ชั่นทางเลือก ส่วนที่คุณควรลบอาจมีลักษณะเช่นนี้:
{
"payable": false,
"stateMutability": "nonpayable",
"type": "fallback"
},
จนกว่าเราจะไปถึงเวอร์ชัน 1.0.0 API ของเราอาจมีการเปลี่ยนแปลงการเปลี่ยนแปลงระหว่างการกระโดดรุ่นรอง นี่คือเพื่อให้แน่ใจว่าเราสามารถมุ่งเน้นไปที่การใช้งานที่ดีที่สุดในขณะที่เรากำลังพัฒนาอย่างหนักแทนที่จะพยายามรักษาสิ่งที่เลิกใช้แล้ว
ที่ถูกกล่าวว่าเราจะพยายามลดการเปลี่ยนแปลง แน่นอนที่สุดจะไม่มีอะไรมากมาย
The Awesome Guys at Boilertalk ⚗
... และสมาชิกที่ยอดเยี่ยมมากขึ้นจากชุมชน?
ตรวจสอบรายชื่อผู้สนับสนุนสำหรับรายการที่สมบูรณ์
Web3 สามารถใช้ได้ภายใต้ใบอนุญาต MIT ดูไฟล์ใบอนุญาตสำหรับข้อมูลเพิ่มเติม