public async Task SpendCommitmemtByMultisig(ICommitment commitment, ICoin spendingCoin, string destination) { TransactionBuildContext context = new TransactionBuildContext(_connectionParams.Network, _pregeneratedOutputsQueueFactory); var destinationAddress = BitcoinAddress.Create(destination); await context.Build(async() => { TransactionBuilder builder = new TransactionBuilder(); builder.AddCoins(spendingCoin); if (OpenAssetsHelper.IsBitcoin(commitment.AssetId)) { builder.Send(destinationAddress, spendingCoin.Amount); } else { builder.SendAsset(destinationAddress, ((ColoredCoin)spendingCoin).Amount); } await _transactionBuildHelper.AddFee(builder, context); var tr = builder.BuildTransaction(false); var scriptParams = new OffchainScriptParams { IsMultisig = true, RedeemScript = commitment.LockedScript.ToScript().ToBytes(), Pushes = new[] { new byte[0], new byte[0], new byte[0] } }; tr.Inputs[0].ScriptSig = OffchainScriptCommitmentTemplate.GenerateScriptSig(scriptParams); var signed = await _signatureApiProvider.SignTransaction(tr.ToHex()); var signedTr = new Transaction(signed); var id = Guid.NewGuid(); await _rpcBitcoinClient.BroadcastTransaction(signedTr, id); await _lykkeTransactionBuilderService.SaveSpentOutputs(id, signedTr); return(Task.CompletedTask); }); }
public async Task TestSpendScript() { var multisigFirstPartPk = new BitcoinSecret("cMahea7zqjxrtgAbB7LSGbcZDo359LNtib5kYpwbiSqBqvs6cqPV"); var singlePk = new BitcoinSecret("cPsQrkj1xqQUomDyDHXqsgnjCbZ41yfr923tWR7EuaSKH7WtDXb9"); var revokePk = new BitcoinSecret("cPsQrkj1xqQUomDyDHXqsgnjCbZ41yfr923tWR7EuaSKH7WtDXb9"); var bitcoinClient = Config.Services.GetService <IRpcBitcoinClient>(); var bitcoinOutService = Config.Services.GetService <IBitcoinOutputsService>(); var assetRepo = Config.Services.GetService <IAssetRepository>(); var helper = Config.Services.GetService <ITransactionBuildHelper>(); var prevTx = new Transaction("0100000002347328a86bbd9d2a40e420e8d0a7da9986fd916b3ca02365c8d480936067a36cce0000008a47304402201eebb0365b67e534b72302987453d43833594965d7180c746dd5b1af27a7d6be02204496df6a47858fe9a3f6fd09dff90382e7c22a5a52c41300466bcfed808a1f39014104ff20028f41de7e2bac4f8e90884becad36c1390d2ab991a16fbcf745db478fd37cbf65c57a84e5a485bd5934c659f94aff35fe9fc50ebd2281ede40366190f57ffffffffab496631bf50d77e36303fb6156c3c73809c2023048e7e28b59c7272a8c509fc2f0000008b483045022100c6cb855117224ff9e7334ccf1030649c34a8e48eb7b6c7c4bf746d3ff67c1641022038257e6100c34c568f24d490a69b4591f93a56c433b6ad30102627a5a48ce0da01410496052ef8fb660bb338ba186dd2f52362c66b23f824295a6b74d0c60cf61a12e2b1f8b97512e09c20693f00dba9df3c644f245c120983d0582e4a88cb466ffa69ffffffff0300e1f5050000000017a914a9168848118a24ff8f848bac2eaaa248105b0307870084d717000000001976a91497a515ec03d9aada5e6f0d895f4aa10eb8f07e8d88ac800f0200000000001976a914ed75405f426601f5493117b5a22dc0082269e32288ac00000000"); var coin = new Coin(prevTx, 0); var redeem = CreateScript(multisigFirstPartPk.PubKey, revokePk.PubKey, singlePk.PubKey); var addr = redeem.WitHash.ScriptPubKey.Hash.GetAddress(Network.TestNet); var scriptCoin = new ScriptCoin(coin, redeem); TransactionBuilder builder = new TransactionBuilder(); TransactionBuildContext context = new TransactionBuildContext(Network.TestNet, null, null); //builder.AddKeys(pk); builder.AddCoins(scriptCoin); builder.Send(multisigFirstPartPk.PubKey.ScriptPubKey, "0.5"); builder.SetChange(addr); builder.SendFees("0.001"); var tr = builder.BuildTransaction(false); //tr.Inputs[0].Sequence = new Sequence(144); // tr.Version = 2; var hash = Script.SignatureHash(redeem, tr, 0, SigHash.All, scriptCoin.Amount, HashVersion.Witness); var signature = singlePk.PrivateKey.Sign(hash, SigHash.All).Signature.ToDER().Concat(new byte[] { 0x01 }).ToArray(); var push1 = multisigFirstPartPk.PrivateKey.Sign(hash, SigHash.All).Signature.ToDER().Concat(new byte[] { 0x01 }).ToArray(); var push2 = revokePk.PrivateKey.Sign(hash, SigHash.All).Signature.ToDER().Concat(new byte[] { 0x01 }).ToArray(); var scriptParams = new OffchainScriptParams { IsMultisig = true, RedeemScript = redeem.ToBytes(), Pushes = new[] { new byte[0], new byte[0], new byte[0], } }; tr.Inputs[0].WitScript = OffchainScriptCommitmentTemplate.GenerateScriptSig(scriptParams); tr.Inputs[0].ScriptSig = new Script(Op.GetPushOp(redeem.WitHash.ScriptPubKey.ToBytes(true))); ScriptError error; tr.Inputs.AsIndexedInputs().First().VerifyScript(scriptCoin.ScriptPubKey, out error); await bitcoinClient.BroadcastTransaction(tr, Guid.NewGuid()); //CheckSequence(1, tr, 0); //CheckSig(signature.ToBytes(), pk.PubKey.ToBytes(), redeem, new TransactionChecker(tr, 0, scriptCoin.Amount), 0); }