Skip to content

Instantly share code, notes, and snippets.

@koraykoska
Created May 14, 2018 19:30
Show Gist options
  • Save koraykoska/c2db36fce19b821221b3f8fdb7bae7da to your computer and use it in GitHub Desktop.
Save koraykoska/c2db36fce19b821221b3f8fdb7bae7da to your computer and use it in GitHub Desktop.
Web3 Swift ERC20 helper
import Web3
struct ERC20 {
let address: EthereumAddress
let reading: Reading
let writing: Writing
init(contractAddress: EthereumAddress) {
self.address = contractAddress
self.reading = Reading(contractAddress: contractAddress)
self.writing = Writing(contractAddress: contractAddress)
}
struct Reading {
let address: EthereumAddress
init(contractAddress: EthereumAddress) {
self.address = contractAddress
}
func name() -> EthereumCall {
let data = EthereumData(bytes: [0x06, 0xfd, 0xde, 0x03])
return EthereumCall(to: address, data: data)
}
func symbol() -> EthereumCall {
let data = EthereumData(bytes: [0x95, 0xd8, 0x9b, 0x41])
return EthereumCall(to: address, data: data)
}
func decimals() -> EthereumCall {
let data = EthereumData(bytes: [0x31, 0x3c, 0xe5, 0x67])
return EthereumCall(to: address, data: data)
}
func totalSupply() -> EthereumCall {
let data = EthereumData(bytes: [0x18, 0x16, 0x0d, 0xdd])
return EthereumCall(to: address, data: data)
}
func balanceOf(owner: EthereumAddress) -> EthereumCall {
var bytes: [UInt8] = [0x70, 0xa0, 0x82, 0x31]
bytes.append(contentsOf: owner.rawAddress.leftPad(with: 0, multipleOf: 32))
let data = EthereumData(bytes: bytes)
return EthereumCall(to: address, data: data)
}
func allowance(owner: EthereumAddress, spender: EthereumAddress) -> EthereumCall {
var bytes: [UInt8] = [0xdd, 0x62, 0xed, 0x3e]
bytes.append(contentsOf: owner.rawAddress.leftPad(with: 0, multipleOf: 32))
bytes.append(contentsOf: spender.rawAddress.leftPad(with: 0, multipleOf: 32))
let data = EthereumData(bytes: bytes)
return EthereumCall(to: self.address, data: data)
}
}
struct Writing {
let address: EthereumAddress
init(contractAddress: EthereumAddress) {
self.address = contractAddress
}
func transfer(
nonce: EthereumQuantity,
gasPrice: EthereumQuantity,
gasLimit: EthereumQuantity,
to: EthereumAddress,
value: EthereumQuantity,
chainId: EthereumQuantity
) -> EthereumTransaction {
var bytes: [UInt8] = [0xa9, 0x05, 0x9c, 0xbb]
bytes.append(contentsOf: to.rawAddress.leftPad(with: 0, multipleOf: 32))
bytes.append(contentsOf: value.quantity.makeBytes().leftPad(with: 0, to: 32))
let data = EthereumData(bytes: bytes)
let tx = EthereumTransaction(nonce: nonce, gasPrice: gasPrice, gasLimit: gasLimit, to: address, value: 0, data: data, chainId: chainId)
return tx
}
func transferFrom(
nonce: EthereumQuantity,
gasPrice: EthereumQuantity,
gasLimit: EthereumQuantity,
from: EthereumAddress,
to: EthereumAddress,
value: EthereumQuantity,
chainId: EthereumQuantity
) -> EthereumTransaction {
var bytes: [UInt8] = [0x23, 0xb8, 0x72, 0xdd]
bytes.append(contentsOf: from.rawAddress.leftPad(with: 0, multipleOf: 32))
bytes.append(contentsOf: to.rawAddress.leftPad(with: 0, multipleOf: 32))
bytes.append(contentsOf: value.quantity.makeBytes().leftPad(with: 0, to: 32))
let data = EthereumData(bytes: bytes)
let tx = EthereumTransaction(nonce: nonce, gasPrice: gasPrice, gasLimit: gasLimit, to: address, value: 0, data: data, chainId: chainId)
return tx
}
func approve(
nonce: EthereumQuantity,
gasPrice: EthereumQuantity,
gasLimit: EthereumQuantity,
spender: EthereumAddress,
value: EthereumQuantity,
chainId: EthereumQuantity
) -> EthereumTransaction {
var bytes: [UInt8] = [0x09, 0x5e, 0xa7, 0xb3]
bytes.append(contentsOf: spender.rawAddress.leftPad(with: 0, multipleOf: 32))
bytes.append(contentsOf: value.quantity.makeBytes().leftPad(with: 0, to: 32))
let data = EthereumData(bytes: bytes)
let tx = EthereumTransaction(nonce: nonce, gasPrice: gasPrice, gasLimit: gasLimit, to: address, value: 0, data: data, chainId: chainId)
return tx
}
}
}
fileprivate extension Array where Element == UInt8 {
func leftPad(with: UInt8, multipleOf: Int) -> [UInt8] {
let paddingSize = multipleOf - (count % multipleOf)
let padding = [UInt8].init(repeating: with, count: paddingSize)
var newArray = self
newArray.insert(contentsOf: padding, at: 0)
return newArray
}
func leftPad(with: UInt8, to: Int) -> [UInt8] {
if count >= to {
return self
}
let paddingSize = to - count
let padding = [UInt8].init(repeating: with, count: paddingSize)
var newArray = self
newArray.insert(contentsOf: padding, at: 0)
return newArray
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment