Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.6.1 Release #533

Merged
merged 17 commits into from
Apr 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 13 additions & 7 deletions Documentation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,35 +74,41 @@ Here are quick references for essential features:

- [x] [EIP-155](https://github.com/ethereum/EIPs/blob/develop/EIPS/eip-155.md) (Replay attacks protection) *enforced!*

- [x] [EIP-165](https://github.com/ethereum/EIPs/blob/develop/EIPS/eip-165.md) (Standard Interface Detection, also known as ERC-165)

- [x] [EIP-681](https://github.com/ethereum/EIPs/blob/develop/EIPS/eip-681.md) (A standard way of representing various transactions, especially payment requests in Ethers and ERC-20 tokens as URLs)

- [x] [EIP-721](https://github.com/ethereum/EIPs/blob/develop/EIPS/eip-721.md) (A standard interface for non-fungible tokens, also known as deeds - ERC-721)

- [x] [EIP-165](https://github.com/ethereum/EIPs/blob/develop/EIPS/eip-165.md) (Standard Interface Detection, also known as ERC-165)
- [x] [EIP-721x](https://github.com/loomnetwork/erc721x) (An extension of ERC721 that adds support for multi-fungible tokens and batch transfers, while being fully backward-compatible, also known as ERC-721x)

- [x] [EIP-777](https://github.com/ethereum/EIPs/blob/develop/EIPS/eip-777.md) (New Advanced Token Standard, also known as ERC-777)

- [x] [EIP-820](https://github.com/ethereum/EIPs/blob/develop/EIPS/eip-820.md) (Pseudo-introspection Registry Contract, also known as ERC-820)

- [x] [EIP-888](https://github.com/ethereum/EIPs/issues/888) (MultiDimensional Token Standard, also known as ERC-888)

- [x] [EIP-1155](https://github.com/ethereum/EIPs/blob/develop/EIPS/eip-1155.md) (Multi Token Standard, also known as ERC-1155)

- [x] [EIP-1376](https://github.com/ethereum/EIPs/issues/1376) (Service-Friendly Token, also known as ERC-1376)

- [x] [EIP-1400](https://github.com/ethereum/EIPs/issues/1411) (Security Token Standard, also known as ERC-1400)

- [x] [EIP-1410](https://github.com/ethereum/EIPs/issues/1410) (Partially Fungible Token Standard, also known as ERC-1410)

- [x] [EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md) (Fee market change for ETH 1.0 chain)

- [x] [EIP-1594](https://github.com/ethereum/EIPs/issues/1594) (Core Security Token Standard, also known as ERC-1594)

- [x] [EIP-1633](https://github.com/ethereum/EIPs/issues/1634) (Re-Fungible Token, also known as ERC-1633)

- [x] [EIP-1643](https://github.com/ethereum/EIPs/issues/1643) (Document Management Standard, also known as ERC-1643)

- [x] [EIP-1644](https://github.com/ethereum/EIPs/issues/1644) (Controller Token Operation Standard, also known as ERC-1644)

- [x] [EIP-1633](https://github.com/ethereum/EIPs/issues/1634) (Re-Fungible Token, also known as ERC-1633)

- [x] [EIP-721x](https://github.com/loomnetwork/erc721x) (An extension of ERC721 that adds support for multi-fungible tokens and batch transfers, while being fully backward-compatible, also known as ERC-721x)

- [x] [EIP-1155](https://github.com/ethereum/EIPs/blob/develop/EIPS/eip-1155.md) (Multi Token Standard, also known as ERC-1155)
- [x] [EIP-2718](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md) (Typed Transaction Envelope)

- [x] [EIP-1376](https://github.com/ethereum/EIPs/issues/1376) (Service-Friendly Token, also known as ERC-1376)
- [x] [EIP-2930](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2930.md) (Optional access lists)

- [x] [ST-20](https://github.com/PolymathNetwork/polymath-core) - ST-20 token is an Ethereum-based token implemented on top of the ERC-20 protocol that adds the ability for tokens to control transfers based on specific rules

Expand Down
35 changes: 35 additions & 0 deletions Documentation/Usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
- [Send ERC-20 Token](#send-erc-20-token)
- [Write Transaction and call smart contract method](#write-transaction-and-call-smart-contract-method)
- [Read Transaction to call smart contract method](#read-transaction-to-call-smart-contract-method)
- [Other Transaction Types (EIP-1559)](#other-transaction-types)
- [Send Transaction](#send-transaction)
- [Write](#write)
- [Read](#read)
Expand Down Expand Up @@ -355,6 +356,40 @@ let result = try! transaction.send(password: password)
let result = try! transaction.call()
```

##### Other Transaction Types

By default a `legacy` transaction will be created which is compatible across all chains, regardless of which fork.
To create one of the new transaction types introduced with the `london` fork you will need to set some additonal parameters
in the `TransactionOptions` object. Note you should only try to send one of tehse new types of transactions if you are on a chain
that supports them.

To send an EIP-2930 style transacton with an access list you need to set the transaction type, and the access list,
in addition what is shown in the examples above.
```swift
let accessList: [AccessListEntry] = [
AccessListEntry(
address: EthereumAddress("0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae"),
storageKeys: [BigUInt(3), BigUInt(7)]
),
AccessListEntry(
address: EthereumAddress("0xbb9bc244d798123fde783fcc1c72d3bb8c189413"),
storageKeys: []
)
]

options.type = .eip2930
options.accessList = accessList
```

To send an EIP-1559 style transaction you set the transaction type, and the new gas parameters `maxFeePerGas` and `maxPriorityFeePerGas`
(you may also send an AccessList with an EIP-1559 transaction) When sending an EIP-1559 transaction, the older `gasPrice` parameter is ignored.
```swift
options.type = .eip1559
options.maxFeePerGas = .manual(...) // the maximum price per unit of gas, inclusive of baseFee and tip
options.maxPriorityFeePerGas = .manual(...) // the tip to be paid to the miner, per unit of gas
```
Note there is a new `Oracle` object available that can be used to assist with estimating the new gas fees

### Chain state

#### Get Block number
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
- [x] ✅**Literally following the standards** (BIP, EIP, etc):

- [x] **[BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) (HD Wallets), [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) (Seed phrases), [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) (Key generation prefixes)**
- [x] **[EIP-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md)** (Standart interface for tokens - ERC-20), **[EIP-67](https://github.com/ethereum/EIPs/issues/67)** (Standard URI scheme), **[EIP-155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md)** (Replay attacks protection)
- [x] **[EIP-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md)** (Standart interface for tokens - ERC-20), **[EIP-67](https://github.com/ethereum/EIPs/issues/67)** (Standard URI scheme), **[EIP-155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md)** (Replay attacks protection), **[EIP-2718](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md)** (Typed Transaction Envelope), **[EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md)** (Gas Fee market change)
- [x] **And many others** *(For details about this EIP's look at [Documentation page](https://github.com/skywinder/web3swift/blob/master/Documentation/))*: EIP-681, EIP-721, EIP-165, EIP-777, EIP-820, EIP-888, EIP-1400, EIP-1410, EIP-1594, EIP-1643, EIP-1644, EIP-1633, EIP-721, EIP-1155, EIP-1376, ST-20

- [x] 🗜 **Batched requests** in concurrent mode
Expand Down
18 changes: 1 addition & 17 deletions Sources/web3swift/Transaction/EIP1559Envelope.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,6 @@ public struct EIP1559Envelope: EIP2718Envelope {
public var maxFeePerGas: BigUInt
public var accessList: [AccessListEntry] // from EIP-2930

/// EIP-1159 trnsactions do not have a gasPrice parameter
/// However, it appears that some nodes report a gasPrice, even for EIP-1159 transactions
/// thus for a temporary workaround we capture and store gasPrice if initialized from a JSON transaction
/// decided form a node. This is currently needed for Oracle to work
private var gasPrice: BigUInt = 0

// for CustomStringConvertible
public var description: String {
var toReturn = ""
Expand Down Expand Up @@ -76,9 +70,6 @@ public struct EIP1559Envelope: EIP2718Envelope {
value: value,
data: data,
gasLimit: gasLimit,
// MARK: workaround for gasPrice coming from nodes for EIP-1159 - this allows Oracle to work for now
gasPrice: gasPrice,

maxFeePerGas: maxFeePerGas,
maxPriorityFeePerGas: maxPriorityFeePerGas,
accessList: accessList
Expand All @@ -94,8 +85,6 @@ public struct EIP1559Envelope: EIP2718Envelope {
maxFeePerGas = val.maxFeePerGas ?? maxFeePerGas
maxPriorityFeePerGas = val.maxPriorityFeePerGas ?? maxPriorityFeePerGas
accessList = val.accessList ?? accessList
// MARK: workaround for gasPrice coming from nodes for EIP-1159 - this allows Oracle to work for now
gasPrice = val.gasPrice ?? gasPrice
}
}

Expand All @@ -117,8 +106,6 @@ extension EIP1559Envelope {
case v
case r
case s
// MARK: workaround for gasPrice coming from nodes for EIP-1159 - this allows Oracle to work for now
case gasPrice
}

public init?(from decoder: Decoder) throws {
Expand Down Expand Up @@ -147,9 +134,6 @@ extension EIP1559Envelope {
self.to = ethAddr
}

// MARK: workaround for gasPrice coming from nodes for EIP-1159 - this allows Oracle to work for now
self.gasPrice = try container.decodeHexIfPresent(BigUInt.self, forKey: .gasPrice) ?? 5000000000

self.value = try container.decodeHexIfPresent(BigUInt.self, forKey: .value) ?? 0
self.maxPriorityFeePerGas = try container.decodeHexIfPresent(BigUInt.self, forKey: .maxPriorityFeePerGas) ?? 0
self.maxFeePerGas = try container.decodeHexIfPresent(BigUInt.self, forKey: .maxFeePerGas) ?? 0
Expand Down Expand Up @@ -212,7 +196,7 @@ extension EIP1559Envelope {

// swiftlint:disable force_unwrapping
switch rlpItem[RlpKey.destination.rawValue]!.content {
// swiftlint:enable force_unwrapping
// swiftlint:enable force_unwrapping
case .noItem:
self.to = EthereumAddress.contractDeploymentAddress()
case .data(let addressData):
Expand Down
57 changes: 57 additions & 0 deletions Sources/web3swift/Transaction/EthereumMetadata.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Package: web3swift
// Created by Alex Vlasov.
// Copyright © 2018 Alex Vlasov. All rights reserved.
//
// Additions for metadata by Mark Loit 2022

import Foundation
import BigInt

/// This structure holds additional data
/// returned by nodes when reading a transaction
/// from the blockchain. The data here is not
/// part of the transaction itself
public struct EthereumMetadata {

/// hash for the block that contains this transaction on chain
var blockHash: Data?

/// block number for the block containing this transaction on chain
var blockNumber: BigUInt?

/// index for this transaction within the containing block
var transactionIndex: UInt?

/// hash for this transaction as returned by the node [not computed]
/// this can be used for validation against the computed hash returned
/// by the transaction envelope.
var transactionHash: Data?

/// gasPrice value returned by the node
/// note this is a duplicate value for legacy and EIP-2930 transaction types
/// but is included here since EIP-1559 does not contain a `gasPrice`, but
/// nodes still report the value.
var gasPrice: BigUInt?
}

public extension EthereumMetadata {
private enum CodingKeys: String, CodingKey {
case blockHash
case blockNumber
case transactionIndex
case transactionHash
case gasPrice
}

/// since metadata realistically can only come when a transaction is created from
/// JSON returned by a node, we only provide an intializer from JSON
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)

self.blockHash = try container.decodeHexIfPresent(Data.self, forKey: .blockHash)
self.transactionHash = try container.decodeHexIfPresent(Data.self, forKey: .transactionHash)
self.transactionIndex = try container.decodeHexIfPresent(UInt.self, forKey: .transactionIndex)
self.blockNumber = try container.decodeHexIfPresent(BigUInt.self, forKey: .blockNumber)
self.gasPrice = try container.decodeHexIfPresent(BigUInt.self, forKey: .gasPrice)
}
}
11 changes: 7 additions & 4 deletions Sources/web3swift/Transaction/EthereumTransaction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ public struct EthereumTransaction: CustomStringConvertible {
/// and type specific implementation
internal var envelope: AbstractEnvelope

/// storage container for additional metadata returned by the node
/// when a transaction is decoded form a JSON stream
public var meta: EthereumMetadata?

// convenience accessors to the common envelope fields
// everything else should come from getOpts/setOpts
/// The type of the transacton being represented, see TransactionType enum
Expand Down Expand Up @@ -227,6 +231,8 @@ extension EthereumTransaction: Decodable {
public init(from decoder: Decoder) throws {
guard let env = try EnvelopeFactory.createEnvelope(from: decoder) else { throw Web3Error.dataError }
self.envelope = env
// capture any metadata that might be present
self.meta = try EthereumMetadata(from: decoder)
}
}

Expand Down Expand Up @@ -330,10 +336,7 @@ extension EthereumTransaction {
guard let env = self.envelope as? EIP2930Envelope else { preconditionFailure("Unable to downcast to EIP2930Envelope") }
return env.parameters.gasPrice ?? 0
case .eip1559:
// MARK: workaround for gasPrice coming from nodes for EIP-1159 - this allows Oracle to work for now
guard let env = self.envelope as? EIP1559Envelope else { preconditionFailure("Unable to downcast to EIP1559Envelope") }
return env.parameters.gasPrice ?? 0
// preconditionFailure("EIP1559Envelope has no member gasPrice")
preconditionFailure("EIP1559Envelope has no member gasPrice")
}
}
set(value) {
Expand Down
2 changes: 1 addition & 1 deletion Sources/web3swift/Web3/Web3+GasOracle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ extension Web3 {
return transaction
}
}
.map { $0.gasPrice }
.map { $0.meta?.gasPrice ?? 0 }

return calculatePercentiles(for: lastNthBlockGasPrice)
}
Expand Down
4 changes: 4 additions & 0 deletions web3swift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@
6049F416280616FC00DFE624 /* LegacyEnvelope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6049F40F280616FC00DFE624 /* LegacyEnvelope.swift */; };
6049F4182806171300DFE624 /* Web3+Signing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6049F4172806171300DFE624 /* Web3+Signing.swift */; };
604FA4FF27ECBDC80021108F /* DataConversionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 604FA4FE27ECBDC80021108F /* DataConversionTests.swift */; };
60C1786E2809BA0C0083F064 /* EthereumMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60C1786D2809BA0C0083F064 /* EthereumMetadata.swift */; };
CB50A52827060BD600D7E39B /* EIP712Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB50A52727060BD600D7E39B /* EIP712Tests.swift */; };
D606A56B279F5D59003643ED /* web3swiftDecodeSolidityErrorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D606A56A279F5D59003643ED /* web3swiftDecodeSolidityErrorType.swift */; };
D6A3D9B827F1E785009E3BCF /* ABIEncoderSoliditySha3Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A3D9B727F1E785009E3BCF /* ABIEncoderSoliditySha3Test.swift */; };
Expand Down Expand Up @@ -433,6 +434,7 @@
6049F40F280616FC00DFE624 /* LegacyEnvelope.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LegacyEnvelope.swift; sourceTree = "<group>"; };
6049F4172806171300DFE624 /* Web3+Signing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Web3+Signing.swift"; sourceTree = "<group>"; };
604FA4FE27ECBDC80021108F /* DataConversionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataConversionTests.swift; sourceTree = "<group>"; };
60C1786D2809BA0C0083F064 /* EthereumMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumMetadata.swift; sourceTree = "<group>"; };
CB50A52727060BD600D7E39B /* EIP712Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EIP712Tests.swift; sourceTree = "<group>"; };
CB50A52927060C5300D7E39B /* EIP712.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EIP712.swift; sourceTree = "<group>"; };
D606A56A279F5D59003643ED /* web3swiftDecodeSolidityErrorType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = web3swiftDecodeSolidityErrorType.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -720,6 +722,7 @@
6049F40F280616FC00DFE624 /* LegacyEnvelope.swift */,
3AA8153D2276E44100F5DB52 /* BloomFilter.swift */,
3AA8153F2276E44100F5DB52 /* EthereumTransaction.swift */,
60C1786D2809BA0C0083F064 /* EthereumMetadata.swift */,
);
path = Transaction;
sourceTree = "<group>";
Expand Down Expand Up @@ -1349,6 +1352,7 @@
3AA815C12276E44100F5DB52 /* Web3+BrowserFunctions.swift in Sources */,
3AA815E82276E44100F5DB52 /* Extensions.swift in Sources */,
3AA815FE2276E44100F5DB52 /* Web3+ERC820.swift in Sources */,
60C1786E2809BA0C0083F064 /* EthereumMetadata.swift in Sources */,
3AA815DB2276E44100F5DB52 /* Web3+TxPool.swift in Sources */,
3AA8160A2276E44100F5DB52 /* Web3+ERC1594.swift in Sources */,
3AA815FB2276E44100F5DB52 /* Promise+Web3+Personal+UnlockAccount.swift in Sources */,
Expand Down