Skip to content

Commit dd11bbf

Browse files
chore: documentation update with detailed guides for function deploy
1 parent d4df888 commit dd11bbf

File tree

2 files changed

+99
-15
lines changed

2 files changed

+99
-15
lines changed

Sources/Core/EthereumAddress/EthereumAddress.swift

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public struct EthereumAddress: Equatable {
3232
return lhs.addressData == rhs.addressData && lhs.type == rhs.type
3333
}
3434

35+
/// Raw representation of the address.
36+
/// If the ``type`` is ``EthereumAddress/AddressType/contractDeployment`` an empty `Data` object is returned.
3537
public var addressData: Data {
3638
get {
3739
switch self.type {
@@ -43,6 +45,9 @@ public struct EthereumAddress: Equatable {
4345
}
4446
}
4547
}
48+
49+
/// Checksummed address with `0x` HEX prefix.
50+
/// If the ``type`` is ``EthereumAddress/AddressType/contractDeployment`` only `0x` prefix is returned.
4651
public var address: String {
4752
switch self.type {
4853
case .normal:
@@ -52,6 +57,11 @@ public struct EthereumAddress: Equatable {
5257
}
5358
}
5459

60+
/// Validates and checksumms given `addr`.
61+
/// If given string is not an address, incomplete address or is invalid validation will fail and `nil` will be returned.
62+
/// - Parameter addr: address in string format, case insensitive, `0x` prefix is not required.
63+
/// - Returns: validates and checksumms the address. Returns `nil` if checksumm has failed or given string cannot be
64+
/// represented as `ASCII` data. Otherwise, checksummed address is returned with `0x` prefix.
5565
public static func toChecksumAddress(_ addr: String) -> String? {
5666
let address = addr.lowercased().stripHexPrefix()
5767
guard let hash = address.data(using: .ascii)?.sha3(.keccak256).toHexString().stripHexPrefix() else {return nil}
@@ -72,15 +82,19 @@ public struct EthereumAddress: Equatable {
7282
return ret
7383
}
7484

85+
/// Creates a special ``EthereumAddress`` that serves the purpose of the receiver, or `to` address of a transaction if it is a
86+
/// smart contract deployment.
87+
/// - Returns: special instance with type ``EthereumAddress/AddressType/contractDeployment`` and
88+
/// empty ``EthereumAddress/address``.
7589
public static func contractDeploymentAddress() -> EthereumAddress {
76-
return EthereumAddress("0x", type: .contractDeployment)!
90+
EthereumAddress("0x", type: .contractDeployment)!
7791
}
7892
}
7993

8094
/// In swift structs it's better to implement initializers in extension
8195
/// Since it's make available syntetized initializer then for free.
8296
extension EthereumAddress {
83-
public init?(_ addressString:String, type: AddressType = .normal, ignoreChecksum: Bool = false) {
97+
public init?(_ addressString: String, type: AddressType = .normal, ignoreChecksum: Bool = false) {
8498
switch type {
8599
case .normal:
86100
guard let data = Data.fromHex(addressString) else {return nil}

Sources/web3swift/Contract/ContractProtocol.swift

Lines changed: 83 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,31 @@ import Foundation
1010
import BigInt
1111
import Core
1212

13+
/// Standard representation of a smart contract.
1314
public protocol ContractProtocol {
15+
/// Address of the referenced smart contract. Can be set later, e.g. if the contract is deploying and address is not yet known.
1416
var address: EthereumAddress? {get set}
1517

1618
/// All ABI elements like: events, functions, constructors and errors.
1719
var abi: [ABI.Element] {get}
1820

19-
/// Functions filtered from `abi`.
20-
/// Contains methods mapped to function name, like `getData`,
21-
/// name with input parameters `getData(bytes32)` and 4 bytes signature `0xffffffff` (expected to be lowercased).
21+
/// Functions filtered from ``abi``.
22+
/// Functions are mapped to:
23+
/// - name, like `getData` that is defined in ``ABI/Element/Function/name``;
24+
/// - name with input parameters that is a combination of ``ABI/Element/Function/name`` and
25+
/// ``ABI/Element/Function/inputs``, e.g. `getData(bytes32)`;
26+
/// - and 4 bytes signature `0xffffffff` (expected to be lowercased).
2227
/// The mapping by name (e.g. `getData`) is the one most likely expected to return arrays with
2328
/// more than one entry due to the fact that solidity allows method overloading.
2429
var methods: [String:[ABI.Element.Function]] {get}
2530

26-
/// All entries from `methods`.
31+
/// All values from ``methods``.
2732
var allMethods: [ABI.Element.Function] {get}
2833

29-
/// Events filtered from `abi`.
34+
/// Events filtered from ``abi`` and mapped to their unchanged ``ABI/Element/Event/name``.
3035
var events: [String:ABI.Element.Event] {get}
3136

32-
/// All events from `events`.
37+
/// All values from ``events``.
3338
var allEvents: [ABI.Element.Event] {get}
3439

3540
/// Errors filtered from ``abi`` and mapped to their unchanged ``ABI/Element/EthError/name``.
@@ -50,7 +55,64 @@ public protocol ContractProtocol {
5055
/// new Solidity keywords, types etc. that are not yet supported, etc.
5156
init(_ abiString: String, at: EthereumAddress?) throws
5257

53-
/// Creates transaction to deploy a smart contract.
58+
/// Creates a smart contract deployment transaction.
59+
///
60+
/// ## How to
61+
/// To create a smart contract deployment transaction there is only one requirement - `bytecode`.
62+
/// That is the compiled smart contract that is ready to be executed by EVM, or eWASM if that is a Serenity.
63+
/// Creating a transaction is as simple as:
64+
///
65+
/// ```swift
66+
/// contractInstance.deploy(bytecode: smartContractBytecode)
67+
/// ```
68+
///
69+
/// One of the default implementations of `ContractProtocol` is ``EthereumContract``.
70+
/// ```swift
71+
/// let contract = EthereumContract(abi: [])
72+
/// contract.deploy(bytecode: smartContractBytecode)
73+
/// ```
74+
///
75+
/// ### Setting constructor arguments
76+
/// Some smart contracts expect input arguments for a constructor that is called on contract deployment.
77+
/// To set these input arguments you must provide `constructor` and `parameters`.
78+
/// Constructor can be statically created if you know upfront what are the input arguments and their exact order:
79+
///
80+
/// ```swift
81+
/// let inputArgsTypes: [ABI.Element.InOut] = [.init(name: "firstArgument", type: ABI.Element.ParameterType.string),
82+
/// .init(name: "secondArgument", type: ABI.Element.ParameterType.uint(bits: 256))]
83+
/// let constructor = ABI.Element.Constructor(inputs: inputArgsTypes, constant: false, payable: payable)
84+
/// let constructorArguments = ["This is the array of constructor arguments", 10_000] as [AnyObject]
85+
///
86+
/// contract.deploy(bytecode: smartContractBytecode,
87+
/// constructor: constructor,
88+
/// parameters: constructorArguments)
89+
/// ```
90+
///
91+
/// Alternatively, if you have ABI string that holds meta data about the constructor you can use it instead of creating constructor manually.
92+
/// But you must make sure the arguments for constructor call are of expected type in and correct order.
93+
/// Example of ABI string can be found in ``Web3/Utils/erc20ABI``.
94+
///
95+
/// ```swift
96+
/// let contract = EthereumContract(abiString)
97+
/// let constructorArguments = ["This is the array of constructor arguments", 10_000] as [AnyObject]
98+
///
99+
/// contract.deploy(bytecode: smartContractBytecode,
100+
/// constructor: contract.constructor,
101+
/// parameters: constructorArguments)
102+
/// ```
103+
///
104+
/// ⚠️ If you pass in only constructor or only parameters - it will have no effect on the final transaction object.
105+
/// Also, you have an option to set any extra bytes at the end of ``EthereumTransaction/data`` attribute.
106+
/// Alternatively you can encode constructor parameters outside of the deploy function and only set `extraData` to pass in these
107+
/// parameters:
108+
///
109+
/// ```swift
110+
/// // `encodeParameters` call returns `Data?`. Check it for nullability before calling `deploy`
111+
/// // function to create `EthereumTransaction`.
112+
/// let encodedConstructorArguments = someConstructor.encodeParameters(arrayOfInputArguments)
113+
/// constructor.deploy(bytecode: smartContractBytecode, extraData: encodedConstructorArguments)
114+
/// ```
115+
///
54116
/// - Parameters:
55117
/// - bytecode: bytecode to deploy.
56118
/// - constructor: constructor of the smart contract bytecode is related to. Used to encode `parameters`.
@@ -104,11 +166,19 @@ public protocol ContractProtocol {
104166
func decodeInputData(_ data: Data) -> [String: Any]?
105167

106168
/// Attempts to parse given event based on the data from `allEvents`, or in other words based on the given smart contract ABI.
107-
func parseEvent(_ eventLog: EventLog) -> (eventName:String?, eventData:[String: Any]?)
169+
func parseEvent(_ eventLog: EventLog) -> (eventName: String?, eventData: [String: Any]?)
108170

171+
/// Tests for probable presence of an event with `eventName` in a given bloom filter.
172+
/// - Parameters:
173+
/// - eventName: event name like `ValueReceived`.
174+
/// - bloom: bloom filter.
175+
/// - Returns: `true` if event is possibly present, `false` if definitely not present and `nil` if event with given name
176+
/// is not part of the ``EthereumContract/abi``.
109177
func testBloomForEventPresence(eventName: String, bloom: EthereumBloomFilter) -> Bool?
110178
}
111179

180+
// MARK: - Overloaded ContractProtocol's functions
181+
112182
extension ContractProtocol {
113183

114184
/// Overloading of ``ContractProtocol/deploy(bytecode:constructor:parameters:extraData:)`` to allow
@@ -119,10 +189,10 @@ extension ContractProtocol {
119189
constructor: ABI.Element.Constructor? = nil,
120190
parameters: [AnyObject]? = nil,
121191
extraData: Data? = nil) -> EthereumTransaction? {
122-
return deploy(bytecode: bytecode,
123-
constructor: constructor,
124-
parameters: parameters,
125-
extraData: extraData)
192+
deploy(bytecode: bytecode,
193+
constructor: constructor,
194+
parameters: parameters,
195+
extraData: extraData)
126196
}
127197

128198
/// Overloading of ``ContractProtocol/method(_:parameters:extraData:)`` to allow
@@ -132,7 +202,7 @@ extension ContractProtocol {
132202
func method(_ method: String = "fallback",
133203
parameters: [AnyObject]? = nil,
134204
extraData: Data? = nil) -> EthereumTransaction? {
135-
return self.method(method, parameters: parameters ?? [], extraData: extraData)
205+
self.method(method, parameters: parameters ?? [], extraData: extraData)
136206
}
137207

138208
func decodeInputData(_ data: Data) -> [String: Any]? {

0 commit comments

Comments
 (0)