Skip to content

Commit add3342

Browse files
Merge pull request #533 from skywinder/develop
2 parents cbdde45 + 4b4ab1b commit add3342

File tree

8 files changed

+119
-30
lines changed

8 files changed

+119
-30
lines changed

Documentation/README.md

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,35 +74,41 @@ Here are quick references for essential features:
7474

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

77+
- [x] [EIP-165](https://github.com/ethereum/EIPs/blob/develop/EIPS/eip-165.md) (Standard Interface Detection, also known as ERC-165)
78+
7779
- [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)
7880

7981
- [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)
8082

81-
- [x] [EIP-165](https://github.com/ethereum/EIPs/blob/develop/EIPS/eip-165.md) (Standard Interface Detection, also known as ERC-165)
83+
- [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)
8284

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

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

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

91+
- [x] [EIP-1155](https://github.com/ethereum/EIPs/blob/develop/EIPS/eip-1155.md) (Multi Token Standard, also known as ERC-1155)
92+
93+
- [x] [EIP-1376](https://github.com/ethereum/EIPs/issues/1376) (Service-Friendly Token, also known as ERC-1376)
94+
8995
- [x] [EIP-1400](https://github.com/ethereum/EIPs/issues/1411) (Security Token Standard, also known as ERC-1400)
9096

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

99+
- [x] [EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md) (Fee market change for ETH 1.0 chain)
100+
93101
- [x] [EIP-1594](https://github.com/ethereum/EIPs/issues/1594) (Core Security Token Standard, also known as ERC-1594)
94102

103+
- [x] [EIP-1633](https://github.com/ethereum/EIPs/issues/1634) (Re-Fungible Token, also known as ERC-1633)
104+
95105
- [x] [EIP-1643](https://github.com/ethereum/EIPs/issues/1643) (Document Management Standard, also known as ERC-1643)
96106

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

99-
- [x] [EIP-1633](https://github.com/ethereum/EIPs/issues/1634) (Re-Fungible Token, also known as ERC-1633)
100-
101-
- [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)
102-
103-
- [x] [EIP-1155](https://github.com/ethereum/EIPs/blob/develop/EIPS/eip-1155.md) (Multi Token Standard, also known as ERC-1155)
109+
- [x] [EIP-2718](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md) (Typed Transaction Envelope)
104110

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

107113
- [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
108114

Documentation/Usage.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
- [Send ERC-20 Token](#send-erc-20-token)
3333
- [Write Transaction and call smart contract method](#write-transaction-and-call-smart-contract-method)
3434
- [Read Transaction to call smart contract method](#read-transaction-to-call-smart-contract-method)
35+
- [Other Transaction Types (EIP-1559)](#other-transaction-types)
3536
- [Send Transaction](#send-transaction)
3637
- [Write](#write)
3738
- [Read](#read)
@@ -355,6 +356,40 @@ let result = try! transaction.send(password: password)
355356
let result = try! transaction.call()
356357
```
357358

359+
##### Other Transaction Types
360+
361+
By default a `legacy` transaction will be created which is compatible across all chains, regardless of which fork.
362+
To create one of the new transaction types introduced with the `london` fork you will need to set some additonal parameters
363+
in the `TransactionOptions` object. Note you should only try to send one of tehse new types of transactions if you are on a chain
364+
that supports them.
365+
366+
To send an EIP-2930 style transacton with an access list you need to set the transaction type, and the access list,
367+
in addition what is shown in the examples above.
368+
```swift
369+
let accessList: [AccessListEntry] = [
370+
AccessListEntry(
371+
address: EthereumAddress("0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae"),
372+
storageKeys: [BigUInt(3), BigUInt(7)]
373+
),
374+
AccessListEntry(
375+
address: EthereumAddress("0xbb9bc244d798123fde783fcc1c72d3bb8c189413"),
376+
storageKeys: []
377+
)
378+
]
379+
380+
options.type = .eip2930
381+
options.accessList = accessList
382+
```
383+
384+
To send an EIP-1559 style transaction you set the transaction type, and the new gas parameters `maxFeePerGas` and `maxPriorityFeePerGas`
385+
(you may also send an AccessList with an EIP-1559 transaction) When sending an EIP-1559 transaction, the older `gasPrice` parameter is ignored.
386+
```swift
387+
options.type = .eip1559
388+
options.maxFeePerGas = .manual(...) // the maximum price per unit of gas, inclusive of baseFee and tip
389+
options.maxPriorityFeePerGas = .manual(...) // the tip to be paid to the miner, per unit of gas
390+
```
391+
Note there is a new `Oracle` object available that can be used to assist with estimating the new gas fees
392+
358393
### Chain state
359394

360395
#### Get Block number

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
- [x]**Literally following the standards** (BIP, EIP, etc):
5858

5959
- [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)**
60-
- [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)
60+
- [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)
6161
- [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
6262

6363
- [x] 🗜 **Batched requests** in concurrent mode

Sources/web3swift/Transaction/EIP1559Envelope.swift

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,6 @@ public struct EIP1559Envelope: EIP2718Envelope {
4141
public var maxFeePerGas: BigUInt
4242
public var accessList: [AccessListEntry] // from EIP-2930
4343

44-
/// EIP-1159 trnsactions do not have a gasPrice parameter
45-
/// However, it appears that some nodes report a gasPrice, even for EIP-1159 transactions
46-
/// thus for a temporary workaround we capture and store gasPrice if initialized from a JSON transaction
47-
/// decided form a node. This is currently needed for Oracle to work
48-
private var gasPrice: BigUInt = 0
49-
5044
// for CustomStringConvertible
5145
public var description: String {
5246
var toReturn = ""
@@ -76,9 +70,6 @@ public struct EIP1559Envelope: EIP2718Envelope {
7670
value: value,
7771
data: data,
7872
gasLimit: gasLimit,
79-
// MARK: workaround for gasPrice coming from nodes for EIP-1159 - this allows Oracle to work for now
80-
gasPrice: gasPrice,
81-
8273
maxFeePerGas: maxFeePerGas,
8374
maxPriorityFeePerGas: maxPriorityFeePerGas,
8475
accessList: accessList
@@ -94,8 +85,6 @@ public struct EIP1559Envelope: EIP2718Envelope {
9485
maxFeePerGas = val.maxFeePerGas ?? maxFeePerGas
9586
maxPriorityFeePerGas = val.maxPriorityFeePerGas ?? maxPriorityFeePerGas
9687
accessList = val.accessList ?? accessList
97-
// MARK: workaround for gasPrice coming from nodes for EIP-1159 - this allows Oracle to work for now
98-
gasPrice = val.gasPrice ?? gasPrice
9988
}
10089
}
10190

@@ -117,8 +106,6 @@ extension EIP1559Envelope {
117106
case v
118107
case r
119108
case s
120-
// MARK: workaround for gasPrice coming from nodes for EIP-1159 - this allows Oracle to work for now
121-
case gasPrice
122109
}
123110

124111
public init?(from decoder: Decoder) throws {
@@ -147,9 +134,6 @@ extension EIP1559Envelope {
147134
self.to = ethAddr
148135
}
149136

150-
// MARK: workaround for gasPrice coming from nodes for EIP-1159 - this allows Oracle to work for now
151-
self.gasPrice = try container.decodeHexIfPresent(BigUInt.self, forKey: .gasPrice) ?? 5000000000
152-
153137
self.value = try container.decodeHexIfPresent(BigUInt.self, forKey: .value) ?? 0
154138
self.maxPriorityFeePerGas = try container.decodeHexIfPresent(BigUInt.self, forKey: .maxPriorityFeePerGas) ?? 0
155139
self.maxFeePerGas = try container.decodeHexIfPresent(BigUInt.self, forKey: .maxFeePerGas) ?? 0
@@ -212,7 +196,7 @@ extension EIP1559Envelope {
212196

213197
// swiftlint:disable force_unwrapping
214198
switch rlpItem[RlpKey.destination.rawValue]!.content {
215-
// swiftlint:enable force_unwrapping
199+
// swiftlint:enable force_unwrapping
216200
case .noItem:
217201
self.to = EthereumAddress.contractDeploymentAddress()
218202
case .data(let addressData):
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Package: web3swift
2+
// Created by Alex Vlasov.
3+
// Copyright © 2018 Alex Vlasov. All rights reserved.
4+
//
5+
// Additions for metadata by Mark Loit 2022
6+
7+
import Foundation
8+
import BigInt
9+
10+
/// This structure holds additional data
11+
/// returned by nodes when reading a transaction
12+
/// from the blockchain. The data here is not
13+
/// part of the transaction itself
14+
public struct EthereumMetadata {
15+
16+
/// hash for the block that contains this transaction on chain
17+
var blockHash: Data?
18+
19+
/// block number for the block containing this transaction on chain
20+
var blockNumber: BigUInt?
21+
22+
/// index for this transaction within the containing block
23+
var transactionIndex: UInt?
24+
25+
/// hash for this transaction as returned by the node [not computed]
26+
/// this can be used for validation against the computed hash returned
27+
/// by the transaction envelope.
28+
var transactionHash: Data?
29+
30+
/// gasPrice value returned by the node
31+
/// note this is a duplicate value for legacy and EIP-2930 transaction types
32+
/// but is included here since EIP-1559 does not contain a `gasPrice`, but
33+
/// nodes still report the value.
34+
var gasPrice: BigUInt?
35+
}
36+
37+
public extension EthereumMetadata {
38+
private enum CodingKeys: String, CodingKey {
39+
case blockHash
40+
case blockNumber
41+
case transactionIndex
42+
case transactionHash
43+
case gasPrice
44+
}
45+
46+
/// since metadata realistically can only come when a transaction is created from
47+
/// JSON returned by a node, we only provide an intializer from JSON
48+
init(from decoder: Decoder) throws {
49+
let container = try decoder.container(keyedBy: CodingKeys.self)
50+
51+
self.blockHash = try container.decodeHexIfPresent(Data.self, forKey: .blockHash)
52+
self.transactionHash = try container.decodeHexIfPresent(Data.self, forKey: .transactionHash)
53+
self.transactionIndex = try container.decodeHexIfPresent(UInt.self, forKey: .transactionIndex)
54+
self.blockNumber = try container.decodeHexIfPresent(BigUInt.self, forKey: .blockNumber)
55+
self.gasPrice = try container.decodeHexIfPresent(BigUInt.self, forKey: .gasPrice)
56+
}
57+
}

Sources/web3swift/Transaction/EthereumTransaction.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ public struct EthereumTransaction: CustomStringConvertible {
1414
/// and type specific implementation
1515
internal var envelope: AbstractEnvelope
1616

17+
/// storage container for additional metadata returned by the node
18+
/// when a transaction is decoded form a JSON stream
19+
public var meta: EthereumMetadata?
20+
1721
// convenience accessors to the common envelope fields
1822
// everything else should come from getOpts/setOpts
1923
/// The type of the transacton being represented, see TransactionType enum
@@ -227,6 +231,8 @@ extension EthereumTransaction: Decodable {
227231
public init(from decoder: Decoder) throws {
228232
guard let env = try EnvelopeFactory.createEnvelope(from: decoder) else { throw Web3Error.dataError }
229233
self.envelope = env
234+
// capture any metadata that might be present
235+
self.meta = try EthereumMetadata(from: decoder)
230236
}
231237
}
232238

@@ -330,10 +336,7 @@ extension EthereumTransaction {
330336
guard let env = self.envelope as? EIP2930Envelope else { preconditionFailure("Unable to downcast to EIP2930Envelope") }
331337
return env.parameters.gasPrice ?? 0
332338
case .eip1559:
333-
// MARK: workaround for gasPrice coming from nodes for EIP-1159 - this allows Oracle to work for now
334-
guard let env = self.envelope as? EIP1559Envelope else { preconditionFailure("Unable to downcast to EIP1559Envelope") }
335-
return env.parameters.gasPrice ?? 0
336-
// preconditionFailure("EIP1559Envelope has no member gasPrice")
339+
preconditionFailure("EIP1559Envelope has no member gasPrice")
337340
}
338341
}
339342
set(value) {

Sources/web3swift/Web3/Web3+GasOracle.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ extension Web3 {
139139
return transaction
140140
}
141141
}
142-
.map { $0.gasPrice }
142+
.map { $0.meta?.gasPrice ?? 0 }
143143

144144
return calculatePercentiles(for: lastNthBlockGasPrice)
145145
}

web3swift.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@
202202
6049F416280616FC00DFE624 /* LegacyEnvelope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6049F40F280616FC00DFE624 /* LegacyEnvelope.swift */; };
203203
6049F4182806171300DFE624 /* Web3+Signing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6049F4172806171300DFE624 /* Web3+Signing.swift */; };
204204
604FA4FF27ECBDC80021108F /* DataConversionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 604FA4FE27ECBDC80021108F /* DataConversionTests.swift */; };
205+
60C1786E2809BA0C0083F064 /* EthereumMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60C1786D2809BA0C0083F064 /* EthereumMetadata.swift */; };
205206
CB50A52827060BD600D7E39B /* EIP712Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB50A52727060BD600D7E39B /* EIP712Tests.swift */; };
206207
D606A56B279F5D59003643ED /* web3swiftDecodeSolidityErrorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D606A56A279F5D59003643ED /* web3swiftDecodeSolidityErrorType.swift */; };
207208
D6A3D9B827F1E785009E3BCF /* ABIEncoderSoliditySha3Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A3D9B727F1E785009E3BCF /* ABIEncoderSoliditySha3Test.swift */; };
@@ -433,6 +434,7 @@
433434
6049F40F280616FC00DFE624 /* LegacyEnvelope.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LegacyEnvelope.swift; sourceTree = "<group>"; };
434435
6049F4172806171300DFE624 /* Web3+Signing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Web3+Signing.swift"; sourceTree = "<group>"; };
435436
604FA4FE27ECBDC80021108F /* DataConversionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataConversionTests.swift; sourceTree = "<group>"; };
437+
60C1786D2809BA0C0083F064 /* EthereumMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumMetadata.swift; sourceTree = "<group>"; };
436438
CB50A52727060BD600D7E39B /* EIP712Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EIP712Tests.swift; sourceTree = "<group>"; };
437439
CB50A52927060C5300D7E39B /* EIP712.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EIP712.swift; sourceTree = "<group>"; };
438440
D606A56A279F5D59003643ED /* web3swiftDecodeSolidityErrorType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = web3swiftDecodeSolidityErrorType.swift; sourceTree = "<group>"; };
@@ -720,6 +722,7 @@
720722
6049F40F280616FC00DFE624 /* LegacyEnvelope.swift */,
721723
3AA8153D2276E44100F5DB52 /* BloomFilter.swift */,
722724
3AA8153F2276E44100F5DB52 /* EthereumTransaction.swift */,
725+
60C1786D2809BA0C0083F064 /* EthereumMetadata.swift */,
723726
);
724727
path = Transaction;
725728
sourceTree = "<group>";
@@ -1349,6 +1352,7 @@
13491352
3AA815C12276E44100F5DB52 /* Web3+BrowserFunctions.swift in Sources */,
13501353
3AA815E82276E44100F5DB52 /* Extensions.swift in Sources */,
13511354
3AA815FE2276E44100F5DB52 /* Web3+ERC820.swift in Sources */,
1355+
60C1786E2809BA0C0083F064 /* EthereumMetadata.swift in Sources */,
13521356
3AA815DB2276E44100F5DB52 /* Web3+TxPool.swift in Sources */,
13531357
3AA8160A2276E44100F5DB52 /* Web3+ERC1594.swift in Sources */,
13541358
3AA815FB2276E44100F5DB52 /* Promise+Web3+Personal+UnlockAccount.swift in Sources */,

0 commit comments

Comments
 (0)