
Web3.swift는 거래에 서명하고 이더 리움 네트워크에서 스마트 계약과 상호 작용하는 신속한 라이브러리입니다.
이를 통해 Geth 또는 Erigon Ethereum 노드 (예 : Chainnodes)에 연결하여 프로토콜의 구현을 작성할 필요없이 트랜잭션을 보내고 스마트 계약에서 값을 읽을 수 있습니다.
Web3.swift는 Swift 패키지 관리자와 함께 iOS, MacOS, TVOS, WatchOS 및 Linux를 지원합니다.
아래 사용량을 확인하거나 리포지토리 테스트를 살펴보십시오.
Swift로 작성된 Web3 라이브러리가 이미 있습니다. 우리는 그들의 강점과 약점을 알고 있으며 사용 사례를 위해 그들은 효과가 없었습니다.
Web3.swift 모듈성, 이식성, 속도 및 효율성을 염두에두고 구축되었습니다.
좋아, 유행어에 감사드립니다. 그러나 이것이 실제로 무엇을 의미합니까?
Web3.swift 모듈 식으로 만들어졌습니다. 기본 Web3 SPM 제품을 설치/사용하는 경우 트랜잭션 서명 및 HTTP RPC 서버와 상호 작용하는 것과 같은 가장 기본적인 기능에 액세스 할 수 있습니다.
IPC RPC 또는 다른 것에 대한 지원을 추가하려면 Web3 에 의존하는 라이브러리를 간단하게 만들고이 정확한 기능을 구현할 수 있습니다. 나중에 그것에 대해 더 자세히 설명합니다.
Web3 통화에 PromiseKit 확장을 사용하려면 제공된 Promiskit SPM 제품을 사용하거나 직접 만들 수 있습니다.
이더 리움 스마트 계약을 위해 JSON ABI를 편리하게 구문 분석하려면 제공된 ABI 구문 분석 SPM 제품을 사용할 수 있습니다.
마지막으로, 아직 제공되지 않은 Web3.swift 에 기능을 추가하려면 버전 범프에서 병합되어 해제 될 때까지 기다릴 필요가 없습니다. 우리의 API가 변경에 매우 열려 있기 때문에 자신의 앱 내에서 간단한 확장/업데이트 기능을 할 수 있습니다.
예를 들어, Web3.swift 에서 아직 제공되지 않은 Web3 메소드를 추가하려면 (Infura 지원 방법 만 지원할 것입니다), 메소드의 입력 및 출력 매개 변수에 따라 약 3 줄의 코드 만 추가하면됩니다. IPC RPC 지원을 추가하면 프로토콜과 응답 요청 만 구현됩니다.
당신이 볼 수 있듯이, Web3.swift 사용하면 모든 것이 가능합니다.
우리 가이 프로젝트를 시작하기 시작한 주된 이유 중 하나는 다른 플랫폼의 Swift 패키지 관리자와 함께 사용하기를 원했기 때문입니다.
이 때문에 Web3.swift iOS, MacOS, TVOS, WatchOS 및 Linux의 Swift 패키지 관리자를 통해 제공됩니다.
참고 : SPM의 경우 iOS, MacOS 및 공식적으로 지원되는 Linux 배포 (현재 Ubuntu 16.04 및 20.04) 만 테스트하고 있지만 빠른 컴파일러, Foundation 및 GLIBC를 컴파일 할 수있는 모든 Little 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 패키지 관리자와 함께 Xcode 프로젝트의 모든 종속성을 이미로드 할 수 있습니다.
더 많은 업데이트로 인해 더욱 널리 퍼졌습니다. 코코 포드와 카르타고 관리자는 프로젝트에 대한 관심을 잃고 유지 관리를 중단했습니다. 해결되지 않은 문제가 많이 있습니다. 특히 코코아포드가있는 도서관 개발자에게는 많은 문제가 있습니다.
실제 이득없이 너무 번거 로움. 사용자는 이미 SPM을 지원하는 종속성을 Xcode 프로젝트에 넣을 수 있습니다. 그래서 왜 귀찮게합니까?
대답은 간단합니다. 일부는 여전히 Xcode <11을 사용하고 일부 라이브러리 개발자는 자체 포드/카르타이지의 Web3에 의존합니다.
결정은 어려웠고 시간이 걸렸습니다. 그러나 마지막 버전이 매우 안정적이고 이미 많은 프로덕션 앱에서 사용되는 것을 본 후에, 우리는 지금이 움직임으로 시작하기로 결정했습니다.
Xcode 10은 이미 2 세 이상입니다. 대부분의 프로젝트는 이미 업그레이드되었으며 Web3.swift보다 더 큰 문제가없는 프로젝트는 코코아포에 대한 업데이트를하지 않습니다 ...
Web3.swift에 따라 도서관 소유자는 코코 포드와 카르타고 지원도 삭제하는 것이 좋습니다.
SPM은 미래입니다. 많은 라이브러리가 아직 SPM으로 전환되지 않았기 때문에 사용하는 모든 Cocoapods 및 Carthage 사용자의 경우 : Web3.swift를 여전히 .xcworkspace 또는 .xcodeproj 에 SPM 제품으로 추가하고 Cocoapods/Carthage 내부에 다른 모든 종속성을 유지할 수 있습니다. 그러나 여전히. SPM에 최대한 많은 종속성으로 전환하는 것이 좋습니다. 나중에 더 빨리. 이 작업을 수행하는 방법에 대한 다음 섹션을 참조하십시오.
iOS, MacOS 또는 기타 Apple 플랫폼의 경우 Xcode 11 이상을 사용하여 SPM 패키지를 매우 쉽게 추가 할 수 있습니다.
Xcode에서 프로젝트를 선택하십시오. 드롭 다운에서 단일 대상이 아닌 프로젝트를 선택하여 탭에서 Swift Packages 선택하십시오.
그런 다음 + 아이콘을 클릭 하고이 저장소 (https://github.com/boilertalk/web3.swift)에 URL을 넣을 수 있습니다.
이제 모든 제품을 선택하고 종속성이 추가 될 때까지 다음을 클릭 할 수 있습니다.
그게 다야. CI조차도 변화를 밀면 아무런 문제가 없습니다. 오래된 사양 리포지토리와의 번거 로움 없음, 때때로 발생하는 이상한 링커 오류에 문제가 없습니다.
추가 지침이 필요한 경우 Telegram Group에 가입하면 도와 드리겠습니다. 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 Struct의 net Struct에서 사용할 수 있습니다. eth_ 방법은 web3 구조물의 eth 구조 아래에서 사용할 수 있습니다.
아래 예제를 참조하십시오
참고 : 예제가 작동하려면 Web3 및 Promiskit을 먼저 가져와야합니다.
현재 클라이언트 버전을 반환합니다.
매개 변수
없음
보고
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 바이트 - 트랜잭션 해시 또는 거래를 아직 사용할 수없는 경우 0 해시
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 문서를 읽으십시오.
우리는 스마트 계약과의 상호 작용을위한 선택 모듈을 제공하고 있습니다. 이를 사용하려면 PodFile (SPM)의 대상 종속성에 Web3ContractABI 추가해야합니다. 먼저 설치 지침을 확인하십시오.
우리는 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를 사용하면 Ethereum 네트워크의 모든 스마트 계약과 상호 작용할 수 있습니다!
계약 생성 (생성자 호출)을 포함한 더 많은 예를 보려면 테스트를 확인하십시오.
JSON에서 ABI를 구문 분석 할 때이 오류가 발생하는 경우 계약에 폴백 기능이 있기 때문일 수 있습니다. 이를 해결하려면 폴백 함수에 대한 정보가있는 ABI 조각을 제거하십시오. 제거 해야하는 부분은 다음과 같습니다.
{
"payable": false,
"stateMutability": "nonpayable",
"type": "fallback"
},
우리가 버전 1.0.0에 도달 할 때까지 API는 마이너 버전 점프 사이의 변경 사항을 끊을 수 있습니다. 이것은 우리가 감가 상각 된 것을 유지하려고 노력하는 대신 강력한 개발 중에 최상의 구현을 제공하는 데 집중할 수 있도록하기위한 것입니다.
즉, 우리는 깨진 변화를 최소화하려고 노력할 것입니다. 가장 확실한 것은 많지 않을 것입니다.
보일러 갈 때의 멋진 사람들
... 그리고 커뮤니티의 더 멋진 회원?
전체 목록은 기고자 목록을 확인하십시오.
Web3는 MIT 라이센스에 따라 사용할 수 있습니다. 자세한 내용은 라이센스 파일을 참조하십시오.