public void FullExchange2() { var initiatorInputKey = new Key(); var acceptorInputKey = new Key(); var offerKey = new Key(); var acceptKey = new Key(); var initiator = new DLCTransactionBuilder(true, null, null, null, Network.RegTest); var acceptor = new DLCTransactionBuilder(false, null, null, null, Network.RegTest); var oracleInfo = OracleInfo.Parse("e4d36e995ff4bba4da2b60ad907d61d36e120d6f7314a3c2a20c6e27a5cd850ff67f8f41718c86f05eb95fab308f5ed788a2a963124299154648f97124caa579"); var requiredCollateral = initiator.Offer(oracleInfo.PubKey, oracleInfo.RValue, new DiscretePayoffs() { new DiscretePayoff("Republicans", Money.Coins(0.4m)), new DiscretePayoff("Democrats", -Money.Coins(0.6m)), new DiscretePayoff("Smith", Money.Zero) }, new Timeouts() { ContractMaturity = 100, ContractTimeout = 200 }); var fund1 = GetFundingPSBT(acceptorInputKey, requiredCollateral); var offer = initiator.FundOffer(offerKey, fund1); var payoff = acceptor.Accept(offer); var fund2 = GetFundingPSBT(initiatorInputKey, payoff.CalculateMinimumCollateral()); var accept = acceptor.FundAccept(acceptKey, fund2); initiator.Sign1(accept); var fundPSBT = initiator.GetFundingPSBT(); fundPSBT.SignWithKeys(initiatorInputKey); var sign = initiator.Sign2(offerKey, fundPSBT); acceptor.Finalize1(sign); fundPSBT = acceptor.GetFundingPSBT(); fundPSBT.SignWithKeys(acceptorInputKey); var fullyVerified = acceptor.Finalize(fundPSBT); foreach (var i in fullyVerified.Inputs) { Assert.NotNull(i.WitScript); } var cet = initiator.BuildCET(offer.ContractInfo[0].Outcome); var keyBytes = Encoders.Hex.DecodeData("d1da46f96f0be50bce2bbabe6bc8633f448ec3f1d14715a0b086b68ed34e095d"); var oracleSecret = new Key(keyBytes); var sig = oracleInfo.RValue.CreateSchnorrSignature(oracleSecret.ToECPrivKey()); Assert.True(oracleInfo.PubKey.SigVerifyBIP340(sig, new DiscreteOutcome("Republicans").Hash)); initiator.BuildSignedCET(offerKey, oracleSecret); this.testOutputHelper.WriteLine("----Final state------"); testOutputHelper.WriteLine(JObject.Parse(initiator.ExportState()).ToString(Formatting.Indented)); this.testOutputHelper.WriteLine("---------------------"); }
public void CanCreateAccept() { var offer = Parse <Messages.Offer>("Data/Offer2.json"); var builder = new DLCTransactionBuilder(false, null, null, null, Network.RegTest); var fundingInputKey = new Key(); var payoffs = builder.Accept(offer); PSBT fundPSBT = GetFundingPSBT(fundingInputKey, payoffs.CalculateMinimumCollateral()); var accept = builder.FundAccept(new Key(), fundPSBT); builder = new DLCTransactionBuilder(true, offer, null, null, Network.RegTest); builder.Sign1(accept); }
public async Task dlc_test() { await foreach (var vector in DLCTestVector.ReadVectors()) { Assert.Equal(vector.ExpectedOfferTLV, Encoders.Hex.EncodeData(vector.Offer.ToTLV())); var accept = new Accept(); accept.TemporaryContractId = vector.Offer.GetTemporaryContractId(); vector.FillFundingInformation(accept, "acceptParams"); accept.PubKeys.FundingKey = vector.AcceptPrivateKey.PubKey; var acceptor = new DLCTransactionBuilder(false, null, null, null, Network.RegTest); acceptor.Accept(vector.Offer, accept.TotalCollateral); Assert.True(acceptor.State.TemporaryContractId); var builtAccept = acceptor.FundAccept(vector.AcceptPrivateKey, accept.CreateSetupPSBT(Network.RegTest)); accept.CetSigs = builtAccept.CetSigs; // this signature is non deterministic... accept.CetSigs.RefundSig = Accept.ParseFromTLV(vector.ExpectedAcceptTLV, Network.RegTest).CetSigs.RefundSig; Assert.Equal(vector.ExpectedAcceptTLV, Encoders.Hex.EncodeData(accept.ToTLV())); var actualFundingTransaction = acceptor.GetFundingTransaction(); var actualRefundTransaction = acceptor.BuildRefund(); var actualCETs = new Transaction[vector.Offer.ContractInfo.Length]; for (int i = 0; i < vector.Offer.ContractInfo.Length; i++) { actualCETs[i] = acceptor.BuildCET(vector.Offer.ContractInfo[i].Outcome); } var offerer = new DLCTransactionBuilder(true, vector.Offer, null, null, Network.RegTest); offerer.Sign1(accept); var fundingPSBT = offerer.GetFundingPSBT(); FillSignatures(fundingPSBT, vector.SignedTxs.FundingTx); var sign = offerer.Sign2(vector.OfferPrivateKey, fundingPSBT); // this signature is non deterministic... sign.CetSigs.RefundSig = Sign.ParseFromTLV(vector.ExpectedSignTLV, Network.RegTest).CetSigs.RefundSig; Assert.Equal(vector.ExpectedSignTLV, Encoders.Hex.EncodeData(sign.ToTLV())); Assert.Equal( RemoveForDebug(vector.UnsignedTxs.FundingTx.ToString()), RemoveForDebug(actualFundingTransaction.ToString())); Assert.Equal( RemoveForDebug(vector.UnsignedTxs.RefundTx.ToString()), RemoveForDebug(actualRefundTransaction.ToString())); for (int i = 0; i < actualCETs.Length; i++) { Assert.Equal( RemoveForDebug(vector.UnsignedTxs.Cets[i].ToString()), RemoveForDebug(actualCETs[i].ToString())); } Assert.NotNull(offerer.State.ContractId); Assert.Equal(offerer.State.ContractId, acceptor.State.ContractId); Assert.False(offerer.State.TemporaryContractId); } }
public void CanCreateAccept() { var offer = Parse <Messages.Offer>("Data/Offer2.json"); offer.SetContractPreimages( new DiscreteOutcome("Republicans_win"), new DiscreteOutcome("Democrats_win"), new DiscreteOutcome("other") ); var builder = new DLCTransactionBuilder(false, null, null, null, Network.RegTest); var fundingInputKey = new Key(); var payoffs = builder.Accept(offer); PSBT fundPSBT = GetFundingPSBT(fundingInputKey, payoffs.CalculateMinimumCollateral()); var accept = builder.FundAccept(new Key(), fundPSBT); builder = new DLCTransactionBuilder(true, offer, null, null, Network.RegTest); builder.Sign1(accept); }
public void FullExchange() { var offerExample = Parse <Messages.Offer>("Data/Offer2.json"); var offerKey = new Key(); var acceptKey = new Key(); var initiatorInputKey = new Key(); var acceptorInputKey = new Key(); var initiator = new DLCTransactionBuilder(true, null, null, null, Network.RegTest); var requiredFund = initiator.Offer(offerExample.OracleInfo.PubKey, offerExample.OracleInfo.RValue, DiscretePayoffs.CreateFromContractInfo(offerExample.ContractInfo, offerExample.TotalCollateral, new[] { new DiscreteOutcome("Republicans_win"), new DiscreteOutcome("Democrats_win"), new DiscreteOutcome("other") }), offerExample.Timeouts); var fund1 = GetFundingPSBT(initiatorInputKey, requiredFund); var offer = initiator.FundOffer(offerKey, fund1); var acceptor = new DLCTransactionBuilder(false, null, null, null, Network.RegTest); var acceptorPayoff = acceptor.Accept(offer); var fund2 = GetFundingPSBT(acceptorInputKey, acceptorPayoff.CalculateMinimumCollateral()); var accept = acceptor.FundAccept(acceptKey, fund2); initiator.Sign1(accept); var fundPSBT = initiator.GetFundingPSBT(); fundPSBT.SignWithKeys(initiatorInputKey); var sign = initiator.Sign2(offerKey, fundPSBT); acceptor.Finalize1(sign); fundPSBT = acceptor.GetFundingPSBT(); fundPSBT.SignWithKeys(acceptorInputKey); var fullyVerified = acceptor.Finalize(fundPSBT); foreach (var i in fullyVerified.Inputs) { Assert.NotNull(i.WitScript); } fundPSBT = acceptor.GetFundingPSBT(); if (fundPSBT.TryGetEstimatedFeeRate(out var estimated)) { Assert.True(estimated > new FeeRate(1.0m), "Fee Rate of the funding PSBT are too low"); } }