前言:什么是智能合约?
智能合约,是一段写在区块链上的代码,一旦某个事件触发合约中的条款,代码即自动执行。也就是说,满足条件就执行,不需要人为操控。
web3Swift
web3json数据Swift是一个纯粹json数据而快速以太坊Web3库 github.com/skywi源码精灵永久兑换码nder/w…
在使用之前,请先Cocoapproachapods集成web3swift
pod 'web3swift' #web3智能合约
Web3SwiftUtils
- 相信很多接触刚智能合约开发和合约API调用的iOSer会遇到很多问题或踩坑,本工具类主要实现了Etherum、B源码时代inance、Polygon链等智能合约常用业务调用及主要方jsonobject法封装;
主要方法调用
调用智能合约
/// 操作智能合约
/// - Parameters:
/// - method: 方法名称
/// - params: 参数
/// - config: options配置
/// - closure: tx结果信息
private func callContractService(_ abiType: CSContractAbiType = .erc20, methodName: String, callType: CSContractCallType, params: [AnyObject] = [AnyObject](), config: CSContractConfig, closure: @escaping (CSContractTransResult)->Void) {
if let object = config.modelToJSONObject() {
print("Contract call config:(object)n")
print("Contract call params:(params)n")
print("Contract call rpc:(self.network.ipUrl)n")
}
let transResult = CSContractTransResult()
// key
guard let privateKey = config.privateKey else { return }
let formattedKey = privateKey.trimmingCharacters(in: .whitespacesAndNewlines)
let dataKey = Data.fromHex(formattedKey)!
let keystore = try! EthereumKeystoreV3(privateKey: dataKey, password: password)
let keystoreManager = KeystoreManager([keystore! as EthereumKeystoreV3])
/// web3
let endpoint = URL(string: contractURL)!
guard let web333 = try? Web3.new(endpoint) else {
return
}
web333.addKeystoreManager(keystoreManager)
web3Manager = web333
// 合约方法名称
let contractMethod = methodName
// ABI资源
var contractABI = Web3.Utils.erc20ABI
switch abiType {
case .erc20:
contractABI = Web3.Utils.erc20ABI
default:
let abiName = fetchAbiType(type: abiType)
contractABI = String.fileContractABI(resName: abiName)
}
// 合约地址
let ethContractAddress = EthereumAddress(config.contractAddress!)
let abiVersion = 2 // Contract ABI version
guard let contract = web333.contract(contractABI, at: ethContractAddress, abiVersion: abiVersion) else {
return
}
var options = TransactionOptions.defaultOptions
// 我的地址
if let from = config.from, let walletAddress = EthereumAddress(from) {
options.from = walletAddress
}
// 接收地址
if let to = config.to, let toAddress = EthereumAddress(to) {
options.to = toAddress
}
var decimals = BigUInt(18)
// get the decimals manually
if let callResult = try? contract.read("decimals", transactionOptions: options)?.call() {
guard let dec = callResult["0"], let decTyped = dec as? BigUInt else {
return
}
decimals = decTyped
}
let intDecimals = Int(decimals)
if let amount = config.amount {
options.value = Web3.Utils.parseToBigUInt(amount, decimals: intDecimals)
}
if let gasLimit = config.gasLimit {
options.gasLimit = .manual(BigUInt("(gasLimit)")!)
}else {
options.gasLimit = .automatic
}
if let gasPrice = config.gasPrice {
if let gwei = Web3.Utils.parseToBigUInt(gasPrice, units: .Gwei) {
options.gasPrice = .manual(gwei)
}else {
options.gasPrice = .automatic
}
}
else {
options.gasPrice = .automatic
}
let extraData: Data = Data() // Extra data for contract method
if (callType == .write) {
guard let tx = contract.write(contractMethod,
parameters: params,
extraData: extraData,
transactionOptions: options) else {
// callback
closure(transResult)
return
}
print("Transaction methodName:(methodName)n")
print("Transaction description:(tx.transaction.description)n")
if let result = try? tx.call() {
transResult.callData = result
print("Transaction callData:(result)")
if let etherAddress = result["0"] as? EthereumAddress {
print("Transaction _link:(etherAddress.address)")
transResult.linkAddress = etherAddress.address
}
}
txSendCallResult(tx, config: config) { result in
transResult.transHash = result?.hash ?? ""
transResult.transDesc = result?.transaction.description ?? ""
}
}else {
guard let tx = contract.read(contractMethod,
parameters: params,
extraData: extraData,
transactionOptions: options) else {
// callback
closure(transResult)
return
}
print("Transaction methodName:(methodName)n")
print("Transaction description:(tx.transaction.description)n")
if let result = try? tx.call() {
transResult.callData = result
if let tokenWei = result["0"] as? BigUInt {
transResult.callStatus = tokenWei > 0
transResult.approvedAmount = "(tokenWei)"
}else if let status = result["0"] as? Bool {
if (config.symbol == "BNB" || config.symbol == "ETH" || config.symbol == "MATIC") {
transResult.callStatus = true
}else {
transResult.callStatus = status
}
}
print("Transaction callData:(result)")
}
}
// callback
closure(transResult)
}
获取合约Transaction结果
private func txSendCallResult(_ tx: WriteTransaction, options: TransactionOptions? = nil, config: CSContractConfig, completion: @escaping (TransactionSendingResult?)->Void) {
// Get transaction result
do {
let result = try tx.send(password: password, transactionOptions: options)
completion(result)
print("Transaction hash:(result.hash)n")
print("Transaction desc:(result.transaction.description)n")
} catch {
completion(nil)
let transactionErr = "(error)"
showMessage(message: transactionErr, config: config)
}
}
代币授权
func tokenApprove() {
let config = CSContractConfig()
config.abiType = .erc20;
config.privateKey = "your privateKey"
config.from = "your walletAddress";
config.approveAmount = "1000000000000";
config.contractAddress = "contract address"
config.symbol = "token symbol"
CSContractManager.shared.callContract(method: "approve", params: [], config: config) { result in
if (result.transHash.length > 0 && result.callData.count > 0) {
print("Token approve success")
}else {
print("Token approve fail")
}
}
}
代币发送
func sendToken() {
let config = CSContractConfig()
config.abiType = .erc20;
config.privateKey = "your privateKey"
config.from = "your walletAddress";
config.contractAddress = "contract address"
config.symbol = "token symbol"
config.gasLimit = kBaseGasLimit;
let targetAddress = "target address"
CSContractManager.shared.sendToken(config: config, amount: "10", toAdds: targetAddress) { result in
if (result.transHash.length > 0) {
print("Token send success")
}else {
print("Token send fail")
}
}
}
查询代币信息
func queryToken() {
let tokenAddress = ""
guard let token = CSContractManager.shared.querySocialToken(address: tokenAddress) else {
return
}
print("Token Name:(token.name)n")
print("Token Symbol:(token.symbol)n")
print("Token decimals:(token.decimals)n")
}
查询当前钱包账户余额
func queryAccountBalance () {
let myWalletAddress = "your walletAddress";
let balance = CSContractManager.shared.getAccountBalance(address: myWalletAddress)
print("Your account balance:(balance)")
}
具体功能使用,可以下载源码了解;
githugiticomfort是什么轮胎b.com/deve源码时代loperje… 如果对您有一些帮助请麻烦给个Sgithub中文官网网页ta源码时代r,谢谢。