На примере здесь: https://bitcoinj.github.io/working-with-contracts
Я считаю, что все сделал правильно. Тем не менее, моя программа не может распространяться правильно или из-за ошибки tx, и я не могу определить, почему
Несколько вещей, которые я считаю причиной
1) Моя одноранговая группа. соответствующим образом (например, использую ли я класс UTXO или TransactionSignature) 3) Попытка потратить средства с отслеживаемого адреса. У меня есть необходимые ключи для разблокировки UTXO, но я хотел бы посмотреть, смогу ли я потратить средства без использования класса кошелька 4) В целом поддержка Multisig для биткойнов отсутствует или неполная. я надеюсь, что это не так, как я действительно хотел бы, чтобы это работало. Но - я не думаю, что это самая большая проблема, потому что я провел модульные тесты, и все они все еще проверяются.
Шаг через код, чтобы быть тщательным:
Создайте 3 ECKeys для мультиподписного контракта 2 из 3, поместите их в список, создайте сценарий выкупа, который сортирует ключи в лексикографическом порядке и записывает сценарий мультиподписи m-of-n, затем создайте экземпляр объекта транзакции и назначьте его в качестве ВЫХОДА. который я буду использовать в качестве ВХОДА (сумма + сценарий погашения), также известного как UTXO, который я буду тратить (РЕДАКТИРОВАТЬ: краткое упоминание. На самом деле ECKeys, которые я использую, являются жестко закодированными значениями, которые я сделал некоторое время назад, это для иллюстрации. Я также должен упомянуть, что это мультиподпись P2SH, а не необработанная нестандартная мультиподпись.
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);
Создайте второй объект транзакции, который я буду использовать для сборки выходного сценария, также известного как адрес (значение + пункт назначения), на который я буду подписывать свой UTXO. Также где sigHash подписан двумя моими ключами и добавлен в scriptSig транзакции
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);
теперь вручную подписывайте входы... (подписи в том же порядке, что и в скрипте)
//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);
... теперь создайте multisignputscript, проверьте и транслируйте tx
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");
хорошо... это не распространяется, но проверка подтверждается. и я даже не знаю, является ли это проблемой сети, поскольку это проблема кода, потому что, когда я изменяю значение в выходном сценарии на> баланс UTXO, он не генерирует исключение InsufficientMoneyException, как я думаю, это должно быть. Я бы показал некоторые журналы ошибок, но их нет. Единственная ошибка заключается в том, что когда я меняю createmultisiginputscript на createP2SHmultisiginputscript, консоль выдает ненулевую ошибку nulldummy, которую у меня также возникают проблемы с исправлением, поэтому я никогда не мог узнать, является ли переход на этот метод правильным решением. Я думаю, что я правильно настроил соединение с группой пиров.
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();
}
Так что я действительно не понимаю... Я пришел к выводу, что мое понимание как-то не так. Извините за запутанный длинный пост. Прошли дни. Кто-нибудь может помочь?
РЕДАКТИРОВАТЬ: вот необработанная транзакция
В шестнадцатеричном формате:
В журналах:
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 01-12 17:49:20,670 2507-2507/com.cryptoapp.app I/System.out: комиссия 0,7 байт BTC, 000 BTC. 01-12 17:49:20.670 2507-2507/com.cryptoapp.app I/System.out: prps НЕИЗВЕСТНО
Пара комментариев по результатам проверки опубликованных вами данных о транзакциях.
1) Я проверил UTXO, с которого вы тратите, это UTXO.
9e7562d19165077d566af47bfbc18283629ed6799da8862660dfb037c353de11
Тем не менее, ваша транзакция в настоящее время ссылается на следующий UTXO:
c33858b433ef445db35a84daa4da772895df7f03af4b31f21cfa199ea1c017d9
Что не является подтвержденной транзакцией в основной сети.
2) Ваш входной скрипт кажется правильно сформированным, чтобы использовать вывод P2SH (Multisig):
zero
[3044022022b97b9372d35acaea70f3735dee290f5697cab7b5d6be6f7cdfe31139fba4f90220651091b83570843d4fe8afe02d81417194908b0f6af6f8f3b8f1ad020592409f01]
[3044022036eff4f54b8bf3f834f7bb6e417a04a6a696047f5c75a896c6f9b624ad87680a02200bf2115b64b3b15647178b69151d4588d8a4ade16a4d66e375d0e1265c79fad601]
[2 [025ab78e076801b45ccb2172bce562103cce1714edbeb02ce6123ce1235eb08c76] [02d1b74577050b696d5886a7afa61d099ea7ab0a3797766f9819dbd72526b0ce51] [03facf04db5d9bee657151e30c21e839489c326a277891ebcf75b736ec1e17fc1f] 3 checkmultisig]
Последним элементом является встроенный скрипт, который должен хэшировать до 20-битного дайджеста в вашем UTXO, который вы тратите: он действительно правильно хэширует 160 до 6d49586d7529626aaab49812bcd7839aee7e5800
.
Для справки, выходной сценарий P2SH (Multisig) вашего UTXO: "hash160 [6d49586d7529626aaab49812bcd7839aee7e5800] equal"
обратите внимание, что хэши одинаковы, так что это хорошо.
3) Вы не включили комиссию в свою транзакцию. Сумма вывода 50000 сатоши идентична сумме UTXO. Чтобы эта транзакция была принята мемпулом, должна быть минимальная комиссия.
Надеюсь, это поможет.
Стивен
Стивен
Джеймс С.
Джеймс С.
Стивен
Джеймс С.
Стивен
Джеймс С.
Стивен
Стивен
Джеймс С.
Стивен
Джеймс С.
Стивен
Джеймс С.
Стивен
Стивен
Джеймс С.
Стивен
Стивен
Джеймс С.
Стивен
Джеймс С.
Стивен
Джеймс С.
Марч