diff --git a/.github/workflows/macOS-tests.yml b/.github/workflows/macOS-tests.yml index 3e3bafb6f..77bc06b23 100644 --- a/.github/workflows/macOS-tests.yml +++ b/.github/workflows/macOS-tests.yml @@ -8,7 +8,6 @@ on: - hotfix paths: - Packag*.swift - - web3swift.podspec - Cartfile - Sources/** - 'Tests/**' diff --git a/.gitignore b/.gitignore index 2dd3e0601..7d4533d53 100755 --- a/.gitignore +++ b/.gitignore @@ -43,13 +43,11 @@ Package.pins */.swiftpm/** Package.resolved -# CocoaPods -# -# We recommend against adding the Pods directory to your .gitignore. However -# you should judge for yourself, the pros and cons are mentioned at: -# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control -# -Example/**/Pods +# Pods +Pods/ +Podfile +Podfile.lock +*.podspec # Carthage # diff --git a/CONTRIBUTION.md b/CONTRIBUTION.md index be8daa9de..0f541e210 100644 --- a/CONTRIBUTION.md +++ b/CONTRIBUTION.md @@ -35,8 +35,6 @@ In ci/cd we’re using Xcode test plans feature to spread tests to local and rem Please add any files unused due build process to `excludeFiles` array in `Package.swift`. ### Carthage Please do not forget to add & remove all new or dropped files and dependencies in carthage `.xcodeproj` file if you’re working with project anywhere but carthage project. -### Cocoapods -Please do not forget to add & remove all dependencies within `web3swift.podspec` file. ### GitHub actions You’re able to use our github actions checks in your fork without needing to make PR to this repo. To get that just add your branch name to the branch list in file on path `.github/actions/ci.yml` to let the magic happening like follow: diff --git a/Package.swift b/Package.swift index 96a315782..92c871786 100755 --- a/Package.swift +++ b/Package.swift @@ -13,7 +13,7 @@ let package = Package( ], dependencies: [ .package(url: "https://github.com/attaswift/BigInt.git", from: "5.3.0"), - .package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", from: "1.5.1") + .package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", from: "1.8.0") ], targets: [ .target(name: "secp256k1"), diff --git a/README.md b/README.md index d468f2b8b..66b8accaf 100755 --- a/README.md +++ b/README.md @@ -5,23 +5,23 @@ [Join our discord](https://discord.gg/8bHCNmhS7x) or [Telegram](https://t.me/web3swift) if you need support or want to contribute to web3swift development! ![matter-github-swift](https://github.com/web3swift-team/web3swift/blob/develop/web3swift-logo.png) -[![Web3swift CI](https://github.com/web3swift-team/web3swift/actions/workflows/macOS-12.yml/badge.svg)](https://github.com/web3swift-team/web3swift/actions/workflows/macOS-12.yml) -[![Swift](https://img.shields.io/badge/Swift-5.4-orange.svg?style=flat)](https://developer.apple.com/swift/) -[![Platform](https://img.shields.io/cocoapods/p/web3swift?style=flat)](http://cocoapods.org/pods/web3swift) -[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/web3swift?style=flat)](http://cocoapods.org/pods/web3swift) +[![Web3swift CI](https://github.com/web3swift-team/web3swift/actions/workflows/macOS-tests.yml/badge.svg)](https://github.com/web3swift-team/web3swift/actions/workflows/macOS-tests.yml) +[![Swift](https://img.shields.io/badge/Swift-5.5-f26118.svg?style=flat)](https://developer.apple.com/swift/) [![License](https://img.shields.io/cocoapods/l/web3swift.svg?style=flat)](https://github.com/web3swift-team/web3swift/blob/master/LICENSE.md) -[![support](https://brianmacdonald.github.io/Ethonate/svg/eth-support-blue.svg)](https://brianmacdonald.github.io/Ethonate/address#0xe22b8979739d724343bd002f9f432f5990879901) [![Stackoverflow](https://img.shields.io/badge/stackoverflow-ask-blue.svg)](https://stackoverflow.com/questions/tagged/web3swift) + --- -- [Core features](#core-features) +- [Core Features](#core-features) - [Installation](#installation) - [Swift Package](#swift-package) - [CocoaPods](#cocoapods) - [Example usage](#example-usage) + - [Create Web3 Provider](#create-web3-provider) + - [Create Web3 Object](#create-web3-object) - [Send Ether](#send-ether) - [Contract read method](#contract-read-method) - [Write Transaction and call smart contract method](#write-transaction-and-call-smart-contract-method) @@ -48,11 +48,11 @@ - [x] :thought_balloon: Interaction with remote node via **JSON RPC** - [x] 🔐 Local **keystore management** (`geth` compatible) - [x] 🤖 Smart-contract **ABI parsing** -- [x] 🔓**ABI decoding** (V2 is supported with return of structures from public functions. Part of 0.4.22 Solidity compiler) +- [x] 🔓**ABI decoding** (V2 is supported with a return of structures from public functions. Part of 0.4.22 Solidity compiler) - [x] 🕸Ethereum Name Service **(ENS) support** - a secure & decentralised way to address resources both on and off the blockchain using simple, human-readable names - [x] :arrows_counterclockwise: **Smart contracts interactions** (read/write) - [x] ⛩ **Infura support** -- [x] ⚒ **Parsing TxPool** content into native values (ethereum addresses and transactions) - easy to get pending transactions +- [x] ⚒ **Parsing TxPool** content into native values (Ethereum addresses and transactions) - easy to get pending transactions - [x] 🖇 **Event loops** functionality - [x] 🕵️‍♂️ Possibility to **add or remove "middleware" that intercepts**, modifies and even **cancel transaction** workflow on stages "before assembly", "after assembly" and "before submission" - [x] ✅**Literally following the standards** (BIP, EIP, etc): @@ -66,7 +66,7 @@ ## Installation -### Swift Package (Recommended) +### Swift Package The [Swift Package Manager](https://swift.org/package-manager/ "") is a tool for automating the distribution of Swift code that is well integrated with Swift build system. Once you have your Swift package set up, adding `web3swift` as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`. @@ -89,30 +89,45 @@ import Web3Core ### CocoaPods -[CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command: +CocoaPods is not supported. -```bash -$ sudo gem install cocoapods +### Create Web3 Provider +Currently, web3swift supports only HTTP providers. WebSocket provider support was removed and is planned to be rebuilt from scratch. +To create a Web3HttpProvider you only need an RPC URL: +```swift +try await Web3HttpProvider(url: rpcUrl) ``` -To integrate web3swift into your Xcode project using CocoaPods, specify it in your `Podfile`: +But if you know chain ID upfront it's better to specify one as well as with chain ID, the initializer won't have to ask the RPC for it and thus you guarantee that the initializer completes successfully without any asynchronous calls, considering your URL using `http/s` scheme: +```swift +let optionalChainId: Networks = .Custom(networkID: 42) +try await Web3HttpProvider(url: rpcUrl, network: optionalChainId) +``` -```ruby -source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '13.0' +Specify a keystore manager for the Web3HttpProvider if you want `web3.personal` namespace to work as it relies on use of the keystore: +```swift +try await Web3HttpProvider(url: rpcUrl, network: optionalChainId, keystoreManager: optionalKeystoreManager) +``` -target '' do - use_frameworks! - pod 'web3swift' -end +### Create Web3 Object +Creating a Web3 object is quite simple once you have a Web3 HTTP provider: +```swift +Web3(provider: provider) ``` -Then, run the following command: -```bash -$ pod install +Or if you are a user of Infura: +```swift +try await Web3.InfuraMainnetWeb3(accessToken: optionalInfuraToken) +try await Web3.InfuraGoerliWeb3(accessToken: optionalInfuraToken) ``` -> **WARNING**: CocoaPods is a powerful tool for managing dependencies in iOS development, but it also has some limitations that preventing us of providing first class support there. We highly recommend using SPM first as using CocoaPods will delay new updates and bug fixes being delivered to you. +If you have a URL or you are using Infura you can use the following: +```swift +try await Web3.new(url, network: chainIdHere) +// or +let web3 = try await Web3.InfuraMainnetWeb3(accessToken: optionalInfuraToken) +let web3 = try await Web3.InfuraGoerliWeb3(accessToken: optionalGoerliToken) +``` ### Send Ether ```swift @@ -129,7 +144,7 @@ web3.eth.send(transaction) let contract = web3.contract(Web3.Utils.erc20ABI, at: receipt.contractAddress!)! let readOp = contract.createReadOperation("name")! readOp.transaction.from = EthereumAddress("0xe22b8979739D724343bd002F9f432F5990879901") -let response = try await readTX.callContractMethod() +let response = try await readTX.call() ``` ### Write Transaction and call smart contract method @@ -152,6 +167,7 @@ func feeHistory(blockCount: UInt, block: BlockNumber, percentiles:[Double]) asyn return response.result } ``` + ## Build from source ### SPM ```bash @@ -166,7 +182,7 @@ swift build - Swift 5.5 ## Documentation -Documentation is under construction👷🏻👷🏼‍♀️. We’re trying our best to comment all public API as detailed as we can, but the end it still far to come. But in one of the nearest minor updates we’ll bring DocC support of already done amount of docs. And your PR in such are more than welcome. +Documentation is under construction👷🏻👷🏼‍♀️. We’re trying our best to comment on all public APIs as detailed as possible, but the end is still far to come. But in one of the nearest minor updates we’ll bring DocC support of already done amount of docs. And your PR in such are more than welcome. ## Projects that are using web3swift Please take a look at [Our customers](https://github.com/web3swift-team/web3swift/wiki/Our-Customers) wiki page. @@ -180,7 +196,7 @@ Please take a look at [Our customers](https://github.com/web3swift-team/web3swif - If you **found a bug**, [open an issue](https://github.com/web3swift-team/web3swift/issues). ## Development -To do local development and run the local tests, we recommend to use [ganache](https://github.com/trufflesuite/ganache) which is also used by CI when running github actions. +To do local development and run the local tests, we recommend using [ganache](https://github.com/trufflesuite/ganache) which is also used by CI when running GitHub actions. ```cli // To install @@ -195,24 +211,24 @@ Make sure that `ganache` is running on its default port `8546`. To change the po ### Before you commit -We are using [pre-commit](https://pre-commit.com) to run validations locally before a commit is created. Please, install pre-commit and run `pre-commit install` from project's root directory. After that before every commit git hook will run and execute `codespell`, `swiftlint` and other checks. +We are using [pre-commit](https://pre-commit.com) to run validations locally before a commit is created. Please, install pre-commit and run `pre-commit install` from the project's root directory. After that before every commit git hook will run and execute `codespell`, `swiftlint` and other checks. ## Contribute Want to improve? It's awesome: -Then good news for you: **We are ready to pay for your contribution via [@gitcoin bot](https://gitcoin.co/grants/358/web3swift)!** +The good news for you: **We are ready to pay for your contribution via [@gitcoin bot](https://gitcoin.co/grants/358/web3swift)!** - If you **have a feature request**, [open an issue](https://github.com/web3swift-team/web3swift/issues). - If you **want to contribute**, [submit a pull request](https://github.com/web3swift-team/web3swift/pulls). ### Contribution -1. You are more than welcome to participate and get bounty by contributing! **Your contribution will be paid via [@gitcoin Grant program](https://gitcoin.co/grants/358/web3swift).** +1. You are more than welcome to participate and get a bounty by contributing! **Your contribution will be paid via [@gitcoin Grant program](https://gitcoin.co/grants/358/web3swift).** 2. Find or create an [issue](https://github.com/web3swift-team/web3swift/issues) 3. You can find open bounties in [Gitcoin Bounties](https://gitcoin.co/explorer?applicants=ALL&keywords=web3swift&order_by=-web3_created) list -4. Commita fix or a new feature in branch, push your changes +4. Commita fix or a new feature in a branch, push your changes 5. [Submit a pull request to **develop** branch](https://github.com/web3swift-team/web3swift/pulls) - 1. Please, provide detailed description to it to help us proceed it faster. + 1. Please, provide a detailed description of it to help us proceed faster. -[@skywinder](https://github.com/skywinder) are charged with open-sourсe and do not require money for using web3swift library. +[@skywinder](https://github.com/skywinder) are charged with open-sourсe and do not require money to use the web3swift library. We want to continue to do everything we can to move the needle forward. - **Support us** via [@gitcoin Grant program](https://gitcoin.co/grants/358/web3swift) diff --git a/Sources/Web3Core/Contract/ContractProtocol.swift b/Sources/Web3Core/Contract/ContractProtocol.swift index b82d8aa8c..5a2ab8863 100755 --- a/Sources/Web3Core/Contract/ContractProtocol.swift +++ b/Sources/Web3Core/Contract/ContractProtocol.swift @@ -143,8 +143,12 @@ public protocol ContractProtocol { /// - name with arguments:`myFunction(uint256)`. /// - method signature (with or without `0x` prefix, case insensitive): `0xFFffFFff`; /// - data: non empty bytes to decode; - /// - Returns: dictionary with decoded values. `nil` if decoding failed. - func decodeReturnData(_ method: String, data: Data) -> [String: Any]? + /// - Returns: dictionary with decoded values. + /// - Throws: + /// - `Web3Error.revert(String, String?)` when function call aborted by `revert(string)` and `require(expression, string)`. + /// - `Web3Error.revertCustom(String, Dictionary)` when function call aborted by `revert CustomError()`. + @discardableResult + func decodeReturnData(_ method: String, data: Data) throws -> [String: Any] /// Decode input arguments of a function. /// - Parameters: @@ -320,13 +324,40 @@ extension DefaultContractProtocol { return bloom.test(topic: event.topic) } - public func decodeReturnData(_ method: String, data: Data) -> [String: Any]? { + @discardableResult + public func decodeReturnData(_ method: String, data: Data) throws -> [String: Any] { if method == "fallback" { - return [String: Any]() + return [:] + } + + guard let function = methods[method]?.first else { + throw Web3Error.inputError(desc: "Make sure ABI you use contains '\(method)' method.") + } + + switch data.count % 32 { + case 0: + return try function.decodeReturnData(data) + case 4: + let selector = data[0..<4] + if selector.toHexString() == "08c379a0", let reason = ABI.Element.EthError.decodeStringError(data[4...]) { + throw Web3Error.revert("revert(string)` or `require(expression, string)` was executed. reason: \(reason)", reason: reason) + } + else if selector.toHexString() == "4e487b71", let reason = ABI.Element.EthError.decodePanicError(data[4...]) { + let panicCode = String(format: "%02X", Int(reason)).addHexPrefix() + throw Web3Error.revert("Error: call revert exception; VM Exception while processing transaction: reverted with panic code \(panicCode)", reason: panicCode) + } + else if let customError = errors[selector.toHexString().addHexPrefix().lowercased()] { + if let errorArgs = customError.decodeEthError(data[4...]) { + throw Web3Error.revertCustom(customError.signature, errorArgs) + } else { + throw Web3Error.inputError(desc: "Signature matches \(customError.errorDeclaration) but failed to be decoded.") + } + } else { + throw Web3Error.inputError(desc: "Make sure ABI you use contains error that can match signature: 0x\(selector.toHexString())") + } + default: + throw Web3Error.inputError(desc: "Given data has invalid bytes count.") } - return methods[method]?.compactMap({ function in - return function.decodeReturnData(data) - }).first } public func decodeInputData(_ method: String, data: Data) -> [String: Any]? { @@ -346,8 +377,32 @@ extension DefaultContractProtocol { return function.decodeInputData(Data(data[data.startIndex + 4 ..< data.startIndex + data.count])) } + public func decodeEthError(_ data: Data) -> [String: Any]? { + guard data.count >= 4, + let err = errors.first(where: { $0.value.methodEncoding == data[0..<4] })?.value else { + return nil + } + return err.decodeEthError(data[4...]) + } + public func getFunctionCalled(_ data: Data) -> ABI.Element.Function? { guard data.count >= 4 else { return nil } return methods[data[data.startIndex ..< data.startIndex + 4].toHexString().addHexPrefix()]?.first } } + +extension DefaultContractProtocol { + @discardableResult + public func callStatic(_ method: String, parameters: [Any], provider: Web3Provider) async throws -> [String: Any] { + guard let address = address else { + throw Web3Error.inputError(desc: "RPC failed: contract is missing an address.") + } + guard let data = self.method(method, parameters: parameters, extraData: nil) else { + throw Web3Error.dataError + } + let transaction = CodableTransaction(to: address, data: data) + + let result: Data = try await APIRequest.sendRequest(with: provider, for: .call(transaction, .latest)).result + return try decodeReturnData(method, data: result) + } +} diff --git a/Sources/Web3Core/EthereumABI/ABIElements.swift b/Sources/Web3Core/EthereumABI/ABIElements.swift index f238e543f..4c58f08e7 100755 --- a/Sources/Web3Core/EthereumABI/ABIElements.swift +++ b/Sources/Web3Core/EthereumABI/ABIElements.swift @@ -202,7 +202,7 @@ extension ABI.Element.Constructor { extension ABI.Element.Function { /// Encode parameters of a given contract method - /// - Parameter parameters: Parameters to pass to Ethereum contract + /// - Parameters: Parameters to pass to Ethereum contract /// - Returns: Encoded data public func encodeParameters(_ parameters: [Any]) -> Data? { guard parameters.count == inputs.count, @@ -292,6 +292,44 @@ extension ABI.Element.Event { } } +// MARK: - Decode custom error + +extension ABI.Element.EthError { + /// Decodes `revert CustomError(_)` calls. + /// - Parameters: + /// - data: bytes returned by a function call that stripped error signature hash. + /// - Returns: a dictionary containing decoded data mappend to indices and names of returned values or nil if decoding failed. + public func decodeEthError(_ data: Data) -> [String: Any]? { + guard inputs.count * 32 <= data.count, + let decoded = ABIDecoder.decode(types: inputs, data: data) else { + return nil + } + + var result = [String: Any]() + for (index, out) in inputs.enumerated() { + result["\(index)"] = decoded[index] + if !out.name.isEmpty { + result[out.name] = decoded[index] + } + } + return result + } + + /// Decodes `revert(string)` or `require(expression, string)` calls. + /// These calls are decomposed as `Error(string)` error. + public static func decodeStringError(_ data: Data) -> String? { + let decoded = ABIDecoder.decode(types: [.init(name: "", type: .string)], data: data) + return decoded?.first as? String + } + + /// Decodes `Panic(uint256)` errors. + /// See more about panic code explain at: https://docs.soliditylang.org/en/v0.8.21/control-structures.html#panic-via-assert-and-error-via-require + public static func decodePanicError(_ data: Data) -> BigUInt? { + let decoded = ABIDecoder.decode(types: [.init(name: "", type: .uint(bits: 256))], data: data) + return decoded?.first as? BigUInt + } +} + // MARK: - Function input/output decoding extension ABI.Element { @@ -304,7 +342,7 @@ extension ABI.Element { case .fallback: return nil case .function(let function): - return function.decodeReturnData(data) + return try? function.decodeReturnData(data) case .receive: return nil case .error: @@ -337,74 +375,38 @@ extension ABI.Element.Function { return ABIDecoder.decodeInputData(rawData, methodEncoding: methodEncoding, inputs: inputs) } - /// Decodes data returned by a function call. Able to decode `revert(string)`, `revert CustomError(...)` and `require(expression, string)` calls. + /// Decodes data returned by a function call. /// - Parameters: /// - data: bytes returned by a function call; - /// - errors: optional dictionary of known errors that could be returned by the function you called. Used to decode the error information. /// - Returns: a dictionary containing decoded data mappend to indices and names of returned values if these are not `nil`. - /// If `data` is an error response returns dictionary containing all available information about that specific error. Read more for details. + /// - Throws: + /// - `Web3Error.processingError(desc: String)` when decode process failed. /// /// Return cases: - /// - when no `outputs` declared and `data` is not an error response: + /// - when no `outputs` declared: /// ```swift - /// ["_success": true] + /// [:] /// ``` /// - when `outputs` declared and decoding completed successfully: /// ```swift - /// ["_success": true, "0": value_1, "1": value_2, ...] + /// ["0": value_1, "1": value_2, ...] /// ``` /// Additionally this dictionary will have mappings to output names if these names are specified in the ABI; - /// - function call was aborted using `revert(message)` or `require(expression, message)`: - /// ```swift - /// ["_success": false, "_abortedByRevertOrRequire": true, "_errorMessage": message]` - /// ``` - /// - function call was aborted using `revert CustomMessage()` and `errors` argument contains the ABI of that custom error type: - /// ```swift - /// ["_success": false, - /// "_abortedByRevertOrRequire": true, - /// "_error": error_name_and_types, // e.g. `MyCustomError(uint256, address senderAddress)` - /// "0": error_arg1, - /// "1": error_arg2, - /// ..., - /// "error_arg1_name": error_arg1, // Only named arguments will be mapped to their names, e.g. `"senderAddress": EthereumAddress` - /// "error_arg2_name": error_arg2, // Otherwise, you can query them by position index. - /// ...] - /// ``` - /// - in case of any error: - /// ```swift - /// ["_success": false, "_failureReason": String] - /// ``` - /// Error reasons include: - /// - `outputs` declared but at least one value failed to be decoded; - /// - `data.count` is less than `outputs.count * 32`; - /// - `outputs` defined and `data` is empty; - /// - `data` represent reverted transaction - /// - /// How `revert(string)` and `require(expression, string)` return value is decomposed: - /// - `08C379A0` function selector for `Error(string)`; - /// - next 32 bytes are the data offset; - /// - next 32 bytes are the error message length; - /// - the next N bytes, where N >= 32, are the message bytes - /// - the rest are 0 bytes padding. - public func decodeReturnData(_ data: Data, errors: [String: ABI.Element.EthError]? = nil) -> [String: Any] { - if let decodedError = decodeErrorResponse(data, errors: errors) { - return decodedError - } - + public func decodeReturnData(_ data: Data) throws -> [String: Any] { guard !outputs.isEmpty else { NSLog("Function doesn't have any output types to decode given data.") - return ["_success": true] + return [:] } guard outputs.count * 32 <= data.count else { - return ["_success": false, "_failureReason": "Bytes count must be at least \(outputs.count * 32). Given \(data.count). Decoding will fail."] + throw Web3Error.processingError(desc: "Bytes count must be at least \(outputs.count * 32). Given \(data.count). Decoding will fail.") } // TODO: need improvement - we should be able to tell which value failed to be decoded guard let values = ABIDecoder.decode(types: outputs, data: data) else { - return ["_success": false, "_failureReason": "Failed to decode at least one value."] + throw Web3Error.processingError(desc: "Failed to decode at least one value.") } - var returnArray: [String: Any] = ["_success": true] + var returnArray: [String: Any] = [:] for i in outputs.indices { returnArray["\(i)"] = values[i] if !outputs[i].name.isEmpty { @@ -453,6 +455,7 @@ extension ABI.Element.Function { /// // "_parsingError" is optional and is present only if decoding of custom error arguments failed /// "_parsingError": "Data matches MyCustomError(uint256, address senderAddress) but failed to be decoded."] /// ``` + @available(*, deprecated, message: "Use decode function from `ABI.Element.EthError` instead") public func decodeErrorResponse(_ data: Data, errors: [String: ABI.Element.EthError]? = nil) -> [String: Any]? { /// If data is empty and outputs are expected it is treated as a `require(expression)` or `revert()` call with no message. /// In solidity `require(false)` and `revert()` calls return empty error response. diff --git a/Sources/Web3Core/EthereumABI/ABIParameterTypes.swift b/Sources/Web3Core/EthereumABI/ABIParameterTypes.swift index eb536237e..7abd04ed1 100755 --- a/Sources/Web3Core/EthereumABI/ABIParameterTypes.swift +++ b/Sources/Web3Core/EthereumABI/ABIParameterTypes.swift @@ -168,31 +168,79 @@ extension ABI.Element.ParameterType: Equatable { } extension ABI.Element.Function { + /// String representation of a function, e.g. `transfer(address,uint256)`. public var signature: String { return "\(name ?? "")(\(inputs.map { $0.type.abiRepresentation }.joined(separator: ",")))" } + /// Function selector, e.g. `"cafe1234"`. Without hex prefix `0x`. + @available(*, deprecated, renamed: "selector", message: "Please, use 'selector' property instead.") public var methodString: String { + return selector + } + + /// Function selector, e.g. `"cafe1234"`. Without hex prefix `0x`. + public var selector: String { return String(signature.sha3(.keccak256).prefix(8)) } + /// Function selector (e.g. `0xcafe1234`) but as raw bytes. + @available(*, deprecated, renamed: "selectorEncoded", message: "Please, use 'selectorEncoded' property instead.") public var methodEncoding: Data { - return signature.data(using: .ascii)!.sha3(.keccak256)[0...3] + return selectorEncoded + } + + /// Function selector (e.g. `0xcafe1234`) but as raw bytes. + public var selectorEncoded: Data { + return Data.fromHex(selector)! } } // MARK: - Event topic extension ABI.Element.Event { + /// String representation of an event, e.g. `ContractCreated(address)`. public var signature: String { return "\(name)(\(inputs.map { $0.type.abiRepresentation }.joined(separator: ",")))" } + /// Hashed signature of an event, e.g. `0xcf78cf0d6f3d8371e1075c69c492ab4ec5d8cf23a1a239b6a51a1d00be7ca312`. public var topic: Data { return signature.data(using: .ascii)!.sha3(.keccak256) } } +extension ABI.Element.EthError { + /// String representation of an error, e.g. `TrasferFailed(address)`. + public var signature: String { + return "\(name)(\(inputs.map { $0.type.abiRepresentation }.joined(separator: ",")))" + } + + /// Error selector, e.g. `"cafe1234"`. Without hex prefix `0x`. + @available(*, deprecated, renamed: "selector", message: "Please, use 'selector' property instead.") + public var methodString: String { + return selector + } + + /// Error selector, e.g. `"cafe1234"`. Without hex prefix `0x`. + public var selector: String { + return String(signature.sha3(.keccak256).prefix(8)) + } + + /// Error selector (e.g. `0xcafe1234`) but as raw bytes. + @available(*, deprecated, renamed: "selectorEncoded", message: "Please, use 'selectorEncoded' property instead.") + public var methodEncoding: Data { + return selectorEncoded + } + + /// Error selector (e.g. `0xcafe1234`) but as raw bytes. + public var selectorEncoded: Data { + return Data.fromHex(selector)! + } +} + extension ABI.Element.ParameterType: ABIEncoding { + + /// Returns a valid solidity type like `address`, `uint128` or any other built-in type from Solidity. public var abiRepresentation: String { switch self { case .uint(let bits): diff --git a/Sources/Web3Core/EthereumABI/Sequence+ABIExtension.swift b/Sources/Web3Core/EthereumABI/Sequence+ABIExtension.swift index 1d2f32744..390b928ee 100644 --- a/Sources/Web3Core/EthereumABI/Sequence+ABIExtension.swift +++ b/Sources/Web3Core/EthereumABI/Sequence+ABIExtension.swift @@ -56,6 +56,8 @@ public extension Sequence where Element == ABI.Element { var errors = [String: ABI.Element.EthError]() for case let .error(error) in self { errors[error.name] = error + errors[error.signature] = error + errors[error.methodString.addHexPrefix().lowercased()] = error } return errors } diff --git a/Sources/Web3Core/EthereumNetwork/Request/APIRequest+ComputedProperties.swift b/Sources/Web3Core/EthereumNetwork/Request/APIRequest+ComputedProperties.swift index cfa7f5190..fc711ce4b 100644 --- a/Sources/Web3Core/EthereumNetwork/Request/APIRequest+ComputedProperties.swift +++ b/Sources/Web3Core/EthereumNetwork/Request/APIRequest+ComputedProperties.swift @@ -8,15 +8,12 @@ import Foundation extension APIRequest { - var method: REST { + public var method: REST { .POST } - public var encodedBody: Data { - let request = RequestBody(method: call, params: parameters) - // this is safe to force try this here - // Because request must failed to compile if it not conformable with `Encodable` protocol - return try! JSONEncoder().encode(request) + public var encodedBody: Data { + RequestBody(method: call, params: parameters).encodedBody } var parameters: [RequestParameter] { diff --git a/Sources/Web3Core/EthereumNetwork/Request/APIRequest+Methods.swift b/Sources/Web3Core/EthereumNetwork/Request/APIRequest+Methods.swift index 58e13aa0f..c25ee496d 100644 --- a/Sources/Web3Core/EthereumNetwork/Request/APIRequest+Methods.swift +++ b/Sources/Web3Core/EthereumNetwork/Request/APIRequest+Methods.swift @@ -8,22 +8,116 @@ import Foundation import BigInt +/// TODO: should we do more error explain like ethers.js? +/// https://github.com/ethers-io/ethers.js/blob/0bfa7f497dc5793b66df7adfb42c6b846c51d794/packages/providers/src.ts/json-rpc-provider.ts#L55 +func checkError(method: String, error: JsonRpcErrorObject.RpcError) throws -> String { + if method == "eth_call" { + if let result = spelunkData(value: error) { + return result.data + } + throw Web3Error.nodeError(desc: "Error data decoding failed: missing revert data in exception; Transaction reverted without a reason string.") + } + + throw Web3Error.nodeError(desc: error.message) +} + +func spelunkData(value: Any?) -> (message: String, data: String)? { + if (value == nil) { + return nil + } + + func spelunkRpcError(_ message: String, data: String) -> (message: String, data: String)? { + if message.contains("revert") && data.isHex { + return (message, data) + } else { + return nil + } + } + + if let error = value as? JsonRpcErrorObject.RpcError { + if let data = error.data as? String { + return spelunkRpcError(error.message, data: data) + } else { + return spelunkData(value: error.data) + } + } + + // Spelunk further... + if let object = value as? [String: Any] { + if let message = object["message"] as? String, + let data = object["data"] as? String { + return spelunkRpcError(message, data: data) + } + + for value in object.values { + if let result = spelunkData(value: value) { + return result + } + return nil + } + } + if let array = value as? [Any] { + for e in array { + if let result = spelunkData(value: e) { + return result + } + return nil + } + } + + // Might be a JSON string we can further descend... + if let string = value as? String, let data = string.data(using: .utf8) { + let json = try? JSONSerialization.jsonObject(with: data) + return spelunkData(value: json) + } + + return nil +} + extension APIRequest { public static func sendRequest(with provider: Web3Provider, for call: APIRequest) async throws -> APIResponse { - let request = setupRequest(for: call, with: provider) - return try await APIRequest.send(uRLRequest: request, with: provider.session) + try await send(call.call, parameters: call.parameters, with: provider) } - static func setupRequest(for call: APIRequest, with provider: Web3Provider) -> URLRequest { + static func setupRequest(for body: RequestBody, with provider: Web3Provider) -> URLRequest { var urlRequest = URLRequest(url: provider.url, cachePolicy: .reloadIgnoringCacheData) urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") urlRequest.setValue("application/json", forHTTPHeaderField: "Accept") - urlRequest.httpMethod = call.method.rawValue - urlRequest.httpBody = call.encodedBody + urlRequest.httpMethod = "POST" + urlRequest.httpBody = body.encodedBody return urlRequest } - public static func send(uRLRequest: URLRequest, with session: URLSession) async throws -> APIResponse { + public static func send(_ method: String, parameters: [Encodable], with provider: Web3Provider) async throws -> APIResponse { + let body = RequestBody(method: method, params: parameters) + let uRLRequest = setupRequest(for: body, with: provider) + + let data: Data + do { + data = try await send(uRLRequest: uRLRequest, with: provider.session) + } catch Web3Error.rpcError(let error) { + let responseAsString = try checkError(method: method, error: error) + guard let LiteralType = Result.self as? LiteralInitiableFromString.Type, + let literalValue = LiteralType.init(from: responseAsString), + let result = literalValue as? Result else { + throw Web3Error.dataError + } + return APIResponse(id: 2, result: result) + } + + /// Checks if `Result` type can be initialized from HEX-encoded bytes. + /// If it can - we attempt initializing a value of `Result` type. + if let LiteralType = Result.self as? LiteralInitiableFromString.Type { + guard let responseAsString = try? JSONDecoder().decode(APIResponse.self, from: data) else { throw Web3Error.dataError } + guard let literalValue = LiteralType.init(from: responseAsString.result) else { throw Web3Error.dataError } + /// `literalValue` conforms `LiteralInitiableFromString` (which conforms to an `APIResponseType` type) so it never fails. + guard let result = literalValue as? Result else { throw Web3Error.typeError } + return APIResponse(id: responseAsString.id, jsonrpc: responseAsString.jsonrpc, result: result) + } + return try JSONDecoder().decode(APIResponse.self, from: data) + } + + public static func send(uRLRequest: URLRequest, with session: URLSession) async throws -> Data { let (data, response) = try await session.data(for: uRLRequest) guard 200 ..< 400 ~= response.statusCode else { @@ -34,9 +128,9 @@ extension APIRequest { } } - if let error = (try? JSONDecoder().decode(JsonRpcErrorObject.self, from: data))?.error { + if let error = JsonRpcErrorObject.init(from: data)?.error { guard let parsedErrorCode = error.parsedErrorCode else { - throw Web3Error.nodeError(desc: "\(error.message)\nError code: \(error.code)") + throw Web3Error.rpcError(error) } let description = "\(parsedErrorCode.errorName). Error code: \(error.code). \(error.message)" switch parsedErrorCode { @@ -49,35 +143,51 @@ extension APIRequest { } } - /// This bit of code is purposed to work with literal types that comes in ``Response`` in hexString type. - /// Currently it's just `Data` and any kind of Integers `(U)Int`, `Big(U)Int`. - if let LiteralType = Result.self as? LiteralInitiableFromString.Type { - guard let responseAsString = try? JSONDecoder().decode(APIResponse.self, from: data) else { throw Web3Error.dataError } - guard let literalValue = LiteralType.init(from: responseAsString.result) else { throw Web3Error.dataError } - /// `literalValue` conforms `LiteralInitiableFromString`, that conforming to an `APIResponseType` type, so it's never fails. - guard let result = literalValue as? Result else { throw Web3Error.typeError } - return APIResponse(id: responseAsString.id, jsonrpc: responseAsString.jsonrpc, result: result) - } - return try JSONDecoder().decode(APIResponse.self, from: data) + return data } } /// JSON RPC Error object. See official specification https://www.jsonrpc.org/specification#error_object -private struct JsonRpcErrorObject: Decodable { +public struct JsonRpcErrorObject { public let error: RpcError? - class RpcError: Decodable { - let message: String - let code: Int + public class RpcError { + public let message: String + public let code: Int + public let data: Any? + + init(message: String, code: Int, data: Any?) { + self.message = message + self.code = code + self.data = data + } + var parsedErrorCode: JsonRpcErrorCode? { JsonRpcErrorCode.from(code) } } + + init?(from data: Data) { + guard let root = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else { + return nil + } + if let error = root["error"] as? [String: Any], + let message = error["message"] as? String, + let code = error["code"] as? Int { + guard let errorData = error["data"] else { + self.error = RpcError(message: message, code: code, data: nil) + return + } + self.error = RpcError(message: message, code: code, data: errorData) + } else { + self.error = nil + } + } } /// For error codes specification see chapter `5.1 Error object` /// https://www.jsonrpc.org/specification#error_object -private enum JsonRpcErrorCode { +enum JsonRpcErrorCode { /// -32700 /// Invalid JSON was received by the server. An error occurred on the server while parsing the JSON case parseError diff --git a/Sources/Web3Core/EthereumNetwork/Request/APIRequest+UtilityTypes.swift b/Sources/Web3Core/EthereumNetwork/Request/APIRequest+UtilityTypes.swift index ca55d622f..1e40e53d5 100644 --- a/Sources/Web3Core/EthereumNetwork/Request/APIRequest+UtilityTypes.swift +++ b/Sources/Web3Core/EthereumNetwork/Request/APIRequest+UtilityTypes.swift @@ -14,7 +14,7 @@ public struct APIResponse: Decodable where Result: APIResultType { public var result: Result } -enum REST: String { +public enum REST: String { case POST case GET } @@ -24,5 +24,30 @@ struct RequestBody: Encodable { var id = Counter.increment() var method: String - var params: [RequestParameter] + var params: [Encodable] + + enum CodingKeys: String, CodingKey { + case jsonrpc + case id + case method + case params + } + + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(jsonrpc, forKey: .jsonrpc) + try container.encode(id, forKey: .id) + try container.encode(method, forKey: .method) + + var paramsContainer = container.superEncoder(forKey: .params).unkeyedContainer() + try params.forEach { a in + try paramsContainer.encode(a) + } + } + + public var encodedBody: Data { + // Safe to use force-try because request will fail to + // compile if it's not conforming to the `Encodable` protocol. + return try! JSONEncoder().encode(self) + } } diff --git a/Sources/Web3Core/KeystoreManager/BIP32Keystore.swift b/Sources/Web3Core/KeystoreManager/BIP32Keystore.swift index 22b305431..8cedb7985 100755 --- a/Sources/Web3Core/KeystoreManager/BIP32Keystore.swift +++ b/Sources/Web3Core/KeystoreManager/BIP32Keystore.swift @@ -111,7 +111,7 @@ public class BIP32Keystore: AbstractKeystore { addressStorage = PathAddressStorage() guard let rootNode = HDNode(seed: seed)?.derive(path: prefixPath, derivePrivateKey: true) else { return nil } self.rootPrefix = prefixPath - try createNewAccount(parentNode: rootNode, password: password) + try createNewAccount(parentNode: rootNode) guard let serializedRootNode = rootNode.serialize(serializePublic: false) else { throw AbstractKeystoreError.keyDerivationError } @@ -129,14 +129,14 @@ public class BIP32Keystore: AbstractKeystore { guard rootNode.depth == prefixPath.components(separatedBy: "/").count - 1 else { throw AbstractKeystoreError.encryptionError("Derivation depth mismatch") } - try createNewAccount(parentNode: rootNode, password: password) + try createNewAccount(parentNode: rootNode) guard let serializedRootNode = rootNode.serialize(serializePublic: false) else { throw AbstractKeystoreError.keyDerivationError } try encryptDataToStorage(password, data: serializedRootNode, aesMode: self.keystoreParams!.crypto.cipher) } - func createNewAccount(parentNode: HDNode, password: String = "web3swift") throws { + internal func createNewAccount(parentNode: HDNode) throws { let maxIndex = addressStorage.paths .compactMap { $0.components(separatedBy: "/").last } .compactMap { UInt32($0) } diff --git a/Sources/Web3Core/Utility/BigUInt+Extension.swift b/Sources/Web3Core/Utility/BigUInt+Extension.swift index 6144b6247..9617ab680 100755 --- a/Sources/Web3Core/Utility/BigUInt+Extension.swift +++ b/Sources/Web3Core/Utility/BigUInt+Extension.swift @@ -13,9 +13,3 @@ public extension BigUInt { self = value } } - -#if COCOAPODS -extension BigUInt { - var isZero: Bool { self == 0 } -} -#endif diff --git a/Sources/Web3Core/Utility/String+Extension.swift b/Sources/Web3Core/Utility/String+Extension.swift index 529fe2ff0..778558166 100755 --- a/Sources/Web3Core/Utility/String+Extension.swift +++ b/Sources/Web3Core/Utility/String+Extension.swift @@ -120,7 +120,7 @@ extension String { let to16 = utf16.index(utf16.startIndex, offsetBy: nsRange.location + nsRange.length, limitedBy: utf16.endIndex), let from = from16.samePosition(in: self), let to = to16.samePosition(in: self) - else { return nil } + else { return nil } return from ..< to } @@ -136,25 +136,39 @@ extension String { trimmingCharacters(in: .whitespacesAndNewlines) } - /// Splits a string into groups of `every` n characters, grouping from left-to-right by default. If `backwards` is true, right-to-left. - public func split(every: Int, backwards: Bool = false) -> [String] { - var result = [String]() - - for i in stride(from: 0, to: self.count, by: every) { - switch backwards { - case true: - let endIndex = self.index(self.endIndex, offsetBy: -i) - let startIndex = self.index(endIndex, offsetBy: -every, limitedBy: self.startIndex) ?? self.startIndex - result.insert(String(self[startIndex.. [String] { + var result = [String]() + + for i in stride(from: 0, to: self.count, by: every) { + switch backwards { + case true: + let endIndex = self.index(self.endIndex, offsetBy: -i) + let startIndex = self.index(endIndex, offsetBy: -every, limitedBy: self.startIndex) ?? self.startIndex + result.insert(String(self[startIndex.. [EthereumAddress] { guard let keystoreManager = self.web3.provider.attachedKeystoreManager else { + // TODO: add the following error message: Missing `attachedKeystoreManager`. throw Web3Error.walletError } guard let ethAddresses = keystoreManager.addresses else { + // TODO: add the following error message: Missing attached keystore is empty. throw Web3Error.walletError } return ethAddresses @@ -42,6 +46,12 @@ extension Web3.Web3Wallet { } } + /// Execute `personal_sign` for given arbitrary message. + /// - Parameters: + /// - personalMessage: message. Must be HEX formatted: message -> to 'UTF-8 bytes' -> to hex string! + /// - account: signer address. + /// - password: web3 attached keystore password. + /// - Returns: signature for the given message or throws an error. public func signPersonalMessage(_ personalMessage: String, account: EthereumAddress, password: String ) throws -> Data { guard let data = Data.fromHex(personalMessage) else { throw Web3Error.dataError diff --git a/Sources/web3swift/Operations/ReadOperation.swift b/Sources/web3swift/Operations/ReadOperation.swift index 50dc30ab4..c2b9365ca 100755 --- a/Sources/web3swift/Operations/ReadOperation.swift +++ b/Sources/web3swift/Operations/ReadOperation.swift @@ -35,7 +35,7 @@ public class ReadOperation { } // TODO: Remove type erasing here, some broad wide protocol should be added instead - public func callContractMethod() async throws -> [String: Any] { + public func call() async throws -> [String: Any] { // MARK: Read data from ABI flow // FIXME: This should be dropped, and after `execute()` call, just to decode raw data. let data: Data = try await self.web3.eth.callTransaction(transaction) @@ -43,9 +43,6 @@ public class ReadOperation { let resultHex = data.toHexString().addHexPrefix() return ["result": resultHex] } - guard let decodedData = self.contract.decodeReturnData(self.method, data: data) else { - throw Web3Error.processingError(desc: "Can not decode returned parameters") - } - return decodedData + return try self.contract.decodeReturnData(self.method, data: data) } } diff --git a/Sources/web3swift/Tokens/ERC1155/Web3+ERC1155.swift b/Sources/web3swift/Tokens/ERC1155/Web3+ERC1155.swift index c00606e59..e1c2fbc14 100644 --- a/Sources/web3swift/Tokens/ERC1155/Web3+ERC1155.swift +++ b/Sources/web3swift/Tokens/ERC1155/Web3+ERC1155.swift @@ -71,7 +71,7 @@ public class ERC1155: IERC1155 { } guard contract.contract.address != nil else { return } - guard let tokenIdPromise = try await contract.createReadOperation("id")?.callContractMethod() else { return } + guard let tokenIdPromise = try await contract.createReadOperation("id")?.call() else { return } guard let tokenId = tokenIdPromise["0"] as? BigUInt else { return } self._tokenId = tokenId @@ -95,7 +95,7 @@ public class ERC1155: IERC1155 { public func balanceOf(account: EthereumAddress, id: BigUInt) async throws -> BigUInt { let result = try await contract .createReadOperation("balanceOf", parameters: [account, id])! - .callContractMethod() + .call() guard let res = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } @@ -107,14 +107,14 @@ public class ERC1155: IERC1155 { } public func isApprovedForAll(owner: EthereumAddress, operator user: EthereumAddress, scope: Data) async throws -> Bool { - let result = try await contract.createReadOperation("isApprovedForAll", parameters: [owner, user, scope])!.callContractMethod() + let result = try await contract.createReadOperation("isApprovedForAll", parameters: [owner, user, scope])!.call() guard let res = result["0"] as? Bool else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } public func supportsInterface(interfaceID: String) async throws -> Bool { - let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.callContractMethod() + let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.call() guard let res = result["0"] as? Bool else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res diff --git a/Sources/web3swift/Tokens/ERC1376/Web3+ERC1376.swift b/Sources/web3swift/Tokens/ERC1376/Web3+ERC1376.swift index 91fa18f31..9bdcad06d 100644 --- a/Sources/web3swift/Tokens/ERC1376/Web3+ERC1376.swift +++ b/Sources/web3swift/Tokens/ERC1376/Web3+ERC1376.swift @@ -89,14 +89,14 @@ public class ERC1376: IERC1376, ERC20BaseProperties { } public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -106,7 +106,8 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() + var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -124,7 +125,8 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() + var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -142,7 +144,8 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() + var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -160,7 +163,8 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() + var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -175,7 +179,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { } public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -185,7 +189,8 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() + var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -206,7 +211,8 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() + var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -224,7 +230,8 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() + var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -246,7 +253,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { func spendableAllowance(owner: EthereumAddress, spender: EthereumAddress) async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("spendableAllowance", parameters: [owner, spender])!.callContractMethod() + let result = try await contract.createReadOperation("spendableAllowance", parameters: [owner, spender])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -256,7 +263,8 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() + var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -274,7 +282,8 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() + var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -289,7 +298,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { } func nonceOf(owner: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("nonceOf", parameters: [owner])!.callContractMethod() + let result = try await contract.createReadOperation("nonceOf", parameters: [owner])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -306,7 +315,8 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() + var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -323,7 +333,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { } func directDebit(debtor: EthereumAddress, receiver: EthereumAddress) async throws -> DirectDebit { - let result = try await contract.createReadOperation("directDebit", parameters: [debtor, receiver])!.callContractMethod() + let result = try await contract.createReadOperation("directDebit", parameters: [debtor, receiver])!.call() guard let res = result["0"] as? DirectDebit else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res diff --git a/Sources/web3swift/Tokens/ERC1400/Web3+ERC1400.swift b/Sources/web3swift/Tokens/ERC1400/Web3+ERC1400.swift index b800f70bd..0938400a7 100644 --- a/Sources/web3swift/Tokens/ERC1400/Web3+ERC1400.swift +++ b/Sources/web3swift/Tokens/ERC1400/Web3+ERC1400.swift @@ -86,14 +86,14 @@ public class ERC1400: IERC1400, ERC20BaseProperties { } public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -103,7 +103,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -122,7 +122,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -141,7 +141,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -157,7 +157,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { } public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -167,7 +167,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -184,7 +184,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { // ERC1400 methods public func getDocument(name: Data) async throws -> (String, Data) { - let result = try await contract.createReadOperation("getDocument", parameters: [name])!.callContractMethod() + let result = try await contract.createReadOperation("getDocument", parameters: [name])!.call() guard let res = result["0"] as? (String, Data) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -197,14 +197,14 @@ public class ERC1400: IERC1400, ERC20BaseProperties { } public func balanceOfByPartition(partition: Data, tokenHolder: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOfByPartition", parameters: [partition, tokenHolder])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOfByPartition", parameters: [partition, tokenHolder])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func partitionsOf(tokenHolder: EthereumAddress) async throws -> [Data] { - let result = try await contract.createReadOperation("partitionsOf", parameters: [tokenHolder])!.callContractMethod() + let result = try await contract.createReadOperation("partitionsOf", parameters: [tokenHolder])!.call() guard let res = result["0"] as? [Data] else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -214,7 +214,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -233,7 +233,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -252,7 +252,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -271,7 +271,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -287,7 +287,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { } public func isControllable() async throws -> Bool { - let result = try await contract.createReadOperation("isControllable")!.callContractMethod() + let result = try await contract.createReadOperation("isControllable")!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -297,7 +297,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -316,7 +316,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -356,21 +356,21 @@ public class ERC1400: IERC1400, ERC20BaseProperties { } public func isOperator(operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isOperator", parameters: [user, tokenHolder])!.callContractMethod() + let result = try await contract.createReadOperation("isOperator", parameters: [user, tokenHolder])!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func isOperatorForPartition(partition: Data, operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isOperatorForPartition", parameters: [partition, user, tokenHolder])!.callContractMethod() + let result = try await contract.createReadOperation("isOperatorForPartition", parameters: [partition, user, tokenHolder])!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func isIssuable() async throws -> Bool { - let result = try await contract.createReadOperation("isIssuable")!.callContractMethod() + let result = try await contract.createReadOperation("isIssuable")!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -380,7 +380,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -399,7 +399,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -418,7 +418,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -437,7 +437,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -456,7 +456,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -475,7 +475,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -492,7 +492,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { public func canTransfer(to: EthereumAddress, amount: String, data: [UInt8]) async throws -> ([UInt8], Data) { // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -503,7 +503,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let result = try await contract.createReadOperation("canTransfer", parameters: [to, value, data])!.callContractMethod() + let result = try await contract.createReadOperation("canTransfer", parameters: [to, value, data])!.call() guard let res = result["0"] as? ([UInt8], Data) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -511,7 +511,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { public func canTransferFrom(originalOwner: EthereumAddress, to: EthereumAddress, amount: String, data: [UInt8]) async throws -> ([UInt8], Data) { // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -522,7 +522,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let result = try await contract.createReadOperation("canTransfer", parameters: [originalOwner, to, value, data])!.callContractMethod() + let result = try await contract.createReadOperation("canTransfer", parameters: [originalOwner, to, value, data])!.call() guard let res = result["0"] as? ([UInt8], Data) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -530,7 +530,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { public func canTransferByPartition(originalOwner: EthereumAddress, to: EthereumAddress, partition: Data, amount: String, data: [UInt8]) async throws -> ([UInt8], Data, Data) { // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -541,7 +541,7 @@ public class ERC1400: IERC1400, ERC20BaseProperties { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let result = try await contract.createReadOperation("canTransfer", parameters: [originalOwner, to, partition, value, data])!.callContractMethod() + let result = try await contract.createReadOperation("canTransfer", parameters: [originalOwner, to, partition, value, data])!.call() guard let res = result["0"] as? ([UInt8], Data, Data) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -550,14 +550,14 @@ public class ERC1400: IERC1400, ERC20BaseProperties { extension ERC1400: IERC777 { public func canImplementInterfaceForAddress(interfaceHash: Data, addr: EthereumAddress) async throws -> Data { - let result = try await contract.createReadOperation("canImplementInterfaceForAddress", parameters: [interfaceHash, addr])!.callContractMethod() + let result = try await contract.createReadOperation("canImplementInterfaceForAddress", parameters: [interfaceHash, addr])!.call() guard let res = result["0"] as? Data else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getInterfaceImplementer(addr: EthereumAddress, interfaceHash: Data) async throws -> EthereumAddress { - let result = try await contract.createReadOperation("getInterfaceImplementer", parameters: [addr, interfaceHash])!.callContractMethod() + let result = try await contract.createReadOperation("getInterfaceImplementer", parameters: [addr, interfaceHash])!.call() guard let res = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -576,7 +576,7 @@ extension ERC1400: IERC777 { } public func interfaceHash(interfaceName: String) async throws -> Data { - let result = try await contract.createReadOperation("interfaceHash", parameters: [interfaceName])!.callContractMethod() + let result = try await contract.createReadOperation("interfaceHash", parameters: [interfaceName])!.call() guard let res = result["0"] as? Data else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -589,21 +589,21 @@ extension ERC1400: IERC777 { } public func supportsInterface(interfaceID: String) async throws -> Bool { - let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.callContractMethod() + let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getGranularity() async throws -> BigUInt { - let result = try await contract.createReadOperation("granularity")!.callContractMethod() + let result = try await contract.createReadOperation("granularity")!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getDefaultOperators() async throws -> [EthereumAddress] { - let result = try await contract.createReadOperation("defaultOperators")!.callContractMethod() + let result = try await contract.createReadOperation("defaultOperators")!.call() guard let res = result["0"] as? [EthereumAddress] else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -624,7 +624,7 @@ extension ERC1400: IERC777 { } public func isOperatorFor(operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isOperatorFor", parameters: [user, tokenHolder])!.callContractMethod() + let result = try await contract.createReadOperation("isOperatorFor", parameters: [user, tokenHolder])!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -634,7 +634,7 @@ extension ERC1400: IERC777 { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -653,7 +653,7 @@ extension ERC1400: IERC777 { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -672,7 +672,7 @@ extension ERC1400: IERC777 { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -691,7 +691,7 @@ extension ERC1400: IERC777 { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} diff --git a/Sources/web3swift/Tokens/ERC1410/Web3+ERC1410.swift b/Sources/web3swift/Tokens/ERC1410/Web3+ERC1410.swift index ad4ae54b0..0d7dc44e4 100644 --- a/Sources/web3swift/Tokens/ERC1410/Web3+ERC1410.swift +++ b/Sources/web3swift/Tokens/ERC1410/Web3+ERC1410.swift @@ -64,14 +64,14 @@ public class ERC1410: IERC1410, ERC20BaseProperties { } public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -81,7 +81,7 @@ public class ERC1410: IERC1410, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -100,7 +100,7 @@ public class ERC1410: IERC1410, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -119,7 +119,7 @@ public class ERC1410: IERC1410, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -135,7 +135,7 @@ public class ERC1410: IERC1410, ERC20BaseProperties { } public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -145,7 +145,7 @@ public class ERC1410: IERC1410, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -162,14 +162,14 @@ public class ERC1410: IERC1410, ERC20BaseProperties { // ERC1410 methods public func balanceOfByPartition(partition: Data, tokenHolder: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOfByPartition", parameters: [partition, tokenHolder])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOfByPartition", parameters: [partition, tokenHolder])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func partitionsOf(tokenHolder: EthereumAddress) async throws -> [Data] { - let result = try await contract.createReadOperation("partitionsOf", parameters: [tokenHolder])!.callContractMethod() + let result = try await contract.createReadOperation("partitionsOf", parameters: [tokenHolder])!.call() guard let res = result["0"] as? [Data] else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -179,7 +179,7 @@ public class ERC1410: IERC1410, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -198,7 +198,7 @@ public class ERC1410: IERC1410, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -215,7 +215,7 @@ public class ERC1410: IERC1410, ERC20BaseProperties { public func canTransferByPartition(originalOwner: EthereumAddress, to: EthereumAddress, partition: Data, amount: String, data: [UInt8]) async throws -> ([UInt8], Data, Data) { // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -226,21 +226,21 @@ public class ERC1410: IERC1410, ERC20BaseProperties { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let result = try await contract.createReadOperation("canTransfer", parameters: [originalOwner, to, partition, value, data])!.callContractMethod() + let result = try await contract.createReadOperation("canTransfer", parameters: [originalOwner, to, partition, value, data])!.call() guard let res = result["0"] as? ([UInt8], Data, Data) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func isOperator(operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isOperator", parameters: [user, tokenHolder])!.callContractMethod() + let result = try await contract.createReadOperation("isOperator", parameters: [user, tokenHolder])!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func isOperatorForPartition(partition: Data, operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isOperatorForPartition", parameters: [partition, user, tokenHolder])!.callContractMethod() + let result = try await contract.createReadOperation("isOperatorForPartition", parameters: [partition, user, tokenHolder])!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -274,7 +274,7 @@ public class ERC1410: IERC1410, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -293,7 +293,7 @@ public class ERC1410: IERC1410, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -312,7 +312,7 @@ public class ERC1410: IERC1410, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -330,14 +330,14 @@ public class ERC1410: IERC1410, ERC20BaseProperties { extension ERC1410: IERC777 { public func canImplementInterfaceForAddress(interfaceHash: Data, addr: EthereumAddress) async throws -> Data { - let result = try await contract.createReadOperation("canImplementInterfaceForAddress", parameters: [interfaceHash, addr])!.callContractMethod() + let result = try await contract.createReadOperation("canImplementInterfaceForAddress", parameters: [interfaceHash, addr])!.call() guard let res = result["0"] as? Data else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getInterfaceImplementer(addr: EthereumAddress, interfaceHash: Data) async throws -> EthereumAddress { - let result = try await contract.createReadOperation("getInterfaceImplementer", parameters: [addr, interfaceHash])!.callContractMethod() + let result = try await contract.createReadOperation("getInterfaceImplementer", parameters: [addr, interfaceHash])!.call() guard let res = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -356,7 +356,7 @@ extension ERC1410: IERC777 { } public func interfaceHash(interfaceName: String) async throws -> Data { - let result = try await contract.createReadOperation("interfaceHash", parameters: [interfaceName])!.callContractMethod() + let result = try await contract.createReadOperation("interfaceHash", parameters: [interfaceName])!.call() guard let res = result["0"] as? Data else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -370,7 +370,7 @@ extension ERC1410: IERC777 { public func supportsInterface(interfaceID: String) async throws -> Bool { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.callContractMethod() + let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -391,7 +391,7 @@ extension ERC1410: IERC777 { } public func isOperatorFor(operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isOperatorFor", parameters: [user, tokenHolder])!.callContractMethod() + let result = try await contract.createReadOperation("isOperatorFor", parameters: [user, tokenHolder])!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -401,7 +401,7 @@ extension ERC1410: IERC777 { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -420,7 +420,7 @@ extension ERC1410: IERC777 { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -439,7 +439,7 @@ extension ERC1410: IERC777 { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -458,7 +458,7 @@ extension ERC1410: IERC777 { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -474,14 +474,14 @@ extension ERC1410: IERC777 { } public func getGranularity() async throws -> BigUInt { - let result = try await contract.createReadOperation("granularity")!.callContractMethod() + let result = try await contract.createReadOperation("granularity")!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getDefaultOperators() async throws -> [EthereumAddress] { - let result = try await contract.createReadOperation("defaultOperators")!.callContractMethod() + let result = try await contract.createReadOperation("defaultOperators")!.call() guard let res = result["0"] as? [EthereumAddress] else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res diff --git a/Sources/web3swift/Tokens/ERC1594/Web3+ERC1594.swift b/Sources/web3swift/Tokens/ERC1594/Web3+ERC1594.swift index 07dba9fc7..9e68a63d6 100644 --- a/Sources/web3swift/Tokens/ERC1594/Web3+ERC1594.swift +++ b/Sources/web3swift/Tokens/ERC1594/Web3+ERC1594.swift @@ -54,14 +54,14 @@ public class ERC1594: IERC1594, ERC20BaseProperties { } public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -70,7 +70,7 @@ public class ERC1594: IERC1594, ERC20BaseProperties { public func transfer(from: EthereumAddress, to: EthereumAddress, amount: String) async throws -> WriteOperation { updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -89,7 +89,7 @@ public class ERC1594: IERC1594, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -108,7 +108,7 @@ public class ERC1594: IERC1594, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -124,7 +124,7 @@ public class ERC1594: IERC1594, ERC20BaseProperties { } public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -134,7 +134,7 @@ public class ERC1594: IERC1594, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -154,7 +154,7 @@ public class ERC1594: IERC1594, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -173,7 +173,7 @@ public class ERC1594: IERC1594, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -189,7 +189,7 @@ public class ERC1594: IERC1594, ERC20BaseProperties { } public func isIssuable() async throws -> Bool { - let result = try await contract.createReadOperation("isIssuable")!.callContractMethod() + let result = try await contract.createReadOperation("isIssuable")!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -199,7 +199,7 @@ public class ERC1594: IERC1594, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -218,7 +218,7 @@ public class ERC1594: IERC1594, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -237,7 +237,7 @@ public class ERC1594: IERC1594, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -254,7 +254,7 @@ public class ERC1594: IERC1594, ERC20BaseProperties { public func canTransfer(to: EthereumAddress, amount: String, data: [UInt8]) async throws -> ([UInt8], Data) { // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -265,7 +265,7 @@ public class ERC1594: IERC1594, ERC20BaseProperties { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let result = try await contract.createReadOperation("canTransfer", parameters: [to, value, data])!.callContractMethod() + let result = try await contract.createReadOperation("canTransfer", parameters: [to, value, data])!.call() guard let res = result["0"] as? ([UInt8], Data) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -273,7 +273,7 @@ public class ERC1594: IERC1594, ERC20BaseProperties { public func canTransferFrom(originalOwner: EthereumAddress, to: EthereumAddress, amount: String, data: [UInt8]) async throws -> ([UInt8], Data) { // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -284,7 +284,7 @@ public class ERC1594: IERC1594, ERC20BaseProperties { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let result = try await contract.createReadOperation("canTransfer", parameters: [originalOwner, to, value, data])!.callContractMethod() + let result = try await contract.createReadOperation("canTransfer", parameters: [originalOwner, to, value, data])!.call() guard let res = result["0"] as? ([UInt8], Data) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res diff --git a/Sources/web3swift/Tokens/ERC1633/Web3+ERC1633.swift b/Sources/web3swift/Tokens/ERC1633/Web3+ERC1633.swift index dfc2ed271..3030df3d0 100644 --- a/Sources/web3swift/Tokens/ERC1633/Web3+ERC1633.swift +++ b/Sources/web3swift/Tokens/ERC1633/Web3+ERC1633.swift @@ -41,14 +41,14 @@ public class ERC1633: IERC1633, ERC20BaseProperties { } public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -58,7 +58,7 @@ public class ERC1633: IERC1633, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -77,7 +77,7 @@ public class ERC1633: IERC1633, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -96,7 +96,7 @@ public class ERC1633: IERC1633, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -112,7 +112,7 @@ public class ERC1633: IERC1633, ERC20BaseProperties { } public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -122,7 +122,7 @@ public class ERC1633: IERC1633, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -138,21 +138,21 @@ public class ERC1633: IERC1633, ERC20BaseProperties { } func parentToken() async throws -> EthereumAddress { - let result = try await contract.createReadOperation("parentToken")!.callContractMethod() + let result = try await contract.createReadOperation("parentToken")!.call() guard let res = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } func parentTokenId() async throws -> BigUInt { - let result = try await contract.createReadOperation("parentTokenId")!.callContractMethod() + let result = try await contract.createReadOperation("parentTokenId")!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func supportsInterface(interfaceID: String) async throws -> Bool { - let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.callContractMethod() + let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res diff --git a/Sources/web3swift/Tokens/ERC1643/Web3+ERC1643.swift b/Sources/web3swift/Tokens/ERC1643/Web3+ERC1643.swift index c70ae346d..5d9ef57cb 100644 --- a/Sources/web3swift/Tokens/ERC1643/Web3+ERC1643.swift +++ b/Sources/web3swift/Tokens/ERC1643/Web3+ERC1643.swift @@ -44,14 +44,14 @@ public class ERC1643: IERC1643, ERC20BaseProperties { } public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -61,7 +61,7 @@ public class ERC1643: IERC1643, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -80,7 +80,7 @@ public class ERC1643: IERC1643, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -99,7 +99,7 @@ public class ERC1643: IERC1643, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -115,7 +115,7 @@ public class ERC1643: IERC1643, ERC20BaseProperties { } public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -125,7 +125,7 @@ public class ERC1643: IERC1643, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -142,7 +142,7 @@ public class ERC1643: IERC1643, ERC20BaseProperties { // ERC1643 methods public func getDocument(name: Data) async throws -> (String, Data) { - let result = try await contract.createReadOperation("getDocument", parameters: [name])!.callContractMethod() + let result = try await contract.createReadOperation("getDocument", parameters: [name])!.call() guard let res = result["0"] as? (String, Data) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -161,7 +161,7 @@ public class ERC1643: IERC1643, ERC20BaseProperties { } public func getAllDocuments() async throws -> [Data] { - let result = try await contract.createReadOperation("getAllDocuments")!.callContractMethod() + let result = try await contract.createReadOperation("getAllDocuments")!.call() guard let res = result["0"] as? [Data] else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res diff --git a/Sources/web3swift/Tokens/ERC1644/Web3+ERC1644.swift b/Sources/web3swift/Tokens/ERC1644/Web3+ERC1644.swift index 31e5795d8..814c02ad4 100644 --- a/Sources/web3swift/Tokens/ERC1644/Web3+ERC1644.swift +++ b/Sources/web3swift/Tokens/ERC1644/Web3+ERC1644.swift @@ -43,14 +43,14 @@ public class ERC1644: IERC1644, ERC20BaseProperties { } public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -60,7 +60,7 @@ public class ERC1644: IERC1644, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -79,7 +79,7 @@ public class ERC1644: IERC1644, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -98,7 +98,7 @@ public class ERC1644: IERC1644, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -114,7 +114,7 @@ public class ERC1644: IERC1644, ERC20BaseProperties { } public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -124,7 +124,7 @@ public class ERC1644: IERC1644, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -141,7 +141,7 @@ public class ERC1644: IERC1644, ERC20BaseProperties { // ERC1644 public func isControllable() async throws -> Bool { - let result = try await contract.createReadOperation("isControllable")!.callContractMethod() + let result = try await contract.createReadOperation("isControllable")!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -151,7 +151,7 @@ public class ERC1644: IERC1644, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -170,7 +170,7 @@ public class ERC1644: IERC1644, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} diff --git a/Sources/web3swift/Tokens/ERC20/ERC20BasePropertiesProvider.swift b/Sources/web3swift/Tokens/ERC20/ERC20BasePropertiesProvider.swift index e786e1517..0907cf32b 100644 --- a/Sources/web3swift/Tokens/ERC20/ERC20BasePropertiesProvider.swift +++ b/Sources/web3swift/Tokens/ERC20/ERC20BasePropertiesProvider.swift @@ -24,15 +24,15 @@ public final class ERC20BasePropertiesProvider { guard !hasReadProperties && contract.contract.address != nil else { return } name = try await contract .createReadOperation("name")? - .callContractMethod()["0"] as? String + .call()["0"] as? String symbol = try await contract .createReadOperation("symbol")? - .callContractMethod()["0"] as? String + .call()["0"] as? String let decimals = try await contract .createReadOperation("decimals")? - .callContractMethod()["0"] as? BigUInt + .call()["0"] as? BigUInt self.decimals = decimals != nil ? UInt8(decimals!) : nil hasReadProperties = true } diff --git a/Sources/web3swift/Tokens/ERC20/Web3+ERC20.swift b/Sources/web3swift/Tokens/ERC20/Web3+ERC20.swift index a3426f754..1f0e41d8b 100644 --- a/Sources/web3swift/Tokens/ERC20/Web3+ERC20.swift +++ b/Sources/web3swift/Tokens/ERC20/Web3+ERC20.swift @@ -44,7 +44,7 @@ public class ERC20: IERC20, ERC20BaseProperties { public func getBalance(account: EthereumAddress) async throws -> BigUInt { let result = try await contract .createReadOperation("balanceOf", parameters: [account])! - .callContractMethod() + .call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -52,7 +52,7 @@ public class ERC20: IERC20, ERC20BaseProperties { public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { let result = try await contract .createReadOperation("allowance", parameters: [originalOwner, delegate])! - .callContractMethod() + .call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -65,7 +65,7 @@ public class ERC20: IERC20, ERC20BaseProperties { // get the decimals manually let callResult = try await contract .createReadOperation("decimals")! - .callContractMethod() + .call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -89,7 +89,7 @@ public class ERC20: IERC20, ERC20BaseProperties { // get the decimals manually let callResult = try await contract .createReadOperation("decimals")! - .callContractMethod() + .call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -113,7 +113,7 @@ public class ERC20: IERC20, ERC20BaseProperties { // get the decimals manually let callResult = try await contract .createReadOperation("decimals")! - .callContractMethod() + .call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -137,7 +137,7 @@ public class ERC20: IERC20, ERC20BaseProperties { // get the decimals manually let callResult = try await contract .createReadOperation("decimals")! - .callContractMethod() + .call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -156,7 +156,7 @@ public class ERC20: IERC20, ERC20BaseProperties { public func totalSupply() async throws -> BigUInt { let result = try await contract .createReadOperation("totalSupply")! - .callContractMethod() + .call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } diff --git a/Sources/web3swift/Tokens/ERC721/Web3+ERC721.swift b/Sources/web3swift/Tokens/ERC721/Web3+ERC721.swift index db72d3784..4db0d0dc4 100644 --- a/Sources/web3swift/Tokens/ERC721/Web3+ERC721.swift +++ b/Sources/web3swift/Tokens/ERC721/Web3+ERC721.swift @@ -92,7 +92,7 @@ public class ERC721: IERC721 { } guard contract.contract.address != nil else { return } - async let tokenIdPromise = contract.createReadOperation("tokenId")?.callContractMethod() + async let tokenIdPromise = contract.createReadOperation("tokenId")?.call() guard let tokenIdResult = try await tokenIdPromise else { return } guard let tokenId = tokenIdResult["0"] as? BigUInt else { return } @@ -103,19 +103,19 @@ public class ERC721: IERC721 { } public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getOwner(tokenId: BigUInt) async throws -> EthereumAddress { - let result = try await contract.createReadOperation("ownerOf", parameters: [tokenId])!.callContractMethod() + let result = try await contract.createReadOperation("ownerOf", parameters: [tokenId])!.call() guard let res = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getApproved(tokenId: BigUInt) async throws -> EthereumAddress { - let result = try await contract.createReadOperation("getApproved", parameters: [tokenId])!.callContractMethod() + let result = try await contract.createReadOperation("getApproved", parameters: [tokenId])!.call() guard let res = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -157,13 +157,13 @@ public class ERC721: IERC721 { } public func isApprovedForAll(owner: EthereumAddress, operator user: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isApprovedForAll", parameters: [owner, user])!.callContractMethod() + let result = try await contract.createReadOperation("isApprovedForAll", parameters: [owner, user])!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func supportsInterface(interfaceID: String) async throws -> Bool { - let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.callContractMethod() + let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -187,19 +187,19 @@ extension ERC721 { extension ERC721: IERC721Enumerable { public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func tokenByIndex(index: BigUInt) async throws -> BigUInt { - let result = try await contract.createReadOperation("tokenByIndex", parameters: [index])!.callContractMethod() + let result = try await contract.createReadOperation("tokenByIndex", parameters: [index])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func tokenOfOwnerByIndex(owner: EthereumAddress, index: BigUInt) async throws -> BigUInt { - let result = try await contract.createReadOperation("tokenOfOwnerByIndex", parameters: [owner, index])!.callContractMethod() + let result = try await contract.createReadOperation("tokenOfOwnerByIndex", parameters: [owner, index])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -212,19 +212,19 @@ extension ERC721: IERC721Enumerable { extension ERC721: IERC721Metadata { public func name() async throws -> String { - let result = try await contract.createReadOperation("name")!.callContractMethod() + let result = try await contract.createReadOperation("name")!.call() guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func symbol() async throws -> String { - let result = try await contract.createReadOperation("symbol")!.callContractMethod() + let result = try await contract.createReadOperation("symbol")!.call() guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func tokenURI(tokenId: BigUInt) async throws -> String { - let result = try await contract.createReadOperation("tokenURI", parameters: [tokenId])!.callContractMethod() + let result = try await contract.createReadOperation("tokenURI", parameters: [tokenId])!.call() guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } diff --git a/Sources/web3swift/Tokens/ERC721x/Web3+ERC721x.swift b/Sources/web3swift/Tokens/ERC721x/Web3+ERC721x.swift index 8407e446a..df26196f2 100644 --- a/Sources/web3swift/Tokens/ERC721x/Web3+ERC721x.swift +++ b/Sources/web3swift/Tokens/ERC721x/Web3+ERC721x.swift @@ -78,7 +78,7 @@ public class ERC721x: IERC721x { guard contract.contract.address != nil else { return } transaction.callOnBlock = .latest - guard let tokenIdPromise = try await contract.createReadOperation("tokenId")?.callContractMethod() else { return } + guard let tokenIdPromise = try await contract.createReadOperation("tokenId")?.call() else { return } guard let tokenId = tokenIdPromise["0"] as? BigUInt else { return } self._tokenId = tokenId @@ -88,7 +88,7 @@ public class ERC721x: IERC721x { public func getBalance(account: EthereumAddress) async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -96,7 +96,7 @@ public class ERC721x: IERC721x { public func getOwner(tokenId: BigUInt) async throws -> EthereumAddress { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("ownerOf", parameters: [tokenId])!.callContractMethod() + let result = try await contract.createReadOperation("ownerOf", parameters: [tokenId])!.call() guard let res = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -104,7 +104,7 @@ public class ERC721x: IERC721x { public func getApproved(tokenId: BigUInt) async throws -> EthereumAddress { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("getApproved", parameters: [tokenId])!.callContractMethod() + let result = try await contract.createReadOperation("getApproved", parameters: [tokenId])!.call() guard let res = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -147,77 +147,77 @@ public class ERC721x: IERC721x { } public func isApprovedForAll(owner: EthereumAddress, operator user: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isApprovedForAll", parameters: [owner, user])!.callContractMethod() + let result = try await contract.createReadOperation("isApprovedForAll", parameters: [owner, user])!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func supportsInterface(interfaceID: String) async throws -> Bool { - let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.callContractMethod() + let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func tokenByIndex(index: BigUInt) async throws -> BigUInt { - let result = try await contract.createReadOperation("tokenByIndex", parameters: [index])!.callContractMethod() + let result = try await contract.createReadOperation("tokenByIndex", parameters: [index])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func tokenOfOwnerByIndex(owner: EthereumAddress, index: BigUInt) async throws -> BigUInt { - let result = try await contract.createReadOperation("tokenOfOwnerByIndex", parameters: [owner, index])!.callContractMethod() + let result = try await contract.createReadOperation("tokenOfOwnerByIndex", parameters: [owner, index])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func name() async throws -> String { - let result = try await contract.createReadOperation("name")!.callContractMethod() + let result = try await contract.createReadOperation("name")!.call() guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func symbol() async throws -> String { - let result = try await contract.createReadOperation("symbol")!.callContractMethod() + let result = try await contract.createReadOperation("symbol")!.call() guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func tokenURI(tokenId: BigUInt) async throws -> String { - let result = try await contract.createReadOperation("tokenURI", parameters: [tokenId])!.callContractMethod() + let result = try await contract.createReadOperation("tokenURI", parameters: [tokenId])!.call() guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } func implementsERC721X() async throws -> Bool { - let result = try await contract.createReadOperation("implementsERC721X")!.callContractMethod() + let result = try await contract.createReadOperation("implementsERC721X")!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } func getBalance(account: EthereumAddress, tokenId: BigUInt) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account, tokenId])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account, tokenId])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } func tokensOwned(account: EthereumAddress) async throws -> ([BigUInt], [BigUInt]) { - let result = try await contract.createReadOperation("tokensOwned", parameters: [account])!.callContractMethod() + let result = try await contract.createReadOperation("tokensOwned", parameters: [account])!.call() guard let res = result["0"] as? ([BigUInt], [BigUInt]) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res diff --git a/Sources/web3swift/Tokens/ERC777/Web3+ERC777.swift b/Sources/web3swift/Tokens/ERC777/Web3+ERC777.swift index c5a428c53..29a29a34a 100644 --- a/Sources/web3swift/Tokens/ERC777/Web3+ERC777.swift +++ b/Sources/web3swift/Tokens/ERC777/Web3+ERC777.swift @@ -57,28 +57,28 @@ public class ERC777: IERC777, ERC20BaseProperties { } public func getGranularity() async throws -> BigUInt { - let result = try await contract.createReadOperation("granularity")!.callContractMethod() + let result = try await contract.createReadOperation("granularity")!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getDefaultOperators() async throws -> [EthereumAddress] { - let result = try await contract.createReadOperation("defaultOperators")!.callContractMethod() + let result = try await contract.createReadOperation("defaultOperators")!.call() guard let res = result["0"] as? [EthereumAddress] else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -88,7 +88,7 @@ public class ERC777: IERC777, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -106,7 +106,7 @@ public class ERC777: IERC777, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -125,7 +125,7 @@ public class ERC777: IERC777, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -140,7 +140,7 @@ public class ERC777: IERC777, ERC20BaseProperties { } public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -162,7 +162,7 @@ public class ERC777: IERC777, ERC20BaseProperties { } public func isOperatorFor(operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isOperatorFor", parameters: [user, tokenHolder])!.callContractMethod() + let result = try await contract.createReadOperation("isOperatorFor", parameters: [user, tokenHolder])!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -172,7 +172,7 @@ public class ERC777: IERC777, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -190,7 +190,7 @@ public class ERC777: IERC777, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -208,7 +208,7 @@ public class ERC777: IERC777, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -226,7 +226,7 @@ public class ERC777: IERC777, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -241,14 +241,14 @@ public class ERC777: IERC777, ERC20BaseProperties { } public func canImplementInterfaceForAddress(interfaceHash: Data, addr: EthereumAddress) async throws -> Data { - let result = try await contract.createReadOperation("canImplementInterfaceForAddress", parameters: [interfaceHash, addr])!.callContractMethod() + let result = try await contract.createReadOperation("canImplementInterfaceForAddress", parameters: [interfaceHash, addr])!.call() guard let res = result["0"] as? Data else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getInterfaceImplementer(addr: EthereumAddress, interfaceHash: Data) async throws -> EthereumAddress { - let result = try await contract.createReadOperation("getInterfaceImplementer", parameters: [addr, interfaceHash])!.callContractMethod() + let result = try await contract.createReadOperation("getInterfaceImplementer", parameters: [addr, interfaceHash])!.call() guard let res = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -267,7 +267,7 @@ public class ERC777: IERC777, ERC20BaseProperties { } public func interfaceHash(interfaceName: String) async throws -> Data { - let result = try await contract.createReadOperation("interfaceHash", parameters: [interfaceName])!.callContractMethod() + let result = try await contract.createReadOperation("interfaceHash", parameters: [interfaceName])!.call() guard let res = result["0"] as? Data else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -284,7 +284,7 @@ public class ERC777: IERC777, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -299,7 +299,7 @@ public class ERC777: IERC777, ERC20BaseProperties { } public func supportsInterface(interfaceID: String) async throws -> Bool { - let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.callContractMethod() + let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.call() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res diff --git a/Sources/web3swift/Tokens/ERC888/Web3+ERC888.swift b/Sources/web3swift/Tokens/ERC888/Web3+ERC888.swift index 1f462b08e..c02abbd89 100644 --- a/Sources/web3swift/Tokens/ERC888/Web3+ERC888.swift +++ b/Sources/web3swift/Tokens/ERC888/Web3+ERC888.swift @@ -39,7 +39,7 @@ public class ERC888: IERC888, ERC20BaseProperties { } public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -51,7 +51,7 @@ public class ERC888: IERC888, ERC20BaseProperties { transaction.callOnBlock = .latest contract.transaction = transaction // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} diff --git a/Sources/web3swift/Tokens/ST20/Web3+ST20.swift b/Sources/web3swift/Tokens/ST20/Web3+ST20.swift index b3688bd9e..526c0e52b 100644 --- a/Sources/web3swift/Tokens/ST20/Web3+ST20.swift +++ b/Sources/web3swift/Tokens/ST20/Web3+ST20.swift @@ -50,7 +50,7 @@ public class ST20: IST20, ERC20BaseProperties { } func tokenDetails() async throws -> [UInt32] { - let result = try await contract.createReadOperation("tokenDetails")!.callContractMethod() + let result = try await contract.createReadOperation("tokenDetails")!.call() guard let res = result["0"] as? [UInt32] else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -60,7 +60,7 @@ public class ST20: IST20, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -79,7 +79,7 @@ public class ST20: IST20, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -98,7 +98,7 @@ public class ST20: IST20, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -114,14 +114,14 @@ public class ST20: IST20, ERC20BaseProperties { } public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -131,7 +131,7 @@ public class ST20: IST20, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -150,7 +150,7 @@ public class ST20: IST20, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -169,7 +169,7 @@ public class ST20: IST20, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -188,7 +188,7 @@ public class ST20: IST20, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -204,7 +204,7 @@ public class ST20: IST20, ERC20BaseProperties { } public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.call() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res diff --git a/Sources/web3swift/Tokens/ST20/Web3+SecurityToken.swift b/Sources/web3swift/Tokens/ST20/Web3+SecurityToken.swift index 7869477f9..452232132 100644 --- a/Sources/web3swift/Tokens/ST20/Web3+SecurityToken.swift +++ b/Sources/web3swift/Tokens/ST20/Web3+SecurityToken.swift @@ -91,7 +91,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { func tokenDetails() async throws -> [UInt32] { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("tokenDetails")!.callContractMethod() + let result = try await contract.createReadOperation("tokenDetails")!.call() guard let res = result["0"] as? [UInt32] else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } @@ -102,7 +102,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { transaction.callOnBlock = .latest contract.transaction = transaction // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals") } @@ -121,7 +121,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { transaction.callOnBlock = .latest contract.transaction = transaction // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals") } @@ -140,7 +140,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { transaction.callOnBlock = .latest contract.transaction = transaction // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals") } @@ -155,14 +155,14 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { public func getBalance(account: EthereumAddress) async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.call() guard let res = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.call() guard let res = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } @@ -173,7 +173,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { transaction.callOnBlock = .latest contract.transaction = transaction // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals") } @@ -192,7 +192,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { transaction.callOnBlock = .latest contract.transaction = transaction // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals") } @@ -211,7 +211,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { transaction.callOnBlock = .latest contract.transaction = transaction // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals") } @@ -230,7 +230,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { transaction.callOnBlock = .latest contract.transaction = transaction // get the decimals manually - let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.call() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals") } @@ -245,7 +245,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { public func totalSupply() async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.call() guard let res = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } @@ -272,42 +272,42 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { public func currentCheckpointId() async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("currentCheckpointId")!.callContractMethod() + let result = try await contract.createReadOperation("currentCheckpointId")!.call() guard let res = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } public func getGranularity() async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("granularity")!.callContractMethod() + let result = try await contract.createReadOperation("granularity")!.call() guard let res = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } public func investorCount() async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("investorCount")!.callContractMethod() + let result = try await contract.createReadOperation("investorCount")!.call() guard let res = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } public func investors(index: UInt) async throws -> [EthereumAddress] { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("investors", parameters: [index])!.callContractMethod() + let result = try await contract.createReadOperation("investors", parameters: [index])!.call() guard let res = result["0"] as? [EthereumAddress] else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } public func checkPermission(delegate: EthereumAddress, module: EthereumAddress, perm: [UInt32]) async throws -> Bool { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("checkPermission", parameters: [delegate, module, perm])!.callContractMethod() + let result = try await contract.createReadOperation("checkPermission", parameters: [delegate, module, perm])!.call() guard let res = result["0"] as? Bool else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } public func getModule(moduleType: UInt8, moduleIndex: UInt8) async throws -> ([UInt32], EthereumAddress) { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("getModule", parameters: [moduleType, moduleIndex])!.callContractMethod() + let result = try await contract.createReadOperation("getModule", parameters: [moduleType, moduleIndex])!.call() guard let moduleList = result["0"] as? [UInt32] else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } guard let moduleAddress = result["1"] as? EthereumAddress else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return (moduleList, moduleAddress) @@ -315,7 +315,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { public func getModuleByName(moduleType: UInt8, name: [UInt32]) async throws -> ([UInt32], EthereumAddress) { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("getModuleByName", parameters: [moduleType, name])!.callContractMethod() + let result = try await contract.createReadOperation("getModuleByName", parameters: [moduleType, name])!.call() guard let moduleList = result["0"] as? [UInt32] else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } guard let moduleAddress = result["1"] as? EthereumAddress else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return (moduleList, moduleAddress) @@ -323,14 +323,14 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { public func totalSupplyAt(checkpointId: BigUInt) async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("totalSupplyAt", parameters: [checkpointId])!.callContractMethod() + let result = try await contract.createReadOperation("totalSupplyAt", parameters: [checkpointId])!.call() guard let res = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } public func balanceOfAt(investor: EthereumAddress, checkpointId: BigUInt) async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("balanceOfAt", parameters: [investor, checkpointId])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOfAt", parameters: [investor, checkpointId])!.call() guard let res = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } @@ -347,7 +347,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { public func getInvestorsLength() async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("getInvestorsLength")!.callContractMethod() + let result = try await contract.createReadOperation("getInvestorsLength")!.call() guard let res = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } diff --git a/Sources/web3swift/Utils/ENS/ENS.swift b/Sources/web3swift/Utils/ENS/ENS.swift index 7c4f8d00e..b561e8af9 100755 --- a/Sources/web3swift/Utils/ENS/ENS.swift +++ b/Sources/web3swift/Utils/ENS/ENS.swift @@ -96,7 +96,7 @@ public class ENS { } // FIXME: Rewrite this to CodableTransaction - public func setAddress(forNode node: String, address: EthereumAddress, options: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { + public func setAddress(forNode node: String, address: EthereumAddress, transaction: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { guard let resolver = try? await self.registry.getResolver(forDomain: node) else { throw Web3Error.processingError(desc: "Failed to get resolver for domain") } @@ -106,9 +106,9 @@ public class ENS { guard isAddrSupports else { throw Web3Error.processingError(desc: "Address isn't supported") } - var options = options ?? defaultTransaction - options.to = resolver.resolverContractAddress - guard let result = try? await resolver.setAddress(forNode: node, address: address, options: options, password: password) else { + var transaction = transaction ?? defaultTransaction + transaction.to = resolver.resolverContractAddress + guard let result = try? await resolver.setAddress(forNode: node, address: address, transaction: transaction, password: password) else { throw Web3Error.processingError(desc: "Can't get result") } return result @@ -131,7 +131,7 @@ public class ENS { } // FIXME: Rewrite this to CodableTransaction - public func setName(forNode node: String, name: String, options: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { + public func setName(forNode node: String, name: String, transaction: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { guard let resolver = try? await self.registry.getResolver(forDomain: node) else { throw Web3Error.processingError(desc: "Failed to get resolver for domain") } @@ -141,9 +141,9 @@ public class ENS { guard isNameSupports else { throw Web3Error.processingError(desc: "Name isn't supported") } - var options = options ?? defaultTransaction + var options = transaction ?? defaultTransaction options.to = resolver.resolverContractAddress - guard let result = try? await resolver.setCanonicalName(forNode: node, name: name, options: options, password: password) else { + guard let result = try? await resolver.setCanonicalName(forNode: node, name: name, transaction: options, password: password) else { throw Web3Error.processingError(desc: "Can't get result") } return result @@ -167,7 +167,7 @@ public class ENS { } // FIXME: Rewrite this to CodableTransaction - public func setContent(forNode node: String, hash: String, options: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { + public func setContent(forNode node: String, hash: String, transaction: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { guard let resolver = try? await self.registry.getResolver(forDomain: node) else { throw Web3Error.processingError(desc: "Failed to get resolver for domain") } @@ -177,9 +177,9 @@ public class ENS { guard isContentSupports else { throw Web3Error.processingError(desc: "Content isn't supported") } - var options = options ?? defaultTransaction + var options = transaction ?? defaultTransaction options.to = resolver.resolverContractAddress - guard let result = try? await resolver.setContentHash(forNode: node, hash: hash, options: options, password: password) else { + guard let result = try? await resolver.setContentHash(forNode: node, hash: hash, transaction: options, password: password) else { throw Web3Error.processingError(desc: "Can't get result") } return result @@ -202,7 +202,7 @@ public class ENS { } // FIXME: Rewrite this to CodableTransaction - public func setABI(forNode node: String, contentType: ENS.Resolver.ContentType, data: Data, options: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { + public func setABI(forNode node: String, contentType: ENS.Resolver.ContentType, data: Data, transaction: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { guard let resolver = try? await self.registry.getResolver(forDomain: node) else { throw Web3Error.processingError(desc: "Failed to get resolver for domain") } @@ -212,9 +212,9 @@ public class ENS { guard isABISupports else { throw Web3Error.processingError(desc: "ABI isn't supported") } - var options = options ?? defaultTransaction + var options = transaction ?? defaultTransaction options.to = resolver.resolverContractAddress - guard let result = try? await resolver.setContractABI(forNode: node, contentType: contentType, data: data, options: options, password: password) else { + guard let result = try? await resolver.setContractABI(forNode: node, contentType: contentType, data: data, transaction: options, password: password) else { throw Web3Error.processingError(desc: "Can't get result") } return result @@ -237,7 +237,7 @@ public class ENS { } // FIXME: Rewrite this to CodableTransaction - public func setPublicKey(forNode node: String, publicKey: PublicKey, options: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { + public func setPublicKey(forNode node: String, publicKey: PublicKey, transaction: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { guard let resolver = try? await self.registry.getResolver(forDomain: node) else { throw Web3Error.processingError(desc: "Failed to get resolver for domain") } @@ -247,9 +247,9 @@ public class ENS { guard isPKSupports else { throw Web3Error.processingError(desc: "Public Key isn't supported") } - var options = options ?? defaultTransaction + var options = transaction ?? defaultTransaction options.to = resolver.resolverContractAddress - guard let result = try? await resolver.setPublicKey(forNode: node, publicKey: publicKey, options: options, password: password) else { + guard let result = try? await resolver.setPublicKey(forNode: node, publicKey: publicKey, transaction: options, password: password) else { throw Web3Error.processingError(desc: "Can't get result") } return result @@ -272,7 +272,7 @@ public class ENS { } // FIXME: Rewrite this to CodableTransaction - public func setText(forNode node: String, key: String, value: String, options: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { + public func setText(forNode node: String, key: String, value: String, transaction: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { guard let resolver = try? await self.registry.getResolver(forDomain: node) else { throw Web3Error.processingError(desc: "Failed to get resolver for domain") } @@ -282,9 +282,9 @@ public class ENS { guard isTextSupports else { throw Web3Error.processingError(desc: "Text isn't supported") } - var options = options ?? defaultTransaction + var options = transaction ?? defaultTransaction options.to = resolver.resolverContractAddress - guard let result = try? await resolver.setTextData(forNode: node, key: key, value: value, options: options, password: password) else { + guard let result = try? await resolver.setTextData(forNode: node, key: key, value: value, transaction: options, password: password) else { throw Web3Error.processingError(desc: "Can't get result") } return result diff --git a/Sources/web3swift/Utils/ENS/ENSBaseRegistrar.swift b/Sources/web3swift/Utils/ENS/ENSBaseRegistrar.swift index 5b7c2d5f4..6c2a7614c 100644 --- a/Sources/web3swift/Utils/ENS/ENSBaseRegistrar.swift +++ b/Sources/web3swift/Utils/ENS/ENSBaseRegistrar.swift @@ -59,7 +59,7 @@ public extension ENS { public func getNameExpirity(name: BigUInt) async throws -> BigUInt { guard let transaction = self.contract.createReadOperation("nameExpires", parameters: [name]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else { throw Web3Error.processingError(desc: "Can't call transaction") } + guard let result = try? await transaction.call() else { throw Web3Error.processingError(desc: "Can't call transaction") } guard let expirity = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Can't get answer") } return expirity } @@ -68,7 +68,7 @@ public extension ENS { public func isNameAvailable(name: BigUInt) async throws -> Bool { guard let transaction = self.contract.createReadOperation("available", parameters: [name]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else { throw Web3Error.processingError(desc: "Can't call transaction") } + guard let result = try? await transaction.call() else { throw Web3Error.processingError(desc: "Can't call transaction") } guard let available = result["0"] as? Bool else { throw Web3Error.processingError(desc: "Can't get answer") } return available } diff --git a/Sources/web3swift/Utils/ENS/ENSRegistry.swift b/Sources/web3swift/Utils/ENS/ENSRegistry.swift index 1e91001b0..e3ae95a8a 100644 --- a/Sources/web3swift/Utils/ENS/ENSRegistry.swift +++ b/Sources/web3swift/Utils/ENS/ENSRegistry.swift @@ -50,7 +50,7 @@ public extension ENS { guard let transaction = self.registryContract.createReadOperation("owner", parameters: [nameHash]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} + guard let result = try? await transaction.call() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let address = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "No address in result")} return address } @@ -60,7 +60,7 @@ public extension ENS { guard let transaction = self.registryContract.createReadOperation("resolver", parameters: [nameHash]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} + guard let result = try? await transaction.call() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let resolverAddress = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "No address in result")} return Resolver(web3: self.web3, resolverContractAddress: resolverAddress) } @@ -70,16 +70,16 @@ public extension ENS { guard let transaction = self.registryContract.createReadOperation("ttl", parameters: [nameHash]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} + guard let result = try? await transaction.call() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let ans = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "No answer in result")} return ans } // FIXME: Rewrite this to CodableTransaction - public func setOwner(node: String, owner: EthereumAddress, options: CodableTransaction?, password: String) async throws -> TransactionSendingResult { - var options = options ?? defaultTransaction + public func setOwner(node: String, owner: EthereumAddress, transaction: CodableTransaction?, password: String) async throws -> TransactionSendingResult { + var transaction = transaction ?? defaultTransaction if let contractAddress = self.registryContractAddress { - options.to = contractAddress + transaction.to = contractAddress } guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} @@ -90,10 +90,10 @@ public extension ENS { } // FIXME: Rewrite this to CodableTransaction - public func setSubnodeOwner(node: String, label: String, owner: EthereumAddress, options: CodableTransaction?, password: String) async throws -> TransactionSendingResult { - var options = options ?? defaultTransaction + public func setSubnodeOwner(node: String, label: String, owner: EthereumAddress, transaction: CodableTransaction?, password: String) async throws -> TransactionSendingResult { + var transaction = transaction ?? defaultTransaction if let contractAddress = self.registryContractAddress { - options.to = contractAddress + transaction.to = contractAddress } guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} guard let labelHash = NameHash.nameHash(label) else {throw Web3Error.processingError(desc: "Failed to get label hash")} @@ -105,10 +105,10 @@ public extension ENS { } // FIXME: Rewrite this to CodableTransaction - public func setResolver(node: String, resolver: EthereumAddress, options: CodableTransaction?, password: String) async throws -> TransactionSendingResult { - var options = options ?? defaultTransaction + public func setResolver(node: String, resolver: EthereumAddress, transaction: CodableTransaction?, password: String) async throws -> TransactionSendingResult { + var transaction = transaction ?? defaultTransaction if let contractAddress = self.registryContractAddress { - options.to = contractAddress + transaction.to = contractAddress } guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} @@ -119,10 +119,10 @@ public extension ENS { } // FIXME: Rewrite this to CodableTransaction - public func setTTL(node: String, ttl: BigUInt, options: CodableTransaction?, password: String) async throws -> TransactionSendingResult { - var options = options ?? defaultTransaction + public func setTTL(node: String, ttl: BigUInt, transaction: CodableTransaction?, password: String) async throws -> TransactionSendingResult { + var transaction = transaction ?? defaultTransaction if let contractAddress = self.registryContractAddress { - options.to = contractAddress + transaction.to = contractAddress } guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} diff --git a/Sources/web3swift/Utils/ENS/ENSResolver.swift b/Sources/web3swift/Utils/ENS/ENSResolver.swift index b7aedd589..d0fc62bc3 100755 --- a/Sources/web3swift/Utils/ENS/ENSResolver.swift +++ b/Sources/web3swift/Utils/ENS/ENSResolver.swift @@ -78,7 +78,7 @@ public extension ENS { guard let transaction = self.resolverContract.createReadOperation("supportsInterface", parameters: [interfaceID]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else { + guard let result = try? await transaction.call() else { throw Web3Error.processingError(desc: "Can't call transaction") } guard let supports = result["0"] as? Bool else { @@ -90,7 +90,7 @@ public extension ENS { public func interfaceImplementer(forNode node: String, interfaceID: String) async throws -> EthereumAddress { guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} guard let transaction = self.resolverContract.createReadOperation("interfaceImplementer", parameters: [nameHash, interfaceID]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} + guard let result = try? await transaction.call() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let address = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Can't get address")} return address } @@ -98,16 +98,16 @@ public extension ENS { public func getAddress(forNode node: String) async throws -> EthereumAddress { guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} guard let transaction = self.resolverContract.createReadOperation("addr", parameters: [nameHash]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} + guard let result = try? await transaction.call() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let address = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Can't get address")} return address } // FIXME: Rewrite this to CodableTransaction @available(*, message: "Available for only owner") - public func setAddress(forNode node: String, address: EthereumAddress, options: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { - var options = options ?? defaultTransaction - options.to = self.resolverContractAddress + public func setAddress(forNode node: String, address: EthereumAddress, transaction: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { + var transaction = transaction ?? defaultTransaction + transaction.to = self.resolverContractAddress guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} guard let transaction = self.resolverContract.createWriteOperation("setAddr", parameters: [nameHash, address]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.writeToChain(password: password) else {throw Web3Error.processingError(desc: "Can't send transaction")} @@ -117,16 +117,16 @@ public extension ENS { public func getCanonicalName(forNode node: String) async throws -> String { guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} guard let transaction = self.resolverContract.createReadOperation("name", parameters: [nameHash]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} + guard let result = try? await transaction.call() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let name = result["0"] as? String else {throw Web3Error.processingError(desc: "Can't get name")} return name } // FIXME: Rewrite this to CodableTransaction @available(*, message: "Available for only owner") - func setCanonicalName(forNode node: String, name: String, options: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { - var options = options ?? defaultTransaction - options.to = self.resolverContractAddress + func setCanonicalName(forNode node: String, name: String, transaction: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { + var transaction = transaction ?? defaultTransaction + transaction.to = self.resolverContractAddress guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} guard let transaction = self.resolverContract.createWriteOperation("setName", parameters: [nameHash, name]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.writeToChain(password: password) else {throw Web3Error.processingError(desc: "Can't send transaction")} @@ -136,16 +136,16 @@ public extension ENS { func getContentHash(forNode node: String) async throws -> Data { guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} guard let transaction = self.resolverContract.createReadOperation("contenthash", parameters: [nameHash]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} + guard let result = try? await transaction.call() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let content = result["0"] as? Data else {throw Web3Error.processingError(desc: "Can't get content")} return content } // FIXME: Rewrite this to CodableTransaction @available(*, message: "Available for only owner") - func setContentHash(forNode node: String, hash: String, options: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { - var options = options ?? defaultTransaction - options.to = self.resolverContractAddress + func setContentHash(forNode node: String, hash: String, transaction: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { + var transaction = transaction ?? defaultTransaction + transaction.to = self.resolverContractAddress guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} guard let transaction = self.resolverContract.createWriteOperation("setContenthash", parameters: [nameHash, hash]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.writeToChain(password: password) @@ -156,7 +156,7 @@ public extension ENS { public func getContractABI(forNode node: String, contentType: ENS.Resolver.ContentType) async throws -> (BigUInt, Data) { guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} guard let transaction = self.resolverContract.createReadOperation("ABI", parameters: [nameHash, contentType.rawValue]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} + guard let result = try? await transaction.call() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let encoding = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Can't get encoding")} guard let data = result["1"] as? Data else {throw Web3Error.processingError(desc: "Can't get data")} return (encoding, data) @@ -164,9 +164,9 @@ public extension ENS { // FIXME: Rewrite this to CodableTransaction @available(*, message: "Available for only owner") - func setContractABI(forNode node: String, contentType: ENS.Resolver.ContentType, data: Data, options: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { - var options = options ?? defaultTransaction - options.to = self.resolverContractAddress + func setContractABI(forNode node: String, contentType: ENS.Resolver.ContentType, data: Data, transaction: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { + var transaction = transaction ?? defaultTransaction + transaction.to = self.resolverContractAddress guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} guard let transaction = self.resolverContract.createWriteOperation("setABI", parameters: [nameHash, contentType.rawValue, data]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.writeToChain(password: password) else {throw Web3Error.processingError(desc: "Can't send transaction")} @@ -176,7 +176,7 @@ public extension ENS { public func getPublicKey(forNode node: String) async throws -> PublicKey { guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} guard let transaction = self.resolverContract.createReadOperation("pubkey", parameters: [nameHash]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} + guard let result = try? await transaction.call() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let x = result["x"] as? Data else {throw Web3Error.processingError(desc: "Can't get x")} guard let y = result["y"] as? Data else {throw Web3Error.processingError(desc: "Can't get y")} let pubkey = PublicKey(x: "0x" + x.toHexString(), y: "0x" + y.toHexString()) @@ -185,9 +185,9 @@ public extension ENS { // FIXME: Rewrite this to CodableTransaction @available(*, message: "Available for only owner") - public func setPublicKey(forNode node: String, publicKey: PublicKey, options: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { - var options = options ?? defaultTransaction - options.to = self.resolverContractAddress + public func setPublicKey(forNode node: String, publicKey: PublicKey, transaction: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { + var transaction = transaction ?? defaultTransaction + transaction.to = self.resolverContractAddress let pubkeyWithoutPrefix = publicKey.getComponentsWithoutPrefix() guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} guard let transaction = self.resolverContract.createWriteOperation("setPubkey", parameters: [nameHash, pubkeyWithoutPrefix.x, pubkeyWithoutPrefix.y]) else { throw Web3Error.transactionSerializationError } @@ -198,16 +198,16 @@ public extension ENS { public func getTextData(forNode node: String, key: String) async throws -> String { guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} guard let transaction = self.resolverContract.createReadOperation("text", parameters: [nameHash, key]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} + guard let result = try? await transaction.call() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let text = result["0"] as? String else {throw Web3Error.processingError(desc: "Can't get text")} return text } // FIXME: Rewrite this to CodableTransaction @available(*, message: "Available for only owner") - public func setTextData(forNode node: String, key: String, value: String, options: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { - var options = options ?? defaultTransaction - options.to = self.resolverContractAddress + public func setTextData(forNode node: String, key: String, value: String, transaction: CodableTransaction? = nil, password: String) async throws -> TransactionSendingResult { + var transaction = transaction ?? defaultTransaction + transaction.to = self.resolverContractAddress guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} guard let transaction = self.resolverContract.createWriteOperation("setText", parameters: [nameHash, key, value]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.writeToChain(password: password) else {throw Web3Error.processingError(desc: "Can't send transaction")} diff --git a/Sources/web3swift/Utils/ENS/ENSReverseRegistrar.swift b/Sources/web3swift/Utils/ENS/ENSReverseRegistrar.swift index f78e0d457..2d9add8c1 100644 --- a/Sources/web3swift/Utils/ENS/ENSReverseRegistrar.swift +++ b/Sources/web3swift/Utils/ENS/ENSReverseRegistrar.swift @@ -55,7 +55,7 @@ public extension ENS { public func getReverseRecordName(address: EthereumAddress) async throws -> Data { guard let transaction = self.contract.createReadOperation("node", parameters: [address]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else { throw Web3Error.processingError(desc: "Can't call transaction") } + guard let result = try? await transaction.call() else { throw Web3Error.processingError(desc: "Can't call transaction") } guard let name = result["0"] as? Data else { throw Web3Error.processingError(desc: "Can't get answer") } return name } @@ -63,7 +63,7 @@ public extension ENS { public func getDefaultResolver() async throws -> EthereumAddress { guard let transaction = self.contract.createReadOperation("defaultResolver") else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else { throw Web3Error.processingError(desc: "Can't call transaction") } + guard let result = try? await transaction.call() else { throw Web3Error.processingError(desc: "Can't call transaction") } guard let address = result["0"] as? EthereumAddress else { throw Web3Error.processingError(desc: "Can't get answer") } return address } diff --git a/Sources/web3swift/Utils/ENS/ETHRegistrarController.swift b/Sources/web3swift/Utils/ENS/ETHRegistrarController.swift index 4c7ef3471..7d41e20e1 100644 --- a/Sources/web3swift/Utils/ENS/ETHRegistrarController.swift +++ b/Sources/web3swift/Utils/ENS/ETHRegistrarController.swift @@ -33,28 +33,28 @@ public extension ENS { public func getRentPrice(name: String, duration: UInt) async throws -> BigUInt { guard let transaction = self.contract.createReadOperation("rentPrice", parameters: [name, duration]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else { throw Web3Error.processingError(desc: "Can't call transaction") } + guard let result = try? await transaction.call() else { throw Web3Error.processingError(desc: "Can't call transaction") } guard let price = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Can't get answer") } return price } public func checkNameValidity(name: String) async throws -> Bool { guard let transaction = self.contract.createReadOperation("valid", parameters: [name]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else { throw Web3Error.processingError(desc: "Can't call transaction") } + guard let result = try? await transaction.call() else { throw Web3Error.processingError(desc: "Can't call transaction") } guard let valid = result["0"] as? Bool else { throw Web3Error.processingError(desc: "Can't get answer") } return valid } public func isNameAvailable(name: String) async throws -> Bool { guard let transaction = self.contract.createReadOperation("available", parameters: [name]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else { throw Web3Error.processingError(desc: "Can't call transaction") } + guard let result = try? await transaction.call() else { throw Web3Error.processingError(desc: "Can't call transaction") } guard let available = result["0"] as? Bool else { throw Web3Error.processingError(desc: "Can't get answer") } return available } public func calculateCommitmentHash(name: String, owner: EthereumAddress, secret: String) async throws -> Data { guard let transaction = self.contract.createReadOperation("makeCommitment", parameters: [name, owner.address, secret]) else { throw Web3Error.transactionSerializationError } - guard let result = try? await transaction.callContractMethod() else { throw Web3Error.processingError(desc: "Can't call transaction") } + guard let result = try? await transaction.call() else { throw Web3Error.processingError(desc: "Can't call transaction") } guard let hash = result["0"] as? Data else { throw Web3Error.processingError(desc: "Can't get answer") } return hash } diff --git a/Sources/web3swift/Web3/Web3+Contract.swift b/Sources/web3swift/Web3/Web3+Contract.swift index 7bf192710..d5fc82da1 100755 --- a/Sources/web3swift/Web3/Web3+Contract.swift +++ b/Sources/web3swift/Web3/Web3+Contract.swift @@ -47,7 +47,7 @@ extension Web3 { // MARK: Writing Data flow // FIXME: Rewrite this to CodableTransaction - /// Deploys a constact instance using the previously provided ABI, some bytecode, constructor parameters and options. + /// Deploys a contract instance using the previously provided ABI, some bytecode, constructor parameters and options. /// If extraData is supplied it is appended to encoded bytecode and constructor parameters. /// /// Returns a "Transaction intermediate" object. @@ -112,5 +112,11 @@ extension Web3 { } return .init(transaction: transaction, web3: web3, contract: contract, method: method) } + + /// Combines `createReadOperation` & `callContractMethod` + @discardableResult + public func callStatic(_ method: String, parameters: [Any]) async throws -> [String: Any] { + try await contract.callStatic(method, parameters: parameters, provider: web3.provider) + } } } diff --git a/Sources/web3swift/Web3/Web3+HttpProvider.swift b/Sources/web3swift/Web3/Web3+HttpProvider.swift index a6411552d..1e75b242c 100755 --- a/Sources/web3swift/Web3/Web3+HttpProvider.swift +++ b/Sources/web3swift/Web3/Web3+HttpProvider.swift @@ -33,13 +33,21 @@ public class Web3HttpProvider: Web3Provider { if let net = net { network = net } else { - var urlRequest = URLRequest(url: url, cachePolicy: .reloadIgnoringCacheData) - urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") - urlRequest.setValue("application/json", forHTTPHeaderField: "Accept") - urlRequest.httpMethod = APIRequest.getNetwork.call - urlRequest.httpBody = APIRequest.getNetwork.encodedBody - let response: APIResponse = try await APIRequest.send(uRLRequest: urlRequest, with: session) - self.network = Networks.fromInt(response.result) + /// chain id could be a hex string or an int value. + let response: String = try await APIRequest.send(APIRequest.getNetwork.call, parameters: [], with: self).result + let result: UInt + if response.hasHexPrefix() { + guard let num = BigUInt(response, radix: 16) else { + throw Web3Error.processingError(desc: "Get network succeeded but can't be parsed to a valid chain id.") + } + result = UInt(num) + } else { + guard let num = UInt(response) else { + throw Web3Error.processingError(desc: "Get network succeeded but can't be parsed to a valid chain id.") + } + result = num + } + self.network = Networks.fromInt(result) } attachedKeystoreManager = manager } diff --git a/Tests/web3swiftTests/localTests/ABIDecoderSliceTests.swift b/Tests/web3swiftTests/localTests/ABIDecoderSliceTests.swift index a3fbeb43c..3e7f077d8 100644 --- a/Tests/web3swiftTests/localTests/ABIDecoderSliceTests.swift +++ b/Tests/web3swiftTests/localTests/ABIDecoderSliceTests.swift @@ -27,7 +27,7 @@ final class ABIDecoderSliceTests: XCTestCase { while startIndex < data.count { let slice = data[startIndex ..< startIndex + answerSize] startIndex += answerSize - guard let bigInt = balanceofMethod.decodeReturnData(slice)["0"] as? BigUInt else { + guard let bigInt = try balanceofMethod.decodeReturnData(slice)["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Can not decode returned parameters") } let value = Utilities.formatToPrecision(bigInt, units: .wei) @@ -52,9 +52,7 @@ final class ABIDecoderSliceTests: XCTestCase { XCTAssertEqual(methods.count, 3) /// Act - guard let decodedData = multiCall2Contract.decodeReturnData("aggregate", data: data) else { - throw Web3Error.processingError(desc: "Can not decode returned parameters") - } + let decodedData = try multiCall2Contract.decodeReturnData("aggregate", data: data) guard let returnData = decodedData["returnData"] as? [Data] else { throw Web3Error.dataError @@ -63,7 +61,7 @@ final class ABIDecoderSliceTests: XCTestCase { XCTAssertEqual(returnData.count, 3) for item in methods.enumerated() { - XCTAssertNotNil(item.element.decodeReturnData(returnData[item.offset])["0"]) + XCTAssertNotNil(try item.element.decodeReturnData(returnData[item.offset])["0"]) } } @@ -74,9 +72,7 @@ final class ABIDecoderSliceTests: XCTestCase { let erc20_balanceof = try EthereumContract(Web3.Utils.erc20ABI).methods["balanceOf"]!.first! /// Act - guard let decodedData = contract.decodeReturnData("tryAggregate", data: data) else { - throw Web3Error.processingError(desc: "Can not decode returned parameters") - } + let decodedData = try contract.decodeReturnData("tryAggregate", data: data) guard let returnData = decodedData["returnData"] as? [[Any]] else { throw Web3Error.dataError @@ -84,7 +80,7 @@ final class ABIDecoderSliceTests: XCTestCase { var resultArray = [BigUInt]() for i in 0..<2 { guard let data = returnData[i][1] as? Data, - let balance = erc20_balanceof.decodeReturnData(data)["0"] as? BigUInt else { + let balance = try? erc20_balanceof.decodeReturnData(data)["0"] as? BigUInt else { resultArray.append(0) continue } diff --git a/Tests/web3swiftTests/localTests/ABIElementErrorDecodingTest.swift b/Tests/web3swiftTests/localTests/ABIElementErrorDecodingTest.swift index 181337d19..d0aa1b9d8 100644 --- a/Tests/web3swiftTests/localTests/ABIElementErrorDecodingTest.swift +++ b/Tests/web3swiftTests/localTests/ABIElementErrorDecodingTest.swift @@ -65,123 +65,140 @@ class ABIElementErrorDecodingTest: XCTestCase { XCTAssertTrue(emptyFunction.decodeErrorResponse(Data()) == nil) } - func testDecodeEmptyErrorOnOneOutputFunction() { - guard let errorData = oneOutputFunction.decodeErrorResponse(Data()) else { - XCTFail("Empty Data must be decoded as a `revert()` or `require(false)` call if function used to decode it has at least one output parameter.") - return + /// `require(expression)` and `revert()` without a message return 0 bytes, + /// we can noly catch an error when function has a return value + func testDecodeEmptyErrorOnOneOutputFunction() throws { + let contract = try EthereumContract(abi: [.function(emptyFunction)]) + do { + try contract.decodeReturnData(emptyFunction.signature, data: Data()) + } catch { + XCTFail() } - XCTAssertEqual(errorData["_success"] as? Bool, false) - XCTAssertNotNil(errorData["_failureReason"] as? String) - - let decodedOutput = oneOutputFunction.decodeReturnData(Data()) - - XCTAssertEqual(errorData["_success"] as? Bool, decodedOutput["_success"] as? Bool) - XCTAssertEqual(errorData["_failureReason"] as? String, decodedOutput["_failureReason"] as? String) + let contract2 = try EthereumContract(abi: [.function(oneOutputFunction)]) + do { + try contract2.decodeReturnData(oneOutputFunction.signature, data: Data()) + XCTFail() + } catch { + print(error) + } } /// Data is decoded as a call of `revert` or `require` with a message no matter the number of outputs configured in the ``ABI/Element/Function``. /// `revert(message)` and `require(false,message)`return at least 128 bytes. We cannot differentiate between `require` or `revert`. - func testDecodeDefaultErrorWithMessage() { + func testDecodeDefaultErrorWithMessage() throws { /// 08c379a0 - Error(string) function selector /// 0000000000000000000000000000000000000000000000000000000000000020 - Data offset /// 000000000000000000000000000000000000000000000000000000000000001a - Message length /// 4e6f7420656e6f7567682045746865722070726f76696465642e000000000000 - Message + 0 bytes padding /// 0000... - some more 0 bytes padding to make the number of bytes match 32 bytes chunks - let errorResponse = Data.fromHex("08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4e6f7420656e6f7567682045746865722070726f76696465642e00000000000000000000000000000000000000000000000000000000000000000000")! - guard let errorData = emptyFunction.decodeErrorResponse(errorResponse) else { - XCTFail("Data must be decoded as a `revert(\"Not enough Ether provided.\")` or `require(false, \"Not enough Ether provided.\")` but decoding failed completely.") - return + let errorResponse = Data.fromHex("08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a4e6f7420656e6f7567682045746865722070726f76696465642e0000000000000000000000000000000000000000000000000000000000000000000000000000")! + let contract = try EthereumContract(abi: [.function(emptyFunction)]) + + do { + try contract.decodeReturnData(emptyFunction.signature, data: errorResponse) + XCTFail("decode function should throw an error") + } catch Web3Error.revert(_, let reason) { + XCTAssertEqual(reason, "Not enough Ether provided.") } - XCTAssertEqual(errorData["_success"] as? Bool, false) - XCTAssertEqual(errorData["_abortedByRevertOrRequire"] as? Bool, true) - XCTAssertEqual(errorData["_errorMessage"] as? String, "Not enough Ether provided.") - XCTAssertNotNil(errorData["_failureReason"] as? String) - - let decodedOutput = oneOutputFunction.decodeReturnData(errorResponse) - - XCTAssertEqual(errorData["_success"] as? Bool, decodedOutput["_success"] as? Bool) - XCTAssertEqual(errorData["_failureReason"] as? String, decodedOutput["_failureReason"] as? String) - XCTAssertEqual(errorData["_abortedByRevertOrRequire"] as? Bool, decodedOutput["_abortedByRevertOrRequire"] as? Bool) - XCTAssertEqual(errorData["_errorMessage"] as? String, decodedOutput["_errorMessage"] as? String) - XCTAssertEqual(decodedOutput["_errorMessage"] as? String, "Not enough Ether provided.") + XCTAssertEqual(EthError.decodeStringError(errorResponse[4...]), "Not enough Ether provided.") } - /// Data is decoded as a call of `revert Unauthorized()`. Decoded only if custom error ABI is given. - func testDecodeRevertWithCustomError() { + /// Data is decoded as a call of `revert Unauthorized()` + func testDecodeRevertWithCustomError() throws { /// 82b42900 - Unauthorized() function selector /// 00000000000000000000000000000000000000000000000000000000 - padding bytes - let errorResponse = Data.fromHex("82b4290000000000000000000000000000000000000000000000000000000000")! - let errors: [String: EthError] = ["82b42900": .init(name: "Unauthorized", inputs: [])] - guard let errorData = emptyFunction.decodeErrorResponse(errorResponse, errors: errors) else { - XCTFail("Data must be decoded as a `revert(\"Not enough Ether provided.\")` or `require(false, \"Not enough Ether provided.\")` but decoding failed completely.") - return + let errorResponse = Data.fromHex("82b429000000000000000000000000000000000000000000000000000000000000000000")! + let error = ABI.Element.EthError(name: "Unauthorized", inputs: []) + let contract = try EthereumContract(abi: [.function(emptyFunction), .error(error)] ) + + do { + try contract.decodeReturnData(emptyFunction.signature, data: errorResponse) + XCTFail("decode function should throw an error") + } catch Web3Error.revertCustom(let signature, let args) { + XCTAssertEqual(signature, "Unauthorized()") + XCTAssertTrue(args.isEmpty) } - XCTAssertEqual(errorData["_success"] as? Bool, false) - XCTAssertEqual(errorData["_abortedByRevertOrRequire"] as? Bool, true) - XCTAssertEqual(errorData["_error"] as? String, "Unauthorized()") - - let decodedOutput = oneOutputFunction.decodeReturnData(errorResponse, errors: errors) - - XCTAssertEqual(errorData["_success"] as? Bool, decodedOutput["_success"] as? Bool) - XCTAssertEqual(errorData["_abortedByRevertOrRequire"] as? Bool, decodedOutput["_abortedByRevertOrRequire"] as? Bool) - XCTAssertEqual(errorData["_error"] as? String, decodedOutput["_error"] as? String) + guard let decoded = error.decodeEthError(errorResponse[4...]) else { + XCTFail("decode response failed.") + return + } + XCTAssertTrue(decoded.isEmpty) } - /// Data is decoded as a call of `revert Unauthorized()`. Decoded only if custom error ABI is given. + /// Data is decoded as a call of `revert Unauthorized(bool)`. /// Trying to decode as `Unauthorized(string)`. Must fail. - func testDecodeRevertWithCustomErrorFailed() { - /// 82b42900 - Unauthorized() function selector + func testDecodeRevertWithCustomErrorFailed() throws { + /// 5caef992 - Unauthorized(bool) function selector /// 00000000000000000000000000000000000000000000000000000000 - padding bytes - let errorResponse = Data.fromHex("82b4290000000000000000000000000000000000000000000000000000000000")! - let errors: [String: EthError] = ["82b42900": .init(name: "Unauthorized", inputs: [.init(name: "", type: .string)])] - guard let errorData = emptyFunction.decodeErrorResponse(errorResponse, errors: errors) else { - XCTFail("Data must be decoded as a `revert(\"Not enough Ether provided.\")` or `require(false, \"Not enough Ether provided.\")` but decoding failed completely.") - return + let errorResponse = Data.fromHex("5caef9920000000000000000000000000000000000000000000000000000000000000000")! + let error = ABI.Element.EthError(name: "Unauthorized", inputs: [.init(name: "", type: .bool)]) + let contract = try EthereumContract(abi: [.function(oneOutputFunction), .error(error)] ) + + do { + try contract.decodeReturnData(oneOutputFunction.signature, data: errorResponse) + XCTFail("decode function should throw an error") + } catch Web3Error.revertCustom(let signature, let args) { + XCTAssertEqual(signature, "Unauthorized(bool)") + XCTAssertEqual(args["0"] as? Bool, false) } - XCTAssertEqual(errorData["_success"] as? Bool, false) - XCTAssertEqual(errorData["_abortedByRevertOrRequire"] as? Bool, true) - XCTAssertEqual(errorData["_error"] as? String, "Unauthorized(string)") - XCTAssertEqual(errorData["_parsingError"] as? String, "Data matches Unauthorized(string) but failed to be decoded.") - - let decodedOutput = oneOutputFunction.decodeReturnData(errorResponse, errors: errors) - - XCTAssertEqual(errorData["_success"] as? Bool, decodedOutput["_success"] as? Bool) - XCTAssertEqual(errorData["_abortedByRevertOrRequire"] as? Bool, decodedOutput["_abortedByRevertOrRequire"] as? Bool) - XCTAssertEqual(errorData["_error"] as? String, decodedOutput["_error"] as? String) - XCTAssertEqual(errorData["_parsingError"] as? String, decodedOutput["_parsingError"] as? String) + guard let decoded = error.decodeEthError(errorResponse[4...]) else { + XCTFail("decode response failed.") + return + } + XCTAssertEqual(decoded["0"] as? Bool, false) } /// Data is decoded as a call of `revert Unauthorized("Reason")`. Decoded only if custom error ABI is given. /// The custom error argument must be extractable by index and name if the name is available. - func testDecodeRevertWithCustomErrorWithArguments() { + func testDecodeRevertWithCustomErrorWithArguments() throws { /// 973d02cb - `Unauthorized(string)` function selector /// 0000000000000000000000000000000000000000000000000000000000000020 - data offset /// 0000000000000000000000000000000000000000000000000000000000000006 - first custom argument length /// 526561736f6e0000000000000000000000000000000000000000000000000000 - first custom argument bytes + 0 bytes padding /// 0000... - some more 0 bytes padding to make the number of bytes match 32 bytes chunks - let errorResponse = Data.fromHex("973d02cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006526561736f6e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")! - let errors: [String: EthError] = ["973d02cb": .init(name: "Unauthorized", inputs: [.init(name: "message_arg", type: .string)])] - guard let errorData = emptyFunction.decodeErrorResponse(errorResponse, errors: errors) else { - XCTFail("Data must be decoded as a `revert(\"Not enough Ether provided.\")` or `require(false, \"Not enough Ether provided.\")` but decoding failed completely.") - return + let errorResponse = Data.fromHex("973d02cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006526561736f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")! + let error = ABI.Element.EthError(name: "Unauthorized", inputs: [.init(name: "message_arg", type: .string)]) + let contract = try EthereumContract(abi: [.function(emptyFunction), .error(error)]) + + do { + try contract.decodeReturnData(emptyFunction.signature, data: errorResponse) + XCTFail("decode function should throw an error") + } catch Web3Error.revertCustom(let signature, let args) { + XCTAssertEqual(signature, "Unauthorized(string)") + XCTAssertEqual(args["0"] as? String, "Reason") + XCTAssertEqual(args["message_arg"] as? String, "Reason") } - XCTAssertEqual(errorData["_success"] as? Bool, false) - XCTAssertEqual(errorData["_abortedByRevertOrRequire"] as? Bool, true) - XCTAssertEqual(errorData["_error"] as? String, "Unauthorized(string message_arg)") - XCTAssertEqual(errorData["0"] as? String, "Reason") - XCTAssertEqual(errorData["0"] as? String, errorData["message_arg"] as? String) + guard let decoded = error.decodeEthError(errorResponse[4...]) else { + XCTFail("decode response failed.") + return + } + XCTAssertEqual(decoded["0"] as? String, "Reason") + XCTAssertEqual(decoded["message_arg"] as? String, "Reason") + } - let decodedOutput = oneOutputFunction.decodeReturnData(errorResponse, errors: errors) + /// Data is decoded as a panic exception is generated. + /// Example: + /// ``` solidity + /// function panicError() public { + /// assert(false); + /// } + /// ``` + func testDecodePanicError() throws { + let errorResponse = Data(hex: "4e487b710000000000000000000000000000000000000000000000000000000000000001") + let contract = try EthereumContract(abi: [.function(emptyFunction)]) + + do { + try contract.decodeReturnData(emptyFunction.signature, data: errorResponse) + } catch Web3Error.revert(let message, let code) { + XCTAssertTrue(message.contains("reverted with panic code 0x01")) + XCTAssertEqual(code, "0x01") + } - XCTAssertEqual(errorData["_success"] as? Bool, decodedOutput["_success"] as? Bool) - XCTAssertEqual(errorData["_abortedByRevertOrRequire"] as? Bool, decodedOutput["_abortedByRevertOrRequire"] as? Bool) - XCTAssertEqual(errorData["_error"] as? String, decodedOutput["_error"] as? String) - XCTAssertEqual(errorData["0"] as? String, decodedOutput["0"] as? String) - XCTAssertEqual(errorData["message_arg"] as? String, decodedOutput["message_arg"] as? String) + XCTAssertEqual(EthError.decodePanicError(errorResponse[4...]), 1) } } diff --git a/Tests/web3swiftTests/localTests/ABIElementsTests.swift b/Tests/web3swiftTests/localTests/ABIElementsTests.swift new file mode 100644 index 000000000..a94fa3d9d --- /dev/null +++ b/Tests/web3swiftTests/localTests/ABIElementsTests.swift @@ -0,0 +1,29 @@ +// +// ABIElementsTests.swift +// +// +// Created by JeneaVranceanu on 09.01.2024. +// + +import Foundation +import XCTest +@testable import web3swift +@testable import Web3Core + +class ABIElementsTests: XCTestCase { + + func testABIElementFunction() { + let test1Function = ABI.Element.Function(name: "Test1", + inputs: [], + outputs: [], + constant: true, + payable: false) + + XCTAssertEqual(test1Function.name, "Test1") + XCTAssertEqual(test1Function.selector, String("Test1()".sha3(.keccak256).prefix(8))) + XCTAssertEqual(test1Function.selectorEncoded, + Data.fromHex("Test1()".sha3(.keccak256))?.prefix(4)) + + } + +} diff --git a/Tests/web3swiftTests/localTests/AdvancedABIv2Tests.swift b/Tests/web3swiftTests/localTests/AdvancedABIv2Tests.swift index 066a1b7a8..66c3749df 100755 --- a/Tests/web3swiftTests/localTests/AdvancedABIv2Tests.swift +++ b/Tests/web3swiftTests/localTests/AdvancedABIv2Tests.swift @@ -17,20 +17,7 @@ class AdvancedABIv2Tests: LocalTestCase { let bytecode = Data.fromHex("6080604052341561000f57600080fd5b610cb18061001e6000396000f30060806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063189533931461007257806338163ff51461009b57806388be6c65146100c4578063e7c1a47c146100ed578063f376e01314610116575b600080fd5b341561007d57600080fd5b61008561013f565b6040516100929190610a9f565b60405180910390f35b34156100a657600080fd5b6100ae610220565b6040516100bb9190610a7d565b60405180910390f35b34156100cf57600080fd5b6100d76102c5565b6040516100e49190610ae3565b60405180910390f35b34156100f857600080fd5b610100610350565b60405161010d9190610ac1565b60405180910390f35b341561012157600080fd5b610129610399565b6040516101369190610b05565b60405180910390f35b6060600260405190808252806020026020018201604052801561017657816020015b60608152602001906001900390816101615790505b5090506040805190810160405280600581526020017f48656c6c6f0000000000000000000000000000000000000000000000000000008152508160008151811015156101be57fe5b906020019060200201819052506040805190810160405280600581526020017f576f726c6400000000000000000000000000000000000000000000000000000081525081600181518110151561021057fe5b9060200190602002018190525090565b610228610546565b6040805190810160405280600581526020017f48656c6c6f00000000000000000000000000000000000000000000000000000081525081600060028110151561026d57fe5b60200201819052506040805190810160405280600581526020017f576f726c640000000000000000000000000000000000000000000000000000008152508160016002811015156102ba57fe5b602002018190525090565b6060600260405190808252806020026020018201604052801561030257816020015b6102ef61056d565b8152602001906001900390816102e75790505b50905061030d610399565b81600081518110151561031c57fe5b90602001906020020181905250610331610399565b81600181518110151561034057fe5b9060200190602002018190525090565b6103586105a9565b610360610399565b81600060028110151561036f57fe5b602002018190525061037f610399565b81600160028110151561038e57fe5b602002018190525090565b6103a16105d8565b60606103ab610614565b6103b3610546565b60036040519080825280602002602001820160405280156103e35781602001602082028038833980820191505090505b50925060008360008151811015156103f757fe5b9060200190602002018181525050600183600181518110151561041657fe5b9060200190602002018181525050600283600281518110151561043557fe5b90602001906020020181815250506040805190810160405280600081526020016001815250915060408051908101604052806040805190810160405280600581526020017f48656c6c6f00000000000000000000000000000000000000000000000000000081525081526020016040805190810160405280600581526020017f576f726c64000000000000000000000000000000000000000000000000000000815250815250905060a060405190810160405280600181526020016040805190810160405280600b81526020017f48656c6c6f20776f726c64000000000000000000000000000000000000000000815250815260200183815260200184815260200182815250935083935050505090565b60408051908101604052806002905b60608152602001906001900390816105555790505090565b60e060405190810160405280600081526020016060815260200161058f610636565b8152602001606081526020016105a3610658565b81525090565b6101c0604051908101604052806002905b6105c261056d565b8152602001906001900390816105ba5790505090565b60e06040519081016040528060008152602001606081526020016105fa610636565b81526020016060815260200161060e610658565b81525090565b6040805190810160405280600290602082028038833980820191505090505090565b6040805190810160405280600290602082028038833980820191505090505090565b60408051908101604052806002905b60608152602001906001900390816106675790505090565b600061068a82610b81565b8360208202850161069a85610b31565b60005b848110156106d35783830388526106b5838351610930565b92506106c082610bdb565b915060208801975060018101905061069d565b508196508694505050505092915050565b60006106ef82610b76565b836020820285016106ff85610b27565b60005b8481101561073857838303885261071a838351610930565b925061072582610bce565b9150602088019750600181019050610702565b508196508694505050505092915050565b600061075482610b8c565b8084526020840193508360208202850161076d85610b3b565b60005b848110156107a6578383038852610788838351610930565b925061079382610be8565b9150602088019750600181019050610770565b508196508694505050505092915050565b60006107c282610b97565b836020820285016107d285610b48565b60005b8481101561080b5783830388526107ed8383516109ea565b92506107f882610bf5565b91506020880197506001810190506107d5565b508196508694505050505092915050565b600061082782610ba2565b8084526020840193508360208202850161084085610b52565b60005b8481101561087957838303885261085b8383516109ea565b925061086682610c02565b9150602088019750600181019050610843565b508196508694505050505092915050565b61089381610bad565b61089c82610b5f565b60005b828110156108ce576108b2858351610a6e565b6108bb82610c0f565b915060208501945060018101905061089f565b5050505050565b60006108e082610bb8565b8084526020840193506108f283610b69565b60005b8281101561092457610908868351610a6e565b61091182610c1c565b91506020860195506001810190506108f5565b50849250505092915050565b600061093b82610bc3565b80845261094f816020860160208601610c33565b61095881610c66565b602085010191505092915050565b600060c08301600083015161097e6000860182610a6e565b50602083015184820360208601526109968282610930565b91505060408301516109ab604086018261088a565b50606083015184820360808601526109c382826108d5565b915050608083015184820360a08601526109dd82826106e4565b9150508091505092915050565b600060c083016000830151610a026000860182610a6e565b5060208301518482036020860152610a1a8282610930565b9150506040830151610a2f604086018261088a565b5060608301518482036080860152610a4782826108d5565b915050608083015184820360a0860152610a6182826106e4565b9150508091505092915050565b610a7781610c29565b82525050565b60006020820190508181036000830152610a97818461067f565b905092915050565b60006020820190508181036000830152610ab98184610749565b905092915050565b60006020820190508181036000830152610adb81846107b7565b905092915050565b60006020820190508181036000830152610afd818461081c565b905092915050565b60006020820190508181036000830152610b1f8184610966565b905092915050565b6000819050919050565b6000819050919050565b6000602082019050919050565b6000819050919050565b6000602082019050919050565b6000819050919050565b6000602082019050919050565b600060029050919050565b600060029050919050565b600081519050919050565b600060029050919050565b600081519050919050565b600060029050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000819050919050565b60005b83811015610c51578082015181840152602081019050610c36565b83811115610c60576000848401525b50505050565b6000601f19601f83011690509190505600a265627a7a72305820fdaf8ce6fe282a46498c8066d5b5ac382b69969eee38e1ad03c0d501b27f65366c6578706572696d656e74616cf50037")! let web3 = try await Web3.new(LocalTestCase.url) - let allAddresses = try await web3.eth.ownedAccounts() - var contract = web3.contract(abiString, at: nil, abiVersion: 2)! - - // MARK: Writing Data flow - let deployTx = contract.prepareDeploy(bytecode: bytecode)! - deployTx.transaction.from = allAddresses[0] - // MARK: Sending Data flow - let policies = Policies(gasLimitPolicy: .manual(3000000)) - let result = try await deployTx.writeToChain(password: "web3swift", policies: policies, sendRaw: false) - let txHash = result.hash.stripHexPrefix() - - Thread.sleep(forTimeInterval: 1.0) - - let receipt = try await web3.eth.transactionReceipt(Data.fromHex(txHash)!) + let receipt = try await deployContract(bytecode: bytecode, abiString: abiString) switch receipt.status { case .notYetProcessed: @@ -39,11 +26,11 @@ class AdvancedABIv2Tests: LocalTestCase { break } - contract = web3.contract(abiString, at: receipt.contractAddress, abiVersion: 2)! + let contract = web3.contract(abiString, at: receipt.contractAddress, abiVersion: 2)! // MARK: Read data from ABI flow // MARK: - Encoding ABI Data flow let tx = contract.createReadOperation("testSingle") - _ = try await tx!.callContractMethod() + _ = try await tx!.call() } func testAdvancedABIv2staticArray() async throws { @@ -51,20 +38,7 @@ class AdvancedABIv2Tests: LocalTestCase { let bytecode = Data.fromHex("6080604052341561000f57600080fd5b610cb18061001e6000396000f30060806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063189533931461007257806338163ff51461009b57806388be6c65146100c4578063e7c1a47c146100ed578063f376e01314610116575b600080fd5b341561007d57600080fd5b61008561013f565b6040516100929190610a9f565b60405180910390f35b34156100a657600080fd5b6100ae610220565b6040516100bb9190610a7d565b60405180910390f35b34156100cf57600080fd5b6100d76102c5565b6040516100e49190610ae3565b60405180910390f35b34156100f857600080fd5b610100610350565b60405161010d9190610ac1565b60405180910390f35b341561012157600080fd5b610129610399565b6040516101369190610b05565b60405180910390f35b6060600260405190808252806020026020018201604052801561017657816020015b60608152602001906001900390816101615790505b5090506040805190810160405280600581526020017f48656c6c6f0000000000000000000000000000000000000000000000000000008152508160008151811015156101be57fe5b906020019060200201819052506040805190810160405280600581526020017f576f726c6400000000000000000000000000000000000000000000000000000081525081600181518110151561021057fe5b9060200190602002018190525090565b610228610546565b6040805190810160405280600581526020017f48656c6c6f00000000000000000000000000000000000000000000000000000081525081600060028110151561026d57fe5b60200201819052506040805190810160405280600581526020017f576f726c640000000000000000000000000000000000000000000000000000008152508160016002811015156102ba57fe5b602002018190525090565b6060600260405190808252806020026020018201604052801561030257816020015b6102ef61056d565b8152602001906001900390816102e75790505b50905061030d610399565b81600081518110151561031c57fe5b90602001906020020181905250610331610399565b81600181518110151561034057fe5b9060200190602002018190525090565b6103586105a9565b610360610399565b81600060028110151561036f57fe5b602002018190525061037f610399565b81600160028110151561038e57fe5b602002018190525090565b6103a16105d8565b60606103ab610614565b6103b3610546565b60036040519080825280602002602001820160405280156103e35781602001602082028038833980820191505090505b50925060008360008151811015156103f757fe5b9060200190602002018181525050600183600181518110151561041657fe5b9060200190602002018181525050600283600281518110151561043557fe5b90602001906020020181815250506040805190810160405280600081526020016001815250915060408051908101604052806040805190810160405280600581526020017f48656c6c6f00000000000000000000000000000000000000000000000000000081525081526020016040805190810160405280600581526020017f576f726c64000000000000000000000000000000000000000000000000000000815250815250905060a060405190810160405280600181526020016040805190810160405280600b81526020017f48656c6c6f20776f726c64000000000000000000000000000000000000000000815250815260200183815260200184815260200182815250935083935050505090565b60408051908101604052806002905b60608152602001906001900390816105555790505090565b60e060405190810160405280600081526020016060815260200161058f610636565b8152602001606081526020016105a3610658565b81525090565b6101c0604051908101604052806002905b6105c261056d565b8152602001906001900390816105ba5790505090565b60e06040519081016040528060008152602001606081526020016105fa610636565b81526020016060815260200161060e610658565b81525090565b6040805190810160405280600290602082028038833980820191505090505090565b6040805190810160405280600290602082028038833980820191505090505090565b60408051908101604052806002905b60608152602001906001900390816106675790505090565b600061068a82610b81565b8360208202850161069a85610b31565b60005b848110156106d35783830388526106b5838351610930565b92506106c082610bdb565b915060208801975060018101905061069d565b508196508694505050505092915050565b60006106ef82610b76565b836020820285016106ff85610b27565b60005b8481101561073857838303885261071a838351610930565b925061072582610bce565b9150602088019750600181019050610702565b508196508694505050505092915050565b600061075482610b8c565b8084526020840193508360208202850161076d85610b3b565b60005b848110156107a6578383038852610788838351610930565b925061079382610be8565b9150602088019750600181019050610770565b508196508694505050505092915050565b60006107c282610b97565b836020820285016107d285610b48565b60005b8481101561080b5783830388526107ed8383516109ea565b92506107f882610bf5565b91506020880197506001810190506107d5565b508196508694505050505092915050565b600061082782610ba2565b8084526020840193508360208202850161084085610b52565b60005b8481101561087957838303885261085b8383516109ea565b925061086682610c02565b9150602088019750600181019050610843565b508196508694505050505092915050565b61089381610bad565b61089c82610b5f565b60005b828110156108ce576108b2858351610a6e565b6108bb82610c0f565b915060208501945060018101905061089f565b5050505050565b60006108e082610bb8565b8084526020840193506108f283610b69565b60005b8281101561092457610908868351610a6e565b61091182610c1c565b91506020860195506001810190506108f5565b50849250505092915050565b600061093b82610bc3565b80845261094f816020860160208601610c33565b61095881610c66565b602085010191505092915050565b600060c08301600083015161097e6000860182610a6e565b50602083015184820360208601526109968282610930565b91505060408301516109ab604086018261088a565b50606083015184820360808601526109c382826108d5565b915050608083015184820360a08601526109dd82826106e4565b9150508091505092915050565b600060c083016000830151610a026000860182610a6e565b5060208301518482036020860152610a1a8282610930565b9150506040830151610a2f604086018261088a565b5060608301518482036080860152610a4782826108d5565b915050608083015184820360a0860152610a6182826106e4565b9150508091505092915050565b610a7781610c29565b82525050565b60006020820190508181036000830152610a97818461067f565b905092915050565b60006020820190508181036000830152610ab98184610749565b905092915050565b60006020820190508181036000830152610adb81846107b7565b905092915050565b60006020820190508181036000830152610afd818461081c565b905092915050565b60006020820190508181036000830152610b1f8184610966565b905092915050565b6000819050919050565b6000819050919050565b6000602082019050919050565b6000819050919050565b6000602082019050919050565b6000819050919050565b6000602082019050919050565b600060029050919050565b600060029050919050565b600081519050919050565b600060029050919050565b600081519050919050565b600060029050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000819050919050565b60005b83811015610c51578082015181840152602081019050610c36565b83811115610c60576000848401525b50505050565b6000601f19601f83011690509190505600a265627a7a72305820fdaf8ce6fe282a46498c8066d5b5ac382b69969eee38e1ad03c0d501b27f65366c6578706572696d656e74616cf50037")! let web3 = try await Web3.new(LocalTestCase.url) - let allAddresses = try await web3.eth.ownedAccounts() - var contract = web3.contract(abiString, at: nil, abiVersion: 2)! - - let parameters: [Any] = [] - // MARK: Writing Data flow - let deployTx = contract.prepareDeploy(bytecode: bytecode, parameters: parameters)! - deployTx.transaction.from = allAddresses[0] - let policies = Policies(gasLimitPolicy: .manual(3000000)) - let result = try await deployTx.writeToChain(password: "web3swift", policies: policies, sendRaw: false) - let txHash = result.hash.stripHexPrefix() - - Thread.sleep(forTimeInterval: 1.0) - - let receipt = try await web3.eth.transactionReceipt(Data.fromHex(txHash)!) + let receipt = try await deployContract(bytecode: bytecode, abiString: abiString) switch receipt.status { case .notYetProcessed: @@ -73,11 +47,11 @@ class AdvancedABIv2Tests: LocalTestCase { break } - contract = web3.contract(abiString, at: receipt.contractAddress, abiVersion: 2)! + let contract = web3.contract(abiString, at: receipt.contractAddress, abiVersion: 2)! // MARK: Read data from ABI flow // MARK: - Encoding ABI Data flow let tx = contract.createReadOperation("testStaticArray") - _ = try await tx!.callContractMethod() + _ = try await tx!.call() } func testAdvancedABIv2dynamicArray() async throws { @@ -85,20 +59,7 @@ class AdvancedABIv2Tests: LocalTestCase { let bytecode = Data.fromHex("6080604052341561000f57600080fd5b610cb18061001e6000396000f30060806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063189533931461007257806338163ff51461009b57806388be6c65146100c4578063e7c1a47c146100ed578063f376e01314610116575b600080fd5b341561007d57600080fd5b61008561013f565b6040516100929190610a9f565b60405180910390f35b34156100a657600080fd5b6100ae610220565b6040516100bb9190610a7d565b60405180910390f35b34156100cf57600080fd5b6100d76102c5565b6040516100e49190610ae3565b60405180910390f35b34156100f857600080fd5b610100610350565b60405161010d9190610ac1565b60405180910390f35b341561012157600080fd5b610129610399565b6040516101369190610b05565b60405180910390f35b6060600260405190808252806020026020018201604052801561017657816020015b60608152602001906001900390816101615790505b5090506040805190810160405280600581526020017f48656c6c6f0000000000000000000000000000000000000000000000000000008152508160008151811015156101be57fe5b906020019060200201819052506040805190810160405280600581526020017f576f726c6400000000000000000000000000000000000000000000000000000081525081600181518110151561021057fe5b9060200190602002018190525090565b610228610546565b6040805190810160405280600581526020017f48656c6c6f00000000000000000000000000000000000000000000000000000081525081600060028110151561026d57fe5b60200201819052506040805190810160405280600581526020017f576f726c640000000000000000000000000000000000000000000000000000008152508160016002811015156102ba57fe5b602002018190525090565b6060600260405190808252806020026020018201604052801561030257816020015b6102ef61056d565b8152602001906001900390816102e75790505b50905061030d610399565b81600081518110151561031c57fe5b90602001906020020181905250610331610399565b81600181518110151561034057fe5b9060200190602002018190525090565b6103586105a9565b610360610399565b81600060028110151561036f57fe5b602002018190525061037f610399565b81600160028110151561038e57fe5b602002018190525090565b6103a16105d8565b60606103ab610614565b6103b3610546565b60036040519080825280602002602001820160405280156103e35781602001602082028038833980820191505090505b50925060008360008151811015156103f757fe5b9060200190602002018181525050600183600181518110151561041657fe5b9060200190602002018181525050600283600281518110151561043557fe5b90602001906020020181815250506040805190810160405280600081526020016001815250915060408051908101604052806040805190810160405280600581526020017f48656c6c6f00000000000000000000000000000000000000000000000000000081525081526020016040805190810160405280600581526020017f576f726c64000000000000000000000000000000000000000000000000000000815250815250905060a060405190810160405280600181526020016040805190810160405280600b81526020017f48656c6c6f20776f726c64000000000000000000000000000000000000000000815250815260200183815260200184815260200182815250935083935050505090565b60408051908101604052806002905b60608152602001906001900390816105555790505090565b60e060405190810160405280600081526020016060815260200161058f610636565b8152602001606081526020016105a3610658565b81525090565b6101c0604051908101604052806002905b6105c261056d565b8152602001906001900390816105ba5790505090565b60e06040519081016040528060008152602001606081526020016105fa610636565b81526020016060815260200161060e610658565b81525090565b6040805190810160405280600290602082028038833980820191505090505090565b6040805190810160405280600290602082028038833980820191505090505090565b60408051908101604052806002905b60608152602001906001900390816106675790505090565b600061068a82610b81565b8360208202850161069a85610b31565b60005b848110156106d35783830388526106b5838351610930565b92506106c082610bdb565b915060208801975060018101905061069d565b508196508694505050505092915050565b60006106ef82610b76565b836020820285016106ff85610b27565b60005b8481101561073857838303885261071a838351610930565b925061072582610bce565b9150602088019750600181019050610702565b508196508694505050505092915050565b600061075482610b8c565b8084526020840193508360208202850161076d85610b3b565b60005b848110156107a6578383038852610788838351610930565b925061079382610be8565b9150602088019750600181019050610770565b508196508694505050505092915050565b60006107c282610b97565b836020820285016107d285610b48565b60005b8481101561080b5783830388526107ed8383516109ea565b92506107f882610bf5565b91506020880197506001810190506107d5565b508196508694505050505092915050565b600061082782610ba2565b8084526020840193508360208202850161084085610b52565b60005b8481101561087957838303885261085b8383516109ea565b925061086682610c02565b9150602088019750600181019050610843565b508196508694505050505092915050565b61089381610bad565b61089c82610b5f565b60005b828110156108ce576108b2858351610a6e565b6108bb82610c0f565b915060208501945060018101905061089f565b5050505050565b60006108e082610bb8565b8084526020840193506108f283610b69565b60005b8281101561092457610908868351610a6e565b61091182610c1c565b91506020860195506001810190506108f5565b50849250505092915050565b600061093b82610bc3565b80845261094f816020860160208601610c33565b61095881610c66565b602085010191505092915050565b600060c08301600083015161097e6000860182610a6e565b50602083015184820360208601526109968282610930565b91505060408301516109ab604086018261088a565b50606083015184820360808601526109c382826108d5565b915050608083015184820360a08601526109dd82826106e4565b9150508091505092915050565b600060c083016000830151610a026000860182610a6e565b5060208301518482036020860152610a1a8282610930565b9150506040830151610a2f604086018261088a565b5060608301518482036080860152610a4782826108d5565b915050608083015184820360a0860152610a6182826106e4565b9150508091505092915050565b610a7781610c29565b82525050565b60006020820190508181036000830152610a97818461067f565b905092915050565b60006020820190508181036000830152610ab98184610749565b905092915050565b60006020820190508181036000830152610adb81846107b7565b905092915050565b60006020820190508181036000830152610afd818461081c565b905092915050565b60006020820190508181036000830152610b1f8184610966565b905092915050565b6000819050919050565b6000819050919050565b6000602082019050919050565b6000819050919050565b6000602082019050919050565b6000819050919050565b6000602082019050919050565b600060029050919050565b600060029050919050565b600081519050919050565b600060029050919050565b600081519050919050565b600060029050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000819050919050565b60005b83811015610c51578082015181840152602081019050610c36565b83811115610c60576000848401525b50505050565b6000601f19601f83011690509190505600a265627a7a72305820fdaf8ce6fe282a46498c8066d5b5ac382b69969eee38e1ad03c0d501b27f65366c6578706572696d656e74616cf50037")! let web3 = try await Web3.new(LocalTestCase.url) - let allAddresses = try await web3.eth.ownedAccounts() - var contract = web3.contract(abiString, at: nil, abiVersion: 2)! - - let parameters: [Any] = [] - // MARK: Writing Data flow - let deployTx = contract.prepareDeploy(bytecode: bytecode, parameters: parameters)! - deployTx.transaction.from = allAddresses[0] - let policies = Policies(gasLimitPolicy: .manual(3000000)) - let result = try await deployTx.writeToChain(password: "web3swift", policies: policies, sendRaw: false) - let txHash = result.hash.stripHexPrefix() - - Thread.sleep(forTimeInterval: 1.0) - - let receipt = try await web3.eth.transactionReceipt(Data.fromHex(txHash)!) + let receipt = try await deployContract(bytecode: bytecode, abiString: abiString) switch receipt.status { case .notYetProcessed: @@ -107,10 +68,10 @@ class AdvancedABIv2Tests: LocalTestCase { break } - contract = web3.contract(abiString, at: receipt.contractAddress, abiVersion: 2)! + let contract = web3.contract(abiString, at: receipt.contractAddress, abiVersion: 2)! let tx = contract.createReadOperation("testDynArray") - _ = try await tx!.callContractMethod() + _ = try await tx!.call() } func testAdvancedABIv2dynamicArrayOfStrings() async throws { @@ -118,20 +79,7 @@ class AdvancedABIv2Tests: LocalTestCase { let bytecode = Data.fromHex("6080604052341561000f57600080fd5b610cb18061001e6000396000f30060806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063189533931461007257806338163ff51461009b57806388be6c65146100c4578063e7c1a47c146100ed578063f376e01314610116575b600080fd5b341561007d57600080fd5b61008561013f565b6040516100929190610a9f565b60405180910390f35b34156100a657600080fd5b6100ae610220565b6040516100bb9190610a7d565b60405180910390f35b34156100cf57600080fd5b6100d76102c5565b6040516100e49190610ae3565b60405180910390f35b34156100f857600080fd5b610100610350565b60405161010d9190610ac1565b60405180910390f35b341561012157600080fd5b610129610399565b6040516101369190610b05565b60405180910390f35b6060600260405190808252806020026020018201604052801561017657816020015b60608152602001906001900390816101615790505b5090506040805190810160405280600581526020017f48656c6c6f0000000000000000000000000000000000000000000000000000008152508160008151811015156101be57fe5b906020019060200201819052506040805190810160405280600581526020017f576f726c6400000000000000000000000000000000000000000000000000000081525081600181518110151561021057fe5b9060200190602002018190525090565b610228610546565b6040805190810160405280600581526020017f48656c6c6f00000000000000000000000000000000000000000000000000000081525081600060028110151561026d57fe5b60200201819052506040805190810160405280600581526020017f576f726c640000000000000000000000000000000000000000000000000000008152508160016002811015156102ba57fe5b602002018190525090565b6060600260405190808252806020026020018201604052801561030257816020015b6102ef61056d565b8152602001906001900390816102e75790505b50905061030d610399565b81600081518110151561031c57fe5b90602001906020020181905250610331610399565b81600181518110151561034057fe5b9060200190602002018190525090565b6103586105a9565b610360610399565b81600060028110151561036f57fe5b602002018190525061037f610399565b81600160028110151561038e57fe5b602002018190525090565b6103a16105d8565b60606103ab610614565b6103b3610546565b60036040519080825280602002602001820160405280156103e35781602001602082028038833980820191505090505b50925060008360008151811015156103f757fe5b9060200190602002018181525050600183600181518110151561041657fe5b9060200190602002018181525050600283600281518110151561043557fe5b90602001906020020181815250506040805190810160405280600081526020016001815250915060408051908101604052806040805190810160405280600581526020017f48656c6c6f00000000000000000000000000000000000000000000000000000081525081526020016040805190810160405280600581526020017f576f726c64000000000000000000000000000000000000000000000000000000815250815250905060a060405190810160405280600181526020016040805190810160405280600b81526020017f48656c6c6f20776f726c64000000000000000000000000000000000000000000815250815260200183815260200184815260200182815250935083935050505090565b60408051908101604052806002905b60608152602001906001900390816105555790505090565b60e060405190810160405280600081526020016060815260200161058f610636565b8152602001606081526020016105a3610658565b81525090565b6101c0604051908101604052806002905b6105c261056d565b8152602001906001900390816105ba5790505090565b60e06040519081016040528060008152602001606081526020016105fa610636565b81526020016060815260200161060e610658565b81525090565b6040805190810160405280600290602082028038833980820191505090505090565b6040805190810160405280600290602082028038833980820191505090505090565b60408051908101604052806002905b60608152602001906001900390816106675790505090565b600061068a82610b81565b8360208202850161069a85610b31565b60005b848110156106d35783830388526106b5838351610930565b92506106c082610bdb565b915060208801975060018101905061069d565b508196508694505050505092915050565b60006106ef82610b76565b836020820285016106ff85610b27565b60005b8481101561073857838303885261071a838351610930565b925061072582610bce565b9150602088019750600181019050610702565b508196508694505050505092915050565b600061075482610b8c565b8084526020840193508360208202850161076d85610b3b565b60005b848110156107a6578383038852610788838351610930565b925061079382610be8565b9150602088019750600181019050610770565b508196508694505050505092915050565b60006107c282610b97565b836020820285016107d285610b48565b60005b8481101561080b5783830388526107ed8383516109ea565b92506107f882610bf5565b91506020880197506001810190506107d5565b508196508694505050505092915050565b600061082782610ba2565b8084526020840193508360208202850161084085610b52565b60005b8481101561087957838303885261085b8383516109ea565b925061086682610c02565b9150602088019750600181019050610843565b508196508694505050505092915050565b61089381610bad565b61089c82610b5f565b60005b828110156108ce576108b2858351610a6e565b6108bb82610c0f565b915060208501945060018101905061089f565b5050505050565b60006108e082610bb8565b8084526020840193506108f283610b69565b60005b8281101561092457610908868351610a6e565b61091182610c1c565b91506020860195506001810190506108f5565b50849250505092915050565b600061093b82610bc3565b80845261094f816020860160208601610c33565b61095881610c66565b602085010191505092915050565b600060c08301600083015161097e6000860182610a6e565b50602083015184820360208601526109968282610930565b91505060408301516109ab604086018261088a565b50606083015184820360808601526109c382826108d5565b915050608083015184820360a08601526109dd82826106e4565b9150508091505092915050565b600060c083016000830151610a026000860182610a6e565b5060208301518482036020860152610a1a8282610930565b9150506040830151610a2f604086018261088a565b5060608301518482036080860152610a4782826108d5565b915050608083015184820360a0860152610a6182826106e4565b9150508091505092915050565b610a7781610c29565b82525050565b60006020820190508181036000830152610a97818461067f565b905092915050565b60006020820190508181036000830152610ab98184610749565b905092915050565b60006020820190508181036000830152610adb81846107b7565b905092915050565b60006020820190508181036000830152610afd818461081c565b905092915050565b60006020820190508181036000830152610b1f8184610966565b905092915050565b6000819050919050565b6000819050919050565b6000602082019050919050565b6000819050919050565b6000602082019050919050565b6000819050919050565b6000602082019050919050565b600060029050919050565b600060029050919050565b600081519050919050565b600060029050919050565b600081519050919050565b600060029050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000819050919050565b60005b83811015610c51578082015181840152602081019050610c36565b83811115610c60576000848401525b50505050565b6000601f19601f83011690509190505600a265627a7a72305820fdaf8ce6fe282a46498c8066d5b5ac382b69969eee38e1ad03c0d501b27f65366c6578706572696d656e74616cf50037")! let web3 = try await Web3.new(LocalTestCase.url) - let allAddresses = try await web3.eth.ownedAccounts() - var contract = web3.contract(abiString, at: nil, abiVersion: 2)! - - let parameters: [Any] = [] - // MARK: Writing Data flow - let deployTx = contract.prepareDeploy(bytecode: bytecode, parameters: parameters)! - deployTx.transaction.from = allAddresses[0] - let policies = Policies(gasLimitPolicy: .manual(3000000)) - let result = try await deployTx.writeToChain(password: "web3swift", policies: policies, sendRaw: false) - let txHash = result.hash.stripHexPrefix() - - Thread.sleep(forTimeInterval: 1.0) - - let receipt = try await web3.eth.transactionReceipt(Data.fromHex(txHash)!) + let receipt = try await deployContract(bytecode: bytecode, abiString: abiString) switch receipt.status { case .notYetProcessed: @@ -140,11 +88,11 @@ class AdvancedABIv2Tests: LocalTestCase { break } - contract = web3.contract(abiString, at: receipt.contractAddress, abiVersion: 2)! + let contract = web3.contract(abiString, at: receipt.contractAddress, abiVersion: 2)! // MARK: Read data from ABI flow // MARK: - Encoding ABI Data flow let tx = contract.createReadOperation("testDynOfDyn") - _ = try await tx!.callContractMethod() + _ = try await tx!.call() } func testAdvancedABIv2staticArrayOfStrings() async throws { @@ -152,20 +100,7 @@ class AdvancedABIv2Tests: LocalTestCase { let bytecode = Data.fromHex("6080604052341561000f57600080fd5b610cb18061001e6000396000f30060806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063189533931461007257806338163ff51461009b57806388be6c65146100c4578063e7c1a47c146100ed578063f376e01314610116575b600080fd5b341561007d57600080fd5b61008561013f565b6040516100929190610a9f565b60405180910390f35b34156100a657600080fd5b6100ae610220565b6040516100bb9190610a7d565b60405180910390f35b34156100cf57600080fd5b6100d76102c5565b6040516100e49190610ae3565b60405180910390f35b34156100f857600080fd5b610100610350565b60405161010d9190610ac1565b60405180910390f35b341561012157600080fd5b610129610399565b6040516101369190610b05565b60405180910390f35b6060600260405190808252806020026020018201604052801561017657816020015b60608152602001906001900390816101615790505b5090506040805190810160405280600581526020017f48656c6c6f0000000000000000000000000000000000000000000000000000008152508160008151811015156101be57fe5b906020019060200201819052506040805190810160405280600581526020017f576f726c6400000000000000000000000000000000000000000000000000000081525081600181518110151561021057fe5b9060200190602002018190525090565b610228610546565b6040805190810160405280600581526020017f48656c6c6f00000000000000000000000000000000000000000000000000000081525081600060028110151561026d57fe5b60200201819052506040805190810160405280600581526020017f576f726c640000000000000000000000000000000000000000000000000000008152508160016002811015156102ba57fe5b602002018190525090565b6060600260405190808252806020026020018201604052801561030257816020015b6102ef61056d565b8152602001906001900390816102e75790505b50905061030d610399565b81600081518110151561031c57fe5b90602001906020020181905250610331610399565b81600181518110151561034057fe5b9060200190602002018190525090565b6103586105a9565b610360610399565b81600060028110151561036f57fe5b602002018190525061037f610399565b81600160028110151561038e57fe5b602002018190525090565b6103a16105d8565b60606103ab610614565b6103b3610546565b60036040519080825280602002602001820160405280156103e35781602001602082028038833980820191505090505b50925060008360008151811015156103f757fe5b9060200190602002018181525050600183600181518110151561041657fe5b9060200190602002018181525050600283600281518110151561043557fe5b90602001906020020181815250506040805190810160405280600081526020016001815250915060408051908101604052806040805190810160405280600581526020017f48656c6c6f00000000000000000000000000000000000000000000000000000081525081526020016040805190810160405280600581526020017f576f726c64000000000000000000000000000000000000000000000000000000815250815250905060a060405190810160405280600181526020016040805190810160405280600b81526020017f48656c6c6f20776f726c64000000000000000000000000000000000000000000815250815260200183815260200184815260200182815250935083935050505090565b60408051908101604052806002905b60608152602001906001900390816105555790505090565b60e060405190810160405280600081526020016060815260200161058f610636565b8152602001606081526020016105a3610658565b81525090565b6101c0604051908101604052806002905b6105c261056d565b8152602001906001900390816105ba5790505090565b60e06040519081016040528060008152602001606081526020016105fa610636565b81526020016060815260200161060e610658565b81525090565b6040805190810160405280600290602082028038833980820191505090505090565b6040805190810160405280600290602082028038833980820191505090505090565b60408051908101604052806002905b60608152602001906001900390816106675790505090565b600061068a82610b81565b8360208202850161069a85610b31565b60005b848110156106d35783830388526106b5838351610930565b92506106c082610bdb565b915060208801975060018101905061069d565b508196508694505050505092915050565b60006106ef82610b76565b836020820285016106ff85610b27565b60005b8481101561073857838303885261071a838351610930565b925061072582610bce565b9150602088019750600181019050610702565b508196508694505050505092915050565b600061075482610b8c565b8084526020840193508360208202850161076d85610b3b565b60005b848110156107a6578383038852610788838351610930565b925061079382610be8565b9150602088019750600181019050610770565b508196508694505050505092915050565b60006107c282610b97565b836020820285016107d285610b48565b60005b8481101561080b5783830388526107ed8383516109ea565b92506107f882610bf5565b91506020880197506001810190506107d5565b508196508694505050505092915050565b600061082782610ba2565b8084526020840193508360208202850161084085610b52565b60005b8481101561087957838303885261085b8383516109ea565b925061086682610c02565b9150602088019750600181019050610843565b508196508694505050505092915050565b61089381610bad565b61089c82610b5f565b60005b828110156108ce576108b2858351610a6e565b6108bb82610c0f565b915060208501945060018101905061089f565b5050505050565b60006108e082610bb8565b8084526020840193506108f283610b69565b60005b8281101561092457610908868351610a6e565b61091182610c1c565b91506020860195506001810190506108f5565b50849250505092915050565b600061093b82610bc3565b80845261094f816020860160208601610c33565b61095881610c66565b602085010191505092915050565b600060c08301600083015161097e6000860182610a6e565b50602083015184820360208601526109968282610930565b91505060408301516109ab604086018261088a565b50606083015184820360808601526109c382826108d5565b915050608083015184820360a08601526109dd82826106e4565b9150508091505092915050565b600060c083016000830151610a026000860182610a6e565b5060208301518482036020860152610a1a8282610930565b9150506040830151610a2f604086018261088a565b5060608301518482036080860152610a4782826108d5565b915050608083015184820360a0860152610a6182826106e4565b9150508091505092915050565b610a7781610c29565b82525050565b60006020820190508181036000830152610a97818461067f565b905092915050565b60006020820190508181036000830152610ab98184610749565b905092915050565b60006020820190508181036000830152610adb81846107b7565b905092915050565b60006020820190508181036000830152610afd818461081c565b905092915050565b60006020820190508181036000830152610b1f8184610966565b905092915050565b6000819050919050565b6000819050919050565b6000602082019050919050565b6000819050919050565b6000602082019050919050565b6000819050919050565b6000602082019050919050565b600060029050919050565b600060029050919050565b600081519050919050565b600060029050919050565b600081519050919050565b600060029050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000819050919050565b60005b83811015610c51578082015181840152602081019050610c36565b83811115610c60576000848401525b50505050565b6000601f19601f83011690509190505600a265627a7a72305820fdaf8ce6fe282a46498c8066d5b5ac382b69969eee38e1ad03c0d501b27f65366c6578706572696d656e74616cf50037")! let web3 = try await Web3.new(LocalTestCase.url) - let allAddresses = try await web3.eth.ownedAccounts() - var contract = web3.contract(abiString, at: nil, abiVersion: 2)! - - let parameters: [Any] = [] - // MARK: Writing Data flow - let deployTx = contract.prepareDeploy(bytecode: bytecode, parameters: parameters)! - deployTx.transaction.from = allAddresses[0] - let policies = Policies(gasLimitPolicy: .manual(3000000)) - let result = try await deployTx.writeToChain(password: "web3swift", policies: policies, sendRaw: false) - let txHash = result.hash.stripHexPrefix() - - Thread.sleep(forTimeInterval: 1.0) - - let receipt = try await web3.eth.transactionReceipt(Data.fromHex(txHash)!) + let receipt = try await deployContract(bytecode: bytecode, abiString: abiString) switch receipt.status { case .notYetProcessed: @@ -174,16 +109,18 @@ class AdvancedABIv2Tests: LocalTestCase { break } - contract = web3.contract(abiString, at: receipt.contractAddress, abiVersion: 2)! + let contract = web3.contract(abiString, at: receipt.contractAddress, abiVersion: 2)! // MARK: Read data from ABI flow // MARK: - Encoding ABI Data flow let tx = contract.createReadOperation("testStOfDyn") - _ = try await tx!.callContractMethod() + _ = try await tx!.call() } func testEmptyArrayDecoding() async throws { + let bytecode = Data(hex: "608060405234801561001057600080fd5b5061027b806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f2a75fe414610030575b600080fd5b61003861004e565b60405161004591906101e0565b60405180910390f35b60606000600267ffffffffffffffff811115610093577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156100c15781602001602082028036833780820191505090505b509050600181600081518110610100577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050600281600181518110610148577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010181815250508091505090565b600061016783836101d1565b60208301905092915050565b600061017e82610212565b610188818561022a565b935061019383610202565b8060005b838110156101c45781516101ab888261015b565b97506101b68361021d565b925050600181019050610197565b5085935050505092915050565b6101da8161023b565b82525050565b600060208201905081810360008301526101fa8184610173565b905092915050565b6000819050602082019050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600081905091905056fea2646970667358221220d1b52dfe3238df01604ccfbb6c6cee01edbaa74fcffd8a57c4041b0b19e6887664736f6c63430008040033") let abiString = "[{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"constant\":true,\"inputs\":[],\"name\":\"empty\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]" - let contractAddress = EthereumAddress("0x200eb5ccda1c35b0f5bf82552fdd65a8aee98e79")! + let receipt = try await deployContract(bytecode: bytecode, abiString: abiString) + let contractAddress = receipt.contractAddress! let web3 = try await Web3.new(LocalTestCase.url) let contract = web3.contract(abiString, at: contractAddress, abiVersion: 2) XCTAssert(contract != nil) @@ -191,20 +128,31 @@ class AdvancedABIv2Tests: LocalTestCase { // MARK: - Encoding ABI Data flow let tx = contract?.createReadOperation("empty") XCTAssertNotNil(tx) - _ = try await tx!.callContractMethod() + let result = try await tx!.call() + XCTAssertEqual(result.count, 1) + XCTAssertEqual((result["0"] as? Array)?[0], 1) + XCTAssertEqual((result["0"] as? Array)?[1], 2) } func testUserCase() async throws { + let bytecode = Data(hex: "0x608060405234801561001057600080fd5b50610484806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063a16e94bf1461003b578063a46b5b6b14610059575b600080fd5b610043610075565b60405161005091906102a6565b60405180910390f35b610073600480360381019061006e919061022c565b610107565b005b6060600080546100849061037c565b80601f01602080910402602001604051908101604052809291908181526020018280546100b09061037c565b80156100fd5780601f106100d2576101008083540402835291602001916100fd565b820191906000526020600020905b8154815290600101906020018083116100e057829003601f168201915b5050505050905090565b806000908051906020019061011d929190610121565b5050565b82805461012d9061037c565b90600052602060002090601f01602090048101928261014f5760008555610196565b82601f1061016857805160ff1916838001178555610196565b82800160010185558215610196579182015b8281111561019557825182559160200191906001019061017a565b5b5090506101a391906101a7565b5090565b5b808211156101c05760008160009055506001016101a8565b5090565b60006101d76101d2846102ed565b6102c8565b9050828152602081018484840111156101ef57600080fd5b6101fa84828561033a565b509392505050565b600082601f83011261021357600080fd5b81356102238482602086016101c4565b91505092915050565b60006020828403121561023e57600080fd5b600082013567ffffffffffffffff81111561025857600080fd5b61026484828501610202565b91505092915050565b60006102788261031e565b6102828185610329565b9350610292818560208601610349565b61029b8161043d565b840191505092915050565b600060208201905081810360008301526102c0818461026d565b905092915050565b60006102d26102e3565b90506102de82826103ae565b919050565b6000604051905090565b600067ffffffffffffffff8211156103085761030761040e565b5b6103118261043d565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b82818337600083830152505050565b60005b8381101561036757808201518184015260208101905061034c565b83811115610376576000848401525b50505050565b6000600282049050600182168061039457607f821691505b602082108114156103a8576103a76103df565b5b50919050565b6103b78261043d565b810181811067ffffffffffffffff821117156103d6576103d561040e565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f830116905091905056fea2646970667358221220264496be069122017e0e6bd1c3b06e335df83ac7d058c0063a81e9227786693564736f6c63430008040033") let abiString = "[{\"constant\":true,\"inputs\":[],\"name\":\"getFlagData\",\"outputs\":[{\"name\":\"data\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"data\",\"type\":\"string\"}],\"name\":\"setFlagData\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" - let contractAddress = EthereumAddress("0x811411e3cdfd4750cdd3552feb3b89a46ddb612e") - let web3 = try await Web3.new(LocalTestCase.url) + let receipt = try await deployContract(bytecode: bytecode, abiString: abiString) + let contractAddress = receipt.contractAddress! + let web3 = try await Web3(provider: Web3HttpProvider(url: LocalTestCase.url, network: nil)) let contract = web3.contract(abiString, at: contractAddress, abiVersion: 2) XCTAssert(contract != nil) + let allAddresses = try await web3.eth.ownedAccounts() + let balance = try await web3.eth.getBalance(for: allAddresses[0]) + let writeOperation = contract?.createWriteOperation("setFlagData", parameters: ["abcdefg"]) + writeOperation?.transaction.from = allAddresses[0] + _ = try await writeOperation?.writeToChain(password: "web3swift", policies: Policies(gasLimitPolicy: .manual(3000000)), sendRaw: false) // MARK: Read data from ABI flow // MARK: - Encoding ABI Data flow let tx = contract?.createReadOperation("getFlagData") XCTAssertNotNil(tx) - _ = try await tx!.callContractMethod() + let result = try await tx!.call() + XCTAssertEqual(result["0"] as? String, "abcdefg") } } diff --git a/Tests/web3swiftTests/localTests/ERC20Tests.swift b/Tests/web3swiftTests/localTests/ERC20Tests.swift index f569640b5..abbb0c436 100755 --- a/Tests/web3swiftTests/localTests/ERC20Tests.swift +++ b/Tests/web3swiftTests/localTests/ERC20Tests.swift @@ -16,7 +16,7 @@ class ERC20Tests: LocalTestCase { let contract = web3.contract(Web3.Utils.erc20ABI, at: receipt.contractAddress!)! let readTX = contract.createReadOperation("name")! readTX.transaction.from = EthereumAddress("0xe22b8979739D724343bd002F9f432F5990879901") - let response = try await readTX.callContractMethod() + let response = try await readTX.call() let name = response["0"] as? String XCTAssert(name == "web3swift", "Failed to create ERC20 name transaction") } @@ -28,7 +28,7 @@ class ERC20Tests: LocalTestCase { let contract = web3.contract(Web3.Utils.erc20ABI, at: receipt.contractAddress!, abiVersion: 2)! guard let readTX = contract.createReadOperation("balanceOf", parameters: [addressOfUser]) else { return XCTFail() } readTX.transaction.from = addressOfUser - let tokenBalanceResponse = try await readTX.callContractMethod() + let tokenBalanceResponse = try await readTX.call() XCTAssertNotNil(tokenBalanceResponse["0"] as? BigUInt) } diff --git a/Tests/web3swiftTests/localTests/LocalTestCase.swift b/Tests/web3swiftTests/localTests/LocalTestCase.swift index 7b79589c4..707fbde93 100644 --- a/Tests/web3swiftTests/localTests/LocalTestCase.swift +++ b/Tests/web3swiftTests/localTests/LocalTestCase.swift @@ -31,4 +31,21 @@ class LocalTestCase: XCTestCase { _ = try! await writeTX.writeToChain(password: "", policies: policies, sendRaw: false) } } + + func deployContract(bytecode: Data, abiString: String) async throws -> TransactionReceipt { + let web3 = try await Web3.new(LocalTestCase.url) + let allAddresses = try await web3.eth.ownedAccounts() + var contract = web3.contract(abiString, at: nil, abiVersion: 2)! + + let parameters: [Any] = [] + // MARK: Writing Data flow + let deployTx = contract.prepareDeploy(bytecode: bytecode, parameters: parameters)! + deployTx.transaction.from = allAddresses[0] + let policies = Policies(gasLimitPolicy: .manual(3000000)) + let result = try await deployTx.writeToChain(password: "web3swift", policies: policies, sendRaw: false) + let txHash = result.hash.stripHexPrefix() + Thread.sleep(forTimeInterval: 1.0) + let receipt = try await web3.eth.transactionReceipt(Data.fromHex(txHash)!) + return receipt + } } diff --git a/Tests/web3swiftTests/localTests/PersonalSignatureTests.swift b/Tests/web3swiftTests/localTests/PersonalSignatureTests.swift index e8cd5e1ff..e108ac59d 100755 --- a/Tests/web3swiftTests/localTests/PersonalSignatureTests.swift +++ b/Tests/web3swiftTests/localTests/PersonalSignatureTests.swift @@ -21,9 +21,79 @@ class PersonalSignatureTests: XCTestCase { let expectedAddress = keystoreManager.addresses![0] let signature = try await web3.personal.signPersonalMessage(message: message.data(using: .utf8)!, from: expectedAddress, password: "") - let unmarshalledSignature = SECP256K1.unmarshalSignature(signatureData: signature)! let signer = web3.personal.recoverAddress(message: message.data(using: .utf8)!, signature: signature) - XCTAssert(expectedAddress == signer, "Failed to sign personal message") + XCTAssertEqual(expectedAddress, signer, "Failed to sign personal message") + } + + /// This test was created by using Metamask 10.3.0 + /// Source: https://github.com/NomicFoundation/hardhat/pull/2009/files#diff-c5f213b3ca761cf1b580355b76fc841122e29cc7f378cb35ffec2949db9e237aR592 + func testPersonalSignatureCompatibleWithMetaMask() async throws { + let privateKey = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" + let messageToSign = "0x7699f568ecd7753e6ddf75a42fa4c2cc86cbbdc704c9eb1a6b6d4b9d8b8d1519" + let expectedSignature = "2875e4206c9fe3b229291c81f95cc4f421e2f4d3e023f5b4041daa56ab4000977010b47a3c01036ec8a6a0872aec2ab285150f003d01b0d8da60c1cceb9154181c" + + let keystore = try! EthereumKeystoreV3(privateKey: Data.fromHex(privateKey)!, password: "")! + let address = keystore.addresses!.first! + let signature = try Web3Signer.signPersonalMessage(Data.fromHex(messageToSign)!, + keystore: keystore, + account: address, + password: "") + XCTAssertNotNil(signature) + XCTAssertEqual(signature?.toHexString(), expectedSignature) + } + + func testPersonalSignatureCompatibleWithMetaMaskv11_5_1() async throws { + let privateKey = "0xbb5bbb5c11112bf637cca88d3612db25202a6e68df28f15ed7118c6a006c2938" + let messageToSign = "Example `personal_sign` message" + let expectedSignature = "24fef5a5d3757929a8782a96c9df2fa30cf39db52cd56c54fd42f17c6325fff220d1e2028f3c4426a66e8b8e665bff7b45f0766df4a12c9c9c59262d6efe9a6b1b" + let keystore = try! EthereumKeystoreV3(privateKey: Data.fromHex(privateKey)!, password: "")! + let address = EthereumAddress("0xeee666c6625aec1807a035b1815264fed21ac566")! + let signature = try Web3Signer.signPersonalMessage(messageToSign.data(using: .utf8)!, + keystore: keystore, + account: address, + password: "") + XCTAssertNotNil(signature) + XCTAssertEqual(signature?.toHexString(), expectedSignature) + } + + /// The same as ``PersonalSignatureTests/testPersonalSignatureCompatibleWithMetaMask`` + func testPersonalSignatureCompatibleWithMetaMaskUsingWeb3Obj() async throws { + let privateKey = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" + let messageToSign = "0x7699f568ecd7753e6ddf75a42fa4c2cc86cbbdc704c9eb1a6b6d4b9d8b8d1519" + let expectedSignature = "2875e4206c9fe3b229291c81f95cc4f421e2f4d3e023f5b4041daa56ab4000977010b47a3c01036ec8a6a0872aec2ab285150f003d01b0d8da60c1cceb9154181c" + + let web3 = try await Web3.new(LocalTestCase.url) + let keystore = try! EthereumKeystoreV3(privateKey: Data.fromHex(privateKey)!, password: "")! + let keystoreManager = KeystoreManager([keystore]) + web3.addKeystoreManager(keystoreManager) + let expectedAddress = keystoreManager.addresses![0] + + let signature = try await web3.personal.signPersonalMessage(message: Data.fromHex(messageToSign)!, from: expectedAddress, password: "") + // ATTENTION: web3.wallet.signPersonalMessage accepts a raw string + // ATTENTION: instead of the message hash but expects it to be + // ATTENTION: 'string' -> to 'UTF-8 bytes' -> to hex string converted! + let signature_walletObj = try web3.wallet.signPersonalMessage(messageToSign, account: expectedAddress, password: "") + let signer = web3.personal.recoverAddress(message: Data.fromHex(messageToSign)!, signature: signature) + + XCTAssertEqual(expectedAddress, signer, "Failed to sign personal message") + XCTAssertNotNil(signature) + XCTAssertEqual(signature.toHexString(), expectedSignature) + XCTAssertEqual(signature_walletObj.toHexString(), expectedSignature) + } + + /// Source: https://github.com/NomicFoundation/hardhat/pull/2009/files#diff-c5f213b3ca761cf1b580355b76fc841122e29cc7f378cb35ffec2949db9e237aR592 + func testPersonalSignatureCompatibleWithGeth() async throws { + let privateKey = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" + let messageToSign = "0x5417aa2a18a44da0675524453ff108c545382f0d7e26605c56bba47c21b5e979" + let expectedSignature = "9c73dd4937a37eecab3abb54b74b6ec8e500080431d36afedb1726624587ee6710296e10c1194dded7376f13ff03ef6c9e797eb86bae16c20c57776fc69344271c" + + let keystore = try! EthereumKeystoreV3(privateKey: Data.fromHex(privateKey)!, password: "")! + let signature = try Web3Signer.signPersonalMessage(Data.fromHex(messageToSign)!, + keystore: keystore, + account: keystore.addresses!.first!, + password: "") + XCTAssertNotNil(signature) + XCTAssertEqual(signature?.toHexString(), expectedSignature) } // TODO: - write contract @@ -66,13 +136,13 @@ class PersonalSignatureTests: XCTestCase { contract = web3.contract(abiString, at: receipt.contractAddress!)! var tx = contract.createReadOperation("hashPersonalMessage", parameters: [message]) tx?.transaction.from = expectedAddress - var result = try await tx!.callContractMethod() + var result = try await tx!.call() guard let hash = result["hash"]! as? Data else { return XCTFail() } XCTAssert(Utilities.hashPersonalMessage(message.data(using: .utf8)!)! == hash) tx = contract.createReadOperation("recoverSigner", parameters: [message, unmarshalledSignature.v, Data(unmarshalledSignature.r), Data(unmarshalledSignature.s)]) tx?.transaction.from = expectedAddress - result = try await tx!.callContractMethod() + result = try await tx!.call() guard let signer = result["signer"]! as? EthereumAddress else { return XCTFail() } XCTAssert(signer == expectedAddress) } diff --git a/Tests/web3swiftTests/localTests/String+ExtensionTests.swift.swift b/Tests/web3swiftTests/localTests/String+ExtensionTests.swift.swift new file mode 100644 index 000000000..1a6686178 --- /dev/null +++ b/Tests/web3swiftTests/localTests/String+ExtensionTests.swift.swift @@ -0,0 +1,31 @@ +// +// String+ExtensionTests.swift +// +// Created by JeneaVranceanu on 26.11.2023. +// + +import Foundation +import XCTest + +class StringExtensionsTest: XCTestCase { + + func testIsHex() throws { + XCTAssertTrue("0x".isHex) + XCTAssertTrue("0xF".isHex) + XCTAssertTrue("F".isHex) + XCTAssertTrue("0xFF".isHex) + XCTAssertTrue("0x0123456789abcdefABCDEF".isHex) + XCTAssertTrue("0123456789abcdefABCDEF".isHex) + XCTAssertTrue("0123456789abcdefABCDEF ".isHex) + XCTAssertTrue(" 0123456789abcdefABCDEF ".isHex) + XCTAssertTrue(" 0123456789abcdefABCDEF".isHex) + + XCTAssertFalse("".isHex) + XCTAssertFalse("-".isHex) + XCTAssertFalse("xyz".isHex) + XCTAssertFalse("0xCAFEQ".isHex) + XCTAssertFalse("R0123456789abcdefABCDEF ".isHex) + XCTAssertFalse(" R0123456789abcdefABCDEF ".isHex) + } + +} diff --git a/Tests/web3swiftTests/localTests/UncategorizedTests.swift b/Tests/web3swiftTests/localTests/UncategorizedTests.swift index 82917d4dc..4d076fdec 100755 --- a/Tests/web3swiftTests/localTests/UncategorizedTests.swift +++ b/Tests/web3swiftTests/localTests/UncategorizedTests.swift @@ -10,7 +10,7 @@ import BigInt @testable import Web3Core @testable import web3swift -class UncategorizedTests: XCTestCase { +class UncategorizedTests: LocalTestCase { func testBitFunctions () throws { let data = Data([0xf0, 0x02, 0x03]) let firstBit = data.bitsInRange(0, 1) @@ -120,24 +120,27 @@ class UncategorizedTests: XCTestCase { // } func testPublicMappingsAccess() async throws { + let bytecode = Data(hex: "0x608060405234801561001057600080fd5b5061023d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063365b98b2146100465780635e79ab6014610076578063bff1f9e1146100a6575b600080fd5b610060600480360381019061005b919061014a565b6100c4565b60405161006d9190610182565b60405180910390f35b610090600480360381019061008b9190610121565b6100ce565b60405161009d9190610182565b60405180910390f35b6100ae6100ee565b6040516100bb9190610182565b60405180910390f35b6000819050919050565b60008173ffffffffffffffffffffffffffffffffffffffff169050919050565b60006064905090565b600081359050610106816101d9565b92915050565b60008135905061011b816101f0565b92915050565b60006020828403121561013357600080fd5b6000610141848285016100f7565b91505092915050565b60006020828403121561015c57600080fd5b600061016a8482850161010c565b91505092915050565b61017c816101cf565b82525050565b60006020820190506101976000830184610173565b92915050565b60006101a8826101af565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6101e28161019d565b81146101ed57600080fd5b50565b6101f9816101cf565b811461020457600080fd5b5056fea26469706673582212207373b0db986284793522a82bff7bf03e30323defa94e6d25f7141e7d63e1ee0564736f6c63430008040033") let jsonString = "[{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"users\",\"outputs\":[{\"name\":\"name\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"userDeviceCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalUsers\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]" + let receipt = try await deployContract(bytecode: bytecode, abiString: jsonString) let web3 = try await Web3.new(LocalTestCase.url) - guard let addr = EthereumAddress("0xdef61132a0c1259464b19e4590e33666aae38574") else {return XCTFail()} - let contract = web3.contract(jsonString, at: addr, abiVersion: 2) - XCTAssert(contract != nil) - let allMethods = contract!.contract.allMethods + guard let addr = receipt.contractAddress else {return XCTFail()} + let contract = web3.contract(jsonString, at: receipt.contractAddress!, abiVersion: 2) + let userDeviceCount = try await contract! .createReadOperation("userDeviceCount", parameters: [addr])? - .callContractMethod() + .call() let totalUsers = try await contract! .createReadOperation("totalUsers")? - .callContractMethod() + .call() let user = try await contract! .createReadOperation("users", parameters: [0])? - .callContractMethod() - + .call() + XCTAssertEqual((userDeviceCount?["0"] as? BigUInt)?.hexString.lowercased(), addr.address.lowercased()) + XCTAssertEqual(totalUsers?["0"] as? BigUInt, 100) + XCTAssertEqual(user?["0"] as? BigUInt, 0) } func testBloomFilterPerformance() throws { diff --git a/Tests/web3swiftTests/localTests/UserCases.swift b/Tests/web3swiftTests/localTests/UserCases.swift index faa903d4d..0a25f41ca 100755 --- a/Tests/web3swiftTests/localTests/UserCases.swift +++ b/Tests/web3swiftTests/localTests/UserCases.swift @@ -24,7 +24,7 @@ class UserCases: XCTestCase { let contract = web3.contract(abiString, at: receipt.contractAddress!)! let readTransaction = contract.createReadOperation("balanceOf", parameters: [account])! readTransaction.transaction.from = account - let response = try await readTransaction.callContractMethod() + let response = try await readTransaction.call() let balance = response["0"] as? BigUInt } diff --git a/Tests/web3swiftTests/localTests/UtilitiesTests.swift b/Tests/web3swiftTests/localTests/UtilitiesTests.swift index 4780805b0..057d99be2 100644 --- a/Tests/web3swiftTests/localTests/UtilitiesTests.swift +++ b/Tests/web3swiftTests/localTests/UtilitiesTests.swift @@ -82,4 +82,9 @@ class UtilitiesTests: XCTestCase { address = Utilities.publicToAddress(Data.fromHex("0x0852972572d465d016d4c501887b8df303eee3ed602c056b1eb09260dfa0da0ab2")!)?.address XCTAssertEqual(address, nil) } + + func testStringIsHex() { + XCTAssertTrue("1234567890abcdef".isHex) + XCTAssertFalse("ghijklmn".isHex) + } } diff --git a/Tests/web3swiftTests/remoteTests/DecodeRemoteErrorTests.swift b/Tests/web3swiftTests/remoteTests/DecodeRemoteErrorTests.swift new file mode 100644 index 000000000..ed5a48bf2 --- /dev/null +++ b/Tests/web3swiftTests/remoteTests/DecodeRemoteErrorTests.swift @@ -0,0 +1,53 @@ +// +// DecodeRemoteErrorTests.swift +// +// Created by liugang zhang on 2023/8/25. +// + +import XCTest +import Web3Core + +@testable import web3swift + +final class DecodeRemoteErrorTests: XCTestCase { + + let entryPoint = EthereumAddress("0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789")! + let factory = EthereumAddress("0x9406Cc6185a346906296840746125a0E44976454")! + let address = EthereumAddress("0x581074D2d9e50913eB37665b07CAFa9bFFdd1640")! + + func testDecodeRemoteFunc() async throws { + let web3 = try await Web3.InfuraMainnetWeb3(accessToken: Constants.infuraToken) + + let entryABI = try EthereumContract(abi: [ + .error(.init(name: "SenderAddressResult", + inputs: [.init(name: "sender", type: .address)])), + .function(.init(name: "getSenderAddress", + inputs: [.init(name: "initCode", type: .dynamicBytes)], + outputs: [], + constant: false, + payable: false)) + ], at: entryPoint) + + let factoryABI = try EthereumContract(abi: [ + .function(.init(name: "createAccount", + inputs: [ + .init(name: "owner", type: .address), + .init(name: "salt", type: .uint(bits: 256)) + ], + outputs: [], + constant: false, + payable: false)) + ]) + + let initCode = factory.addressData + factoryABI.method("createAccount", parameters: [address, 0], extraData: nil)! + + do { + try await entryABI.callStatic("getSenderAddress", parameters: [initCode], provider: web3.provider) + XCTFail() + } catch Web3Error.revertCustom(let signature, let args) { + XCTAssertEqual(signature, "SenderAddressResult(address)") + XCTAssertEqual((args["sender"] as? EthereumAddress)?.address, "0x9CF91286f22a1b799770fB5De0E66f3C4cc165d1") + XCTAssertEqual((args["0"] as? EthereumAddress)?.address, "0x9CF91286f22a1b799770fB5De0E66f3C4cc165d1") + } + } +} diff --git a/Tests/web3swiftTests/remoteTests/InfuraTests.swift b/Tests/web3swiftTests/remoteTests/InfuraTests.swift index fec9289ef..da1cdf412 100755 --- a/Tests/web3swiftTests/remoteTests/InfuraTests.swift +++ b/Tests/web3swiftTests/remoteTests/InfuraTests.swift @@ -10,7 +10,6 @@ import Web3Core // MARK: Works only with network connection class InfuraTests: XCTestCase { - func testGetBalance() async throws { let web3 = try await Web3.InfuraMainnetWeb3(accessToken: Constants.infuraToken) let address = EthereumAddress("0xd61b5ca425F8C8775882d4defefC68A6979DBbce")! diff --git a/Tests/web3swiftTests/remoteTests/Web3HttpProviderTests.swift b/Tests/web3swiftTests/remoteTests/Web3HttpProviderTests.swift new file mode 100644 index 000000000..b2a5e144b --- /dev/null +++ b/Tests/web3swiftTests/remoteTests/Web3HttpProviderTests.swift @@ -0,0 +1,33 @@ +// +// Web3HttpProviderTests.swift +// +// +// Created by liugang zhang on 2023/9/2. +// + +import XCTest +import Web3Core + +@testable import web3swift + +final class Web3HttpProviderTests: XCTestCase { + + /// if one of these rpc server lose efficacy, find a substitution from https://chainlist.org/ + func testGetNetwork() async throws { + let requestURLstring = "https://" + Networks.Mainnet.name + Constants.infuraHttpScheme + Constants.infuraToken + var web3 = try await Web3HttpProvider(url: URL(string: requestURLstring)!, network: nil) + XCTAssertEqual(web3.network?.chainID, 1) + + web3 = try await Web3HttpProvider(url: URL(string: "https://arbitrum-one.publicnode.com")!, network: nil) + XCTAssertEqual(web3.network?.chainID, 42161) + + web3 = try await Web3HttpProvider(url: URL(string: "https://rpc.ankr.com/bsc")!, network: nil) + XCTAssertEqual(web3.network?.chainID, 56) + + web3 = try await Web3HttpProvider(url: URL(string: "https://rpc-mainnet.maticvigil.com/")!, network: nil) + XCTAssertEqual(web3.network?.chainID, 137) + + web3 = try await Web3HttpProvider(url: URL(string: "https://optimism.gateway.tenderly.co")!, network: nil) + XCTAssertEqual(web3.network?.chainID, 10) + } +} diff --git a/Web3Core.podspec b/Web3Core.podspec deleted file mode 100644 index 0da2cabc9..000000000 --- a/Web3Core.podspec +++ /dev/null @@ -1,19 +0,0 @@ -Pod::Spec.new do |spec| - spec.compiler_flags = '-DCOCOAPODS' - - spec.name = 'Web3Core' - spec.version = '3.1.1' - spec.ios.deployment_target = "13.0" - spec.osx.deployment_target = "10.15" - spec.license = { :type => 'Apache License 2.0', :file => 'LICENSE.md' } - spec.summary = 'Core of web3swift library' - spec.homepage = 'https://github.com/web3swift-team/web3swift' - spec.author = {"Alex Vlasov" => "alex.m.vlasov@gmail.com", "Anton Grigorev" => "antongrigorjev2010@gmail.com", "Petr Korolev" => "sky4winder@gmail.com", "Yaroslav Yashin" => "yaroslav.yashin@gmail.com"} - spec.source = { :git => 'https://github.com/web3swift-team/web3swift.git', :tag => spec.version.to_s } - spec.swift_version = '5.5' - - spec.dependency 'secp256k1.c', '~> 0.1' - spec.dependency 'BigInt', '~> 5.2.0' # no newer version in pods. - spec.dependency 'CryptoSwift', '~> 1.5.1' - spec.source_files = "Sources/Web3Core/**/*.swift" -end diff --git a/web3swift.podspec b/web3swift.podspec deleted file mode 100755 index 50da01f53..000000000 --- a/web3swift.podspec +++ /dev/null @@ -1,22 +0,0 @@ -WEB3CORE_VERSION ||= '3.1.1' - -Pod::Spec.new do |spec| - spec.name = 'web3swift' - spec.version = WEB3CORE_VERSION - spec.ios.deployment_target = "13.0" - spec.osx.deployment_target = "10.15" - spec.license = { :type => 'Apache License 2.0', :file => 'LICENSE.md' } - spec.summary = 'Web3 implementation in vanilla Swift for iOS, macOS, and Linux' - spec.homepage = 'https://github.com/web3swift-team/web3swift' - spec.author = {"Alex Vlasov" => "alex.m.vlasov@gmail.com", "Anton Grigorev" => "antongrigorjev2010@gmail.com", "Petr Korolev" => "sky4winder@gmail.com", "Yaroslav Yashin" => "yaroslav.yashin@gmail.com"} - spec.source = { :git => 'https://github.com/web3swift-team/web3swift.git', :tag => spec.version.to_s } - spec.swift_version = '5.5' - - # Make this line same as Web3Core sources - spec.source_files = "Sources/web3swift/**/*.swift" - spec.ios.source_files = 'Sources/web3swift/Browser/*.swift' - spec.resource_bundle = { "Browser" => "Sources/web3swift/Browser/*.js" } - spec.frameworks = 'CoreImage' - spec.dependency 'Starscream', '~> 4.0.4' - spec.dependency 'Web3Core', "~> #{WEB3CORE_VERSION}" -end