mirror of
https://github.com/Qortal/qortal.git
synced 2025-07-23 04:36:50 +00:00
Work on BTC-ACCT
Bump CIYAM AT dependency to v1.2 for MachineState.toCreationBytes()
This commit is contained in:
107
src/test/java/org/qora/test/btcacct/Initiate1.java
Normal file
107
src/test/java/org/qora/test/btcacct/Initiate1.java
Normal file
@@ -0,0 +1,107 @@
|
||||
package org.qora.test.btcacct;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
|
||||
import org.bitcoinj.core.Address;
|
||||
import org.bitcoinj.core.ECKey;
|
||||
import org.bitcoinj.core.LegacyAddress;
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
import org.bitcoinj.params.TestNet3Params;
|
||||
import org.bitcoinj.script.Script.ScriptType;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.qora.account.PublicKeyAccount;
|
||||
import org.qora.crosschain.BTC;
|
||||
import org.qora.crosschain.BTCACCT;
|
||||
import org.qora.crypto.Crypto;
|
||||
import org.qora.utils.Base58;
|
||||
|
||||
import com.google.common.hash.HashCode;
|
||||
|
||||
/**
|
||||
* Initiator must be Qora-chain so that initiator can send initial message to BTC P2SH then Qora can scan for P2SH add send corresponding message to Qora AT.
|
||||
*
|
||||
* Initiator (wants Qora, has BTC)
|
||||
* Funds BTC P2SH address
|
||||
*
|
||||
* Responder (has Qora, wants BTC)
|
||||
* Builds Qora ACCT AT and funds it with Qora
|
||||
*
|
||||
* Initiator sends recipient+secret+script as input to BTC P2SH address, releasing BTC amount - fees to responder
|
||||
*
|
||||
* Qora nodes scan for P2SH output, checks amount and recipient and if ok sends secret to Qora ACCT AT
|
||||
* (Or it's possible to feed BTC transaction details into Qora AT so it can check them itself?)
|
||||
*
|
||||
* Qora ACCT AT sends its Qora to initiator
|
||||
*
|
||||
*/
|
||||
|
||||
public class Initiate1 {
|
||||
|
||||
private static final long REFUND_TIMEOUT = 600L; // seconds
|
||||
|
||||
private static void usage() {
|
||||
System.err.println(String.format("usage: Initiate1 <your-QORT-pubkey> <your-BTC-pubkey> <QORT-amount> <BTC-amount> <their-QORT-pubkey> <their-BTC-pubkey>"));
|
||||
System.err.println(String.format("example: Initiate1 6rNn9b3pYRrG9UKqzMWYZ9qa8F3Zgv2mVWrULGHUusb \\\n"
|
||||
+ "\t03aa20871c2195361f2826c7a649eab6b42639630c4d8c33c55311d5c1e476b5d6 \\\n"
|
||||
+ "\t123 0.00008642 \\\n"
|
||||
+ "\tJBNBQQDzZsm5do1BrwWAp53Ps4KYJVt749EGpCf7ofte \\\n"
|
||||
+ "\t032783606be32a3e639a33afe2b15f058708ab124f3b290d595ee954390a0c8559"));
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (args.length != 6)
|
||||
usage();
|
||||
|
||||
Security.insertProviderAt(new BouncyCastleProvider(), 0);
|
||||
NetworkParameters params = TestNet3Params.get();
|
||||
|
||||
String yourQortPubKey58 = args[0];
|
||||
String yourBitcoinPubKeyHex = args[1];
|
||||
|
||||
String theirBitcoinPubKeyHex = args[5];
|
||||
|
||||
try {
|
||||
System.out.println("Confirm the following is correct based on the info you've given:");
|
||||
|
||||
byte[] yourQortPubKey = Base58.decode(yourQortPubKey58);
|
||||
PublicKeyAccount yourQortalAccount = new PublicKeyAccount(null, yourQortPubKey);
|
||||
System.out.println(String.format("Your Qortal address: %s", yourQortalAccount.getAddress()));
|
||||
|
||||
byte[] yourBitcoinPubKey = HashCode.fromString(yourBitcoinPubKeyHex).asBytes();
|
||||
ECKey yourBitcoinKey = ECKey.fromPublicOnly(yourBitcoinPubKey);
|
||||
Address yourBitcoinAddress = Address.fromKey(params, yourBitcoinKey, ScriptType.P2PKH);
|
||||
System.out.println(String.format("Your Bitcoin address: %s", yourBitcoinAddress.toString()));
|
||||
|
||||
byte[] theirBitcoinPubKey = HashCode.fromString(theirBitcoinPubKeyHex).asBytes();
|
||||
ECKey theirBitcoinKey = ECKey.fromPublicOnly(theirBitcoinPubKey);
|
||||
Address theirBitcoinAddress = Address.fromKey(params, theirBitcoinKey, ScriptType.P2PKH);
|
||||
System.out.println(String.format("Their Bitcoin address: %s", theirBitcoinAddress.toString()));
|
||||
|
||||
// New/derived info
|
||||
|
||||
byte[] secret = new byte[32];
|
||||
new SecureRandom().nextBytes(secret);
|
||||
System.out.println("\nSecret info (DO NOT share with other party):");
|
||||
System.out.println("Secret: " + HashCode.fromBytes(secret).toString());
|
||||
|
||||
System.out.println("\nGive this info to other party:");
|
||||
|
||||
byte[] secretHash = Crypto.digest(secret);
|
||||
System.out.println("Hash of secret: " + HashCode.fromBytes(secretHash).toString());
|
||||
|
||||
long lockTime = System.currentTimeMillis() + REFUND_TIMEOUT;
|
||||
byte[] redeemScriptBytes = BTCACCT.buildRedeemScript(secretHash, yourBitcoinPubKey, theirBitcoinPubKey, lockTime);
|
||||
System.out.println("Redeem script: " + HashCode.fromBytes(redeemScriptBytes).toString());
|
||||
|
||||
byte[] redeemScriptHash = BTC.hash160(redeemScriptBytes);
|
||||
|
||||
Address p2shAddress = LegacyAddress.fromScriptHash(params, redeemScriptHash);
|
||||
System.out.println("P2SH address: " + p2shAddress.toString());
|
||||
} catch (NumberFormatException e) {
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -70,11 +70,11 @@ public class BTCACCTTests {
|
||||
// For when we want to re-run
|
||||
private static final byte[] prevSecret = HashCode.fromString("30a13291e350214bea5318f990b77bc11d2cb709f7c39859f248bef396961dcc").asBytes();
|
||||
private static final long prevLockTime = 1539347892L;
|
||||
private static final boolean usePreviousFundingTx = true;
|
||||
private static final boolean usePreviousFundingTx = false;
|
||||
|
||||
private static final boolean doRefundNotRedeem = false;
|
||||
|
||||
public void main(String[] args) throws NoSuchAlgorithmException, InsufficientMoneyException, InterruptedException, ExecutionException, UnknownHostException {
|
||||
public static void main(String[] args) throws NoSuchAlgorithmException, InsufficientMoneyException, InterruptedException, ExecutionException, UnknownHostException {
|
||||
Security.insertProviderAt(new BouncyCastleProvider(), 0);
|
||||
|
||||
byte[] secret = new byte[32];
|
||||
@@ -173,7 +173,7 @@ public class BTCACCTTests {
|
||||
private static final byte[] redeemScript4 = HashCode.fromString("b17576a914").asBytes();
|
||||
private static final byte[] redeemScript5 = HashCode.fromString("88ac68").asBytes();
|
||||
|
||||
private byte[] buildRedeemScript(byte[] secret, byte[] senderPubKey, byte[] recipientPubKey, long lockTime) {
|
||||
private static byte[] buildRedeemScript(byte[] secret, byte[] senderPubKey, byte[] recipientPubKey, long lockTime) {
|
||||
try {
|
||||
MessageDigest sha256Digester = MessageDigest.getInstance("SHA-256");
|
||||
|
||||
@@ -188,7 +188,7 @@ public class BTCACCTTests {
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] hash160(byte[] input) {
|
||||
private static byte[] hash160(byte[] input) {
|
||||
try {
|
||||
MessageDigest rmd160Digester = MessageDigest.getInstance("RIPEMD160");
|
||||
MessageDigest sha256Digester = MessageDigest.getInstance("SHA-256");
|
||||
@@ -199,7 +199,7 @@ public class BTCACCTTests {
|
||||
}
|
||||
}
|
||||
|
||||
private Transaction buildFundingTransaction(NetworkParameters params, Sha256Hash prevTxHash, long outputIndex, Coin balance, ECKey sigKey, Coin value,
|
||||
private static Transaction buildFundingTransaction(NetworkParameters params, Sha256Hash prevTxHash, long outputIndex, Coin balance, ECKey sigKey, Coin value,
|
||||
byte[] redeemScriptHash) {
|
||||
Transaction fundingTransaction = new Transaction(params);
|
||||
|
||||
@@ -218,7 +218,7 @@ public class BTCACCTTests {
|
||||
return fundingTransaction;
|
||||
}
|
||||
|
||||
private Transaction buildRedeemTransaction(NetworkParameters params, TransactionOutPoint fundingOutPoint, ECKey recipientKey, Coin value, byte[] secret,
|
||||
private static Transaction buildRedeemTransaction(NetworkParameters params, TransactionOutPoint fundingOutPoint, ECKey recipientKey, Coin value, byte[] secret,
|
||||
byte[] redeemScriptBytes) {
|
||||
Transaction redeemTransaction = new Transaction(params);
|
||||
redeemTransaction.setVersion(2);
|
||||
@@ -255,7 +255,7 @@ public class BTCACCTTests {
|
||||
return redeemTransaction;
|
||||
}
|
||||
|
||||
private Transaction buildRefundTransaction(NetworkParameters params, TransactionOutPoint fundingOutPoint, ECKey senderKey, Coin value,
|
||||
private static Transaction buildRefundTransaction(NetworkParameters params, TransactionOutPoint fundingOutPoint, ECKey senderKey, Coin value,
|
||||
byte[] redeemScriptBytes, long lockTime) {
|
||||
Transaction refundTransaction = new Transaction(params);
|
||||
refundTransaction.setVersion(2);
|
||||
@@ -294,7 +294,7 @@ public class BTCACCTTests {
|
||||
return refundTransaction;
|
||||
}
|
||||
|
||||
private void broadcastWithConfirmation(WalletAppKit kit, Transaction transaction) {
|
||||
private static void broadcastWithConfirmation(WalletAppKit kit, Transaction transaction) {
|
||||
System.out.println("Broadcasting tx: " + transaction.getTxId().toString());
|
||||
System.out.println("TX hex: " + HashCode.fromBytes(transaction.bitcoinSerialize()).toString());
|
||||
|
||||
@@ -320,7 +320,7 @@ public class BTCACCTTests {
|
||||
}
|
||||
|
||||
/** Convert int to little-endian byte array */
|
||||
private byte[] toLEByteArray(int value) {
|
||||
private static byte[] toLEByteArray(int value) {
|
||||
return new byte[] { (byte) (value), (byte) (value >> 8), (byte) (value >> 16), (byte) (value >> 24) };
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user