diff --git a/SimpleWallet/AppDelegate.swift b/SimpleWallet/AppDelegate.swift index d48ac83..ce1751c 100644 --- a/SimpleWallet/AppDelegate.swift +++ b/SimpleWallet/AppDelegate.swift @@ -35,9 +35,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } private func setup() { - let post = Post(choices: [Post.Choice(description: "選択肢1", address: "addr1"), - Post.Choice(description: "選択肢2", address: "addr2"), - Post.Choice(description: "選択肢3", address: "addr3")], + let post = Post(choices: [Post.Choice(description: "選択肢1", address: "addr1", pubKey: PrivateKey().publicKey()), + Post.Choice(description: "選択肢2", address: "addr2", pubKey: PrivateKey().publicKey()), + Post.Choice(description: "選択肢3", address: "addr3", pubKey: PrivateKey().publicKey())], userName: "ゆーざ名", createdAt: Date(), description: "ですくり", diff --git a/SimpleWallet/Modules/Models/Post.swift b/SimpleWallet/Modules/Models/Post.swift index 4d25ea5..750ac91 100644 --- a/SimpleWallet/Modules/Models/Post.swift +++ b/SimpleWallet/Modules/Models/Post.swift @@ -7,11 +7,13 @@ // import Foundation +import BitcoinKit struct Post { struct Choice { let description: String let address: String + let pubKey: PublicKey } let choices: [Choice] let userName: String diff --git a/SimpleWallet/Modules/ViewControllers/AddChoiceView/AddChoiceViewController.swift b/SimpleWallet/Modules/ViewControllers/AddChoiceView/AddChoiceViewController.swift index effc939..2f334a1 100644 --- a/SimpleWallet/Modules/ViewControllers/AddChoiceView/AddChoiceViewController.swift +++ b/SimpleWallet/Modules/ViewControllers/AddChoiceView/AddChoiceViewController.swift @@ -9,6 +9,7 @@ import UIKit import RxSwift import RxCocoa +import BitcoinKit class AddChoiceViewController: UIViewController { static func make(choices: BehaviorRelay<[Post.Choice]>) -> UIViewController { @@ -43,9 +44,12 @@ class AddChoiceViewController: UIViewController { output .registerChoice .drive(onNext: { [weak self] _ in - guard let wself = self, let description = wself.choiceTextField.text, let address = wself.BCHurlText.text else { return } + guard + let wself = self, + let description = wself.choiceTextField.text, + let address = wself.BCHurlText.text else { return } var arr = wself.choices.value - arr.append(Post.Choice(description: description, address: address)) + arr.append(Post.Choice(description: description, address: address, pubKey: PrivateKey().publicKey())) wself.choices.accept(arr) wself.dismiss(animated: true) }) diff --git a/SimpleWallet/Modules/ViewControllers/DetailView/DetailViewController.swift b/SimpleWallet/Modules/ViewControllers/DetailView/DetailViewController.swift index 6fb9308..a422620 100644 --- a/SimpleWallet/Modules/ViewControllers/DetailView/DetailViewController.swift +++ b/SimpleWallet/Modules/ViewControllers/DetailView/DetailViewController.swift @@ -34,11 +34,11 @@ class DetailViewController: UIViewController { } @IBAction func voteAction(_ sender: Any) { - print("投票しました") - - // TODO: targetPubKey をちゃんとハメる + debugLog("投票しました") + // 運営と投票される側でマルチシグを行う - let multisig: Address = BCHHelper().createMultisigAddress(adminPubKey: Constant.adminPubKey, targetPubKey: Constant.adminPubKey) + let multisig: Address = BCHHelper().createMultisigAddress(adminPubKey: Constant.adminPubKey, + targetPubKey: post.choices[0].pubKey) //決め打ち sendCoins(toAddress: multisig, amount: Constant.voteAmount, comment: commentText.text!) } @@ -82,9 +82,8 @@ class DetailViewController: UIViewController { .append(.OP_IF) // マルチシグでロック .append(.OP_2) - // TODO: 値の入れ替え .appendData(Constant.adminPubKey.raw) - .appendData(try! Wallet(wif: "立候補者").publicKey.raw) + .appendData(post.choices[0].pubKey.raw) //決め打ち .append(.OP_2) .append(.OP_CHECKMULTISIG) // ユーザーがunlockする場合 @@ -114,34 +113,29 @@ class DetailViewController: UIViewController { var transactionToSign: Transaction { return Transaction(version: unsignedTx.tx.version, inputs: inputsToSign, outputs: unsignedTx.tx.outputs, lockTime: unsignedTx.tx.lockTime) } - + // Signing let hashType = SighashType.BCH.ALL for (i, utxo) in unsignedTx.utxos.enumerated() { - // TODO: 運営の - let walletA = try! Wallet(wif: "") - - let publicKeyA = AppController.shared.wallet!.publicKey - let publicKeyB = walletA.publicKey - - let redeemScript = Script(publicKeys: [publicKeyA, publicKeyB], signaturesRequired: 2)! - - // outputを作り直す - let output = TransactionOutput(value: utxo.output.value, lockingScript: redeemScript.data) - - // 作り直したoutputをsighashを作るときに入れる - let sighash: Data = transactionToSign.signatureHash(for: output, inputIndex: i, hashType: SighashType.BCH.ALL) - let signatureA: Data = try! Crypto.sign(sighash, privateKey: walletA.privateKey) + let pubkeyHash: Data = Script.getPublicKeyHash(from: utxo.output.lockingScript) + + let keysOfUtxo: [PrivateKey] = keys.filter { $0.publicKey().pubkeyHash == pubkeyHash } + guard let key = keysOfUtxo.first else { + continue + } + + let sighash: Data = transactionToSign.signatureHash(for: utxo.output, inputIndex: i, hashType: SighashType.BCH.ALL) + let signature: Data = try! Crypto.sign(sighash, privateKey: key) let txin = inputsToSign[i] - - let unlockingScript = try! Script() - .append(.OP_0) - .appendData(signatureA + UInt8(hashType)) - .appendData(redeemScript.data) - - inputsToSign[i] = TransactionInput(previousOutput: txin.previousOutput, signatureScript: unlockingScript.data, sequence: txin.sequence) + let pubkey = key.publicKey() + + // unlockScriptを作る + let unlockingScript = Script.buildPublicKeyUnlockingScript(signature: signature, pubkey: pubkey, hashType: hashType) + + inputsToSign[i] = TransactionInput(previousOutput: txin.previousOutput, + signatureScript: unlockingScript, + sequence: txin.sequence) } - return transactionToSign } diff --git a/SimpleWallet/Modules/ViewControllers/Sample/SendViewController.swift b/SimpleWallet/Modules/ViewControllers/Sample/SendViewController.swift index 806352d..dcc0652 100644 --- a/SimpleWallet/Modules/ViewControllers/Sample/SendViewController.swift +++ b/SimpleWallet/Modules/ViewControllers/Sample/SendViewController.swift @@ -14,8 +14,8 @@ class SendViewController: UIViewController { @IBOutlet weak var textField: UITextField! @IBAction func sendButtonTapped(_ sender: Any) { // 送金をする - let address: Address = try! AddressFactory.create("bchtest:qpytf7xczxf2mxa3gd6s30rthpts0tmtgyw8ud2sy3") - sendCoins(toAddress: address, amount: 300) + let address: Address = try! AddressFactory.create("bchtest:qqd4tpejz3n3psvlhdv8v095jtl7mc9t2qwt6cnh4r") + sendCoins(toAddress: address, amount: 1000000) } override func viewDidLoad() { @@ -67,11 +67,11 @@ class SendViewController: UIViewController { // 上のBitcoin Scriptを自分で書いてみよー! // OP_RETURNのOutputを作成する - let message = textField.text ?? "" - let opReturnScript = try! Script() - .append(.OP_RETURN) - .appendData(message.data(using: .utf8)!) - let opReturnOutput = TransactionOutput(value: 0, lockingScript: opReturnScript.data) +// let message = textField.text ?? "" +// let opReturnScript = try! Script() +// .append(.OP_RETURN) +// .appendData(message.data(using: .utf8)!) +// let opReturnOutput = TransactionOutput(value: 0, lockingScript: opReturnScript.data) // OP_CLTVのOutputを作成する @@ -81,10 +81,10 @@ class SendViewController: UIViewController { // 5. UTXOとTransactionOutputを合わせて、UnsignedTransactionを作る let unsignedInputs = utxos.map { TransactionInput(previousOutput: $0.outpoint, signatureScript: Data(), sequence: UInt32.max) } -// let tx = Transaction(version: 1, inputs: unsignedInputs, outputs: [toOutput, changeOutput], lockTime: 0) + let tx = Transaction(version: 1, inputs: unsignedInputs, outputs: [toOutput, changeOutput], lockTime: 0) // txのoutputsにopReturnOutputを入れる - let tx = Transaction(version: 1, inputs: unsignedInputs, outputs: [opReturnOutput, changeOutput], lockTime: 0) +// let tx = Transaction(version: 1, inputs: unsignedInputs, outputs: [opReturnOutput, changeOutput], lockTime: 0) return UnsignedTransaction(tx: tx, utxos: utxos) }