I am new to coding, and only know swift, obj-C is still foreign to me. I have a functioning wallet but for now am relying on BlockCypher API to build a transaction which I do NOT want to do. Can anyone please help tell me what I am doing wrong in the following code snippet. I am creating a raw transaction however i get a weird response when decoding it where the address arrays are empty or null. Something is very wrong, if anyone has any experience I would so greatly appreciate it as this is driving me crazy.
import UIKit
class BuildTransactionViewController: UIViewController, BTCTransactionBuilderDataSource {
var addressToSpendFrom = "n1QQYAHbw3q6UjWN6Q4d9oqa6u5iUDnPHT"
var privateKeyToSign = "cNeZkP1QPQ37C4rLvoQ8xZ5eujcjsYHZMj8CLfPPohYPvfKhzHWu"
var receiverAddress = "n1v9HH9Abs36fYf8KbwnFUfzR4prLBXhtW"
var inputData = [NSDictionary]()
var scriptArray = [String]()
var transaction = BTCTransaction()
override func viewDidLoad() {
super.viewDidLoad()
getUTXOforAddress(address: addressToSpendFrom)
}
func getUTXOforAddress(address: String) {
var url:NSURL!
url = NSURL(string: "https://api.blockcypher.com/v1/btc/test3/addrs/\(address)?unspentOnly=true")
let task = URLSession.shared.dataTask(with: url! as URL) { (data, response, error) -> Void in
do {
if error != nil {
print(error as Any)
DispatchQueue.main.async {
displayAlert(viewController: self, title: "Error", message: "Please check your interent connection.")
}
} else {
if let urlContent = data {
do {
let jsonUTXOResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableLeaves) as! NSDictionary
print("json = \(jsonUTXOResult)")
if let utxoCheck = jsonUTXOResult["txrefs"] as? NSArray {
self.inputData = utxoCheck as! [NSDictionary]
print("utxoCheck = \(utxoCheck)")
for item in self.inputData {
let transactionHash = (item)["tx_hash"] as! String
let value = (item)["value"] as! Int
var url:NSURL!
url = NSURL(string: "https://api.blockcypher.com/v1/btc/test3/txs/\(transactionHash)")
let task = URLSession.shared.dataTask(with: url! as URL) { (data, response, error) -> Void in
do {
if error != nil {
print(error as Any)
DispatchQueue.main.async {
displayAlert(viewController: self, title: "Error", message: "Please check your interent connection.")
}
} else {
if let urlContent = data {
do {
let txHashResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableLeaves) as! NSDictionary
print("txHashResult = \(txHashResult)")
if let outputsCheck = txHashResult["outputs"] as? NSArray {
print("outputs = \(outputsCheck)")
for output in outputsCheck {
if let valueCheck = (output as! NSDictionary)["value"] as? Int {
if valueCheck == value {
let script = (output as! NSDictionary)["script"] as! String
self.scriptArray.append(script)
print("script = \(script)")
}
}
}
print("inputData = \(self.inputData)")
print("scriptArray = \(self.scriptArray)")
self.callBTCTransaction()
}
} catch {
print("JSon processing failed")
DispatchQueue.main.async {
displayAlert(viewController: self, title: "Error", message: "Please try again.")
}
}
}
}
}
}
task.resume()
}
}
} catch {
print("JSon processing failed")
DispatchQueue.main.async {
displayAlert(viewController: self, title: "Error", message: "Please try again.")
}
}
}
}
}
}
task.resume()
}
func callBTCTransaction() {
let address = BTCAddress(string: self.receiverAddress)
let newTransaction = BTCTransactionBuilder()
newTransaction.dataSource = self
newTransaction.shouldSign = true
newTransaction.changeAddress = BTCAddress(string: self.addressToSpendFrom)
newTransaction.outputs = [BTCTransactionOutput(value: BTCAmount(1000), address: address)]
newTransaction.feeRate = BTCAmount(2000)
var result:BTCTransactionBuilderResult? = nil
do {
result = try newTransaction.buildTransaction()
print("transactionRaw = \(String(describing: result?.transaction.hex))")
} catch {
print("error = \(error as Any)")
}
}
func transactionBuilder(_ txbuilder: BTCTransactionBuilder!, keyForUnspentOutput txout: BTCTransactionOutput!) -> BTCKey! {
print("transactionBuilder")
let key = BTCKey.init(wif: self.privateKeyToSign)
key?.isPublicKeyCompressed = true
return key
}
func unspentOutputs(for txbuilder: BTCTransactionBuilder!) -> NSEnumerator! {
let outputs = NSMutableArray()
for (index, item) in inputData.enumerated() {
let txout = BTCTransactionOutput()
txout.value = BTCAmount((item).value(forKey: "value") as! Int64)
txout.script = BTCScript.init(hex: self.scriptArray[index])
txout.index = UInt32((item).value(forKey: "tx_output_n") as! Int)
txout.confirmations = UInt((item).value(forKey: "confirmations") as! Int)
let transactionHash = (item)["tx_hash"] as! String
txout.transactionHash = transactionHash.data(using: .utf8)
outputs.add(txout)
}
print("outputs = \(outputs)")
return outputs.objectEnumerator()
}
}