tokenary/Encrypted Ink/Ethereum/Ethereum.swift

93 lines
3.5 KiB
Swift
Raw Normal View History

2021-06-12 14:30:58 +03:00
// Copyright © 2021 Encrypted Ink. All rights reserved.
import Foundation
2021-06-12 18:22:02 +03:00
import Web3Swift
import CryptoSwift
2021-06-12 14:30:58 +03:00
struct Transaction {
2021-06-12 18:22:02 +03:00
let transactionsCount: String
let gasPrice: String
let gasEstimate: String
let recipientAddress: String
let weiAmount: String
let contractCall: String
2021-06-12 14:30:58 +03:00
}
2021-06-12 19:47:44 +03:00
struct Account: Codable {
2021-06-12 18:22:02 +03:00
let privateKey: String
2021-06-12 18:59:15 +03:00
let address: String
2021-06-12 14:30:58 +03:00
}
struct Ethereum {
2021-06-12 18:22:02 +03:00
private static let network: Network = InfuraNetwork(
chain: "mainnet",
apiKey: "0c4d6dc730244b4185a6bde26f981bff"
)
static func sign(message: String, account: Account) throws -> String {
let ethPrivateKey = EthPrivateKey(hex: account.privateKey)
2021-06-12 14:30:58 +03:00
2021-06-12 18:22:02 +03:00
let signature = SECP256k1Signature(
privateKey: ethPrivateKey,
message: UTF8StringBytes(string: message),
hashFunction: SHA3(variant: .keccak256).calculate
)
let data = try ConcatenatedBytes(
bytes: [
signature.r(),
signature.s(),
EthNumber(value: signature.recoverID().value() + 27)
]
).value()
return data.toPrefixedHexString()
2021-06-12 14:30:58 +03:00
}
2021-06-12 18:22:02 +03:00
static func signPersonal(message: String, account: Account) throws -> String {
let ethPrivateKey = EthPrivateKey(hex: account.privateKey)
let signed = SignedPersonalMessageBytes(message: message, signerKey: ethPrivateKey)
let data = try signed.value().toPrefixedHexString()
return data
2021-06-12 14:30:58 +03:00
}
2021-06-12 18:22:02 +03:00
static func sign(typedData: String, account: Account) throws -> String {
let data = try EIP712TypedData(jsonString: typedData)
let hash = EIP712Hash(domain: data.domain, typedData: data)
let privateKey = EthPrivateKey(hex: account.privateKey)
let signer = EIP712Signer(privateKey: privateKey)
return try signer.signatureData(hash: hash).toPrefixedHexString()
2021-06-12 14:30:58 +03:00
}
2021-06-12 18:22:02 +03:00
static func sign(transaction: Transaction, account: Account) throws -> String {
let bytes = signedTransactionBytes(transaction: transaction, account: account)
return try bytes.value().toPrefixedHexString()
2021-06-12 14:30:58 +03:00
}
2021-06-12 18:22:02 +03:00
static func send(transaction: Transaction, account: Account) throws {
let bytes = signedTransactionBytes(transaction: transaction, account: account)
2021-06-12 19:16:23 +03:00
let response = try SendRawTransactionProcedure(network: network, transactionBytes: bytes).call()
2021-06-12 18:22:02 +03:00
}
private static func signedTransactionBytes(transaction: Transaction, account: Account) -> EthContractCallBytes {
let transactionsCount = IntegerBytes(value: Int(transaction.transactionsCount)!)
let gasPrice = BytesFromHexString(hex: transaction.gasPrice)
let gasEstimate = BytesFromHexString(hex: transaction.gasEstimate)
let senderKey = EthPrivateKey(hex: account.privateKey)
let recipientAddress = BytesFromHexString(hex: transaction.recipientAddress)
let weiAmount = BytesFromHexString(hex: transaction.weiAmount)
let contractCall = BytesFromHexString(hex: transaction.contractCall)
let bytes = EthContractCallBytes(
networkID: NetworkID(network: network),
transactionsCount: transactionsCount,
gasPrice: gasPrice,
gasEstimate: gasEstimate,
senderKey: senderKey,
contractAddress: recipientAddress,
weiAmount: weiAmount,
functionCall: contractCall
)
return bytes
2021-06-12 14:30:58 +03:00
}
}