Anhand des Beispiels hier: https://bitcoinj.github.io/working-with-contracts
Ich glaube, ich habe alles richtig gemacht. Mein Programm kann sich jedoch entweder nicht richtig verbreiten oder liegt an einem TX-Fehler, und ich kann nicht feststellen, warum
Ein paar Dinge, von denen ich glaube, dass sie der Grund sind
1) Meine peergroup.broadcastTransaction (spendTx) sendet nicht richtig 2) Eine fehlerhafte Rohtransaktion oder Skriptsig (ich nehme an, es ist dies, aber auch hier keine Fehler) 3) Im Allgemeinen verstehe ich nicht die beste Methode, um Ausgaben mit Eingaben zu verknüpfen und sie zu signieren angemessen (verwende ich zum Beispiel die UTXO-Klasse oder TransactionSignature) 3) Versuchen, Geld von einer überwachten Adresse auszugeben. Ich habe die notwendigen Schlüssel, um die UTXOs freizuschalten, aber ich würde gerne sehen, ob ich das Geld ohne die Verwendung der Wallet-Klasse ausgeben kann. 4) Multisig-Unterstützung im Allgemeinen für Bitcoin ist nicht vorhanden oder unvollständig. Ich hoffe, es ist nicht das, da ich es wirklich gerne zum Laufen bringen würde. Aber – ich glaube nicht, dass dies das größte Problem ist, weil ich die Unit-Tests durchgeführt habe und sie immer noch alle sauber auschecken.
Ein Schritt durch den Code, um gründlich zu sein:
Erstellen Sie 3 ECKeys für einen 2-von-3-Multisig-Vertrag, fügen Sie sie in eine Liste ein, erstellen Sie ein Einlösungsskript, das Schlüssel in lexikografischer Reihenfolge sortiert und ein m-von-n-Multisigoutput-Skript schreibt, dann instanziieren Sie ein Transaktionsobjekt und weisen Sie es als OUTPUT zu die ich als INPUT (Betrag + Einlösungsskript) verwenden werde, AKA das UTXO, das ich ausgeben werde (EDIT: Kurze Erwähnung. Die ECKeys, die ich wirklich verwende, sind fest codierte Werte, die ich vor einiger Zeit erstellt habe, diese dienen der Veranschaulichung. Ich sollte auch erwähnen, dass dies ein P2SH-Multisig ist, nicht das rohe Nicht-Standard-Multisig.
ECKey keyA = new ECKey();
ECKey keyB = new ECKey();
ECKey keyC = new ECKey();
List<ECKey> keys = ImmutableList.of(key1, key2, key3);
Script script = ScriptBuilder.createRedeemScript(2, keys);
Script scriptPubKey = ScriptBuilder.createP2SHOutputScript(script);
Transaction contract = new Transaction(params);
TransactionOutput multiSigOutput = contract.addOutput(Coin.valueOf(50000), scriptPubKey);
Erstellen Sie ein zweites Transaktionsobjekt, das ich verwenden werde, um das Ausgabeskript zusammenzustellen, auch bekannt als die (Wert + Ziel)-Adresse, an der ich mein UTXO anmelden werde. Auch wo der sigHash mit 2 meiner Schlüssel signiert und zum scriptSig der Transaktion hinzugefügt wird
Transaction spendTx = new Transaction(params);
Address address = Address.fromBase58(params, "19EfMrs5WkcvtBBnuEqP6v1yppeWww61Kc");
Script outputScript = ScriptBuilder.createOutputScript(address);
spendTx.addOutput(multiSigOutput.getValue(), outputScript);
// System.out.println(spendTx.getOutputs());
TransactionInput input = spendTx.addInput(multiSigOutput);
Jetzt die Eingaben manuell signieren ... (Signaturen sind in derselben Reihenfolge wie im Skript)
//sign transaction manually
Sha256Hash sigHash = spendTx.hashForSignature(0, script, Transaction.SigHash.ALL, false);
ECKey.ECDSASignature signature = list.get(0).sign(sigHash);
ECKey.ECDSASignature signature1 = list.get(1).sign(sigHash);
TransactionSignature txSig = new TransactionSignature(signature, Transaction.SigHash.ALL, false);
TransactionSignature txSig1 = new TransactionSignature(signature1, Transaction.SigHash.ALL, false);
...jetzt multisiginputscript erstellen, tx validieren und senden
Script inputScript = ScriptBuilder.createP2SHMultiSigInputScript((ImmutableList.of(txSig, txSig1)));
// System.out.println(inputScript);
input.setScriptSig(inputScript);
input.verify(multiSigOutput);
peerGroup.broadcastTransaction(spendTx);
System.out.println(kit.peerGroup().getConnectedPeers());
System.out.println("transaction broadcasted");
ok ... dies wird nicht weitergegeben, aber die Überprüfung wird überprüft. und ich weiß nicht einmal, ob es sich eher um ein Netzwerkproblem als um ein Codeproblem handelt, denn wenn ich den Wert im Ausgabeskript auf > den Saldo des UTXO ändere, wird keine InsufficientMoneyException ausgelöst, wie ich es mir vorstelle. Ich würde einige Fehlerprotokolle anzeigen, aber es gibt keine. Der einzige Fehler ist, wenn ich das createmultisiginputscript in createP2SHmultisiginputscript ändere, gibt die Konsole einen Nicht-Null-Nulldummy-Fehler aus, bei dessen Behebung ich auch Probleme habe, sodass ich nie wissen konnte, ob der Wechsel zu dieser Methode auch die richtige Lösung ist. Ich glaube, ich habe auch die Verbindung zur Peergroup richtig eingerichtet
File chainFile = new File(this.getFilesDir(), "test.spvchain");
System.out.println("does chainfile exist?" + chainFile.exists());
if(chainFile.exists()) {
try {
SPVBlockStore chainStore = new SPVBlockStore(params, chainFile);
BlockChain chain = new BlockChain(params, chainStore);
peerGroup = new PeerGroup(params, chain);
peerGroup.addPeerDiscovery(new DnsDiscovery(params));
peerGroup.startAsync();
} catch (BlockStoreException e) {
e.printStackTrace();
}
Also verstehe ich es nicht wirklich ... Ich bin zu dem Schluss gekommen, dass mein Verständnis irgendwie falsch ist. Sorry für den verwirrenden langen Beitrag. Es ist Tage her. Kann jemand helfen?
EDIT: Hier ist die rohe Transaktion
In Hex:
In Protokollen:
fbb119d8990cd3912a9ec0118fe3ad8ad61a8388e4a13dd342d9eb67aacfdc65
01-12 17:49:20.670 2507-2507/com.cryptoapp.app I/System.out: in 0[] PUSHDATA(71)[3044022022b97b9372d35acaea70f3735dee290f5697cab7b5d6be6f7cdfe31139fba4f90220651091b83570843d4fe8afe02d81417194908b0f6af6f8f3b8f1ad020592409f01] PUSHDATA(71)[3044022036eff4f54b8bf3f834f7bb6e417a04a6a696047f5c75a896c6f9b624ad87680a02200bf2115b64b3b15647178b69151d4588d8a4ade16a4d66e375d0e1265c79fad601] PUSHDATA1[5221025ab78e076801b45ccb2172bce562103cce1714edbeb02ce6123ce1235eb08c762102d1b74577050b696d5886a7afa61d099ea7ab0a3797766f9819dbd72526b0ce512103facf04db5d9bee657151e30c21e839489c326a277891ebcf75b736ec1e17fc1f53ae] 0.0005 BTC 01-12 17:49:20.670 2507-2507/com.cryptoapp.app I/System.out: outpoint:c33858b433ef445db35a84daa4da772895df7f03af4b31f21cfa199ea1c017d9:0 hash160:6d49586d7529626aaab49812bcd7839aee7e5800 01-12 17:49:20.670 2507-2507/com.cryptoapp.app I/System.out: out DUP HASH160 PUSHDATA(20)[5a566f4eda18e818b8d5ca04ee7c5fa3cfbf0e00] EQUALVERIFY CHECKSIG 0.0005 BTC 12.01 01-12 17:49:20.670 2507-2507/com.cryptoapp.app I/System.out: prps UNKNOWN
Ein paar Kommentare von der Überprüfung der von Ihnen geposteten Transaktionsdaten.
1) Ich habe den UTXO überprüft, von dem Sie ausgeben, der UTXO ist
9e7562d19165077d566af47bfbc18283629ed6799da8862660dfb037c353de11
Ihre Transaktionseingabe verweist jedoch derzeit auf das folgende UTXO:
c33858b433ef445db35a84daa4da772895df7f03af4b31f21cfa199ea1c017d9
Was keine bestätigte Transaktion im Hauptnetz ist.
2) Ihr Eingabeskript scheint richtig geformt zu sein, um Ihre P2SH(Multisig)-Ausgabe auszugeben:
zero
[3044022022b97b9372d35acaea70f3735dee290f5697cab7b5d6be6f7cdfe31139fba4f90220651091b83570843d4fe8afe02d81417194908b0f6af6f8f3b8f1ad020592409f01]
[3044022036eff4f54b8bf3f834f7bb6e417a04a6a696047f5c75a896c6f9b624ad87680a02200bf2115b64b3b15647178b69151d4588d8a4ade16a4d66e375d0e1265c79fad601]
[2 [025ab78e076801b45ccb2172bce562103cce1714edbeb02ce6123ce1235eb08c76] [02d1b74577050b696d5886a7afa61d099ea7ab0a3797766f9819dbd72526b0ce51] [03facf04db5d9bee657151e30c21e839489c326a277891ebcf75b736ec1e17fc1f] 3 checkmultisig]
Das letzte Element ist das eingebettete Skript und sollte mit dem 20-B-Digest in Ihrem UTXO hashen, das Sie ausgeben: Es hash160 tatsächlich korrekt zu 6d49586d7529626aaab49812bcd7839aee7e5800
.
Als Referenz lautet das P2SH(Multisig)-Ausgabeskript Ihres UTXO: "hash160 [6d49586d7529626aaab49812bcd7839aee7e5800] equal"
Beachten Sie, dass die Hashes gleich sind, das ist also gut.
3) Sie haben keine Gebühr in Ihre Transaktion aufgenommen. Die Ausgabemenge von 50000 Sats ist identisch mit der UTXO-Menge. Damit diese Transaktion vom Mempool akzeptiert wird, muss eine Mindestgebühr erhoben werden.
Ich hoffe das hilft.
Stefan
Stefan
Jakob C.
Jakob C.
Stefan
Jakob C.
Stefan
Jakob C.
Stefan
Stefan
Jakob C.
Stefan
Jakob C.
Stefan
Jakob C.
Stefan
Stefan
Jakob C.
Stefan
Stefan
Jakob C.
Stefan
Jakob C.
Stefan
Jakob C.
Mursch