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(); PSBT fundPSBT = GetFundingPSBT(fundingInputKey, Money.Coins(0.4m)); Assert.True(PSBTFundingTemplate.TryParse(fundPSBT.ToBase64(), fundPSBT.Network, out var template)); var accept = builder.Accept(offer, template); builder = new DLCTransactionBuilder(true, offer, accept, null, Network.RegTest); Assert.True(builder.VerifyRemoteCetSigs()); Assert.True(builder.VerifyRemoteRefundSignature()); }
public void FullExchange2() { var initiatorInputKey = new Key(); var acceptorInputKey = new Key(); var fund1 = GetFundingPSBT(initiatorInputKey, Money.Coins(0.6m)); var fund2 = GetFundingPSBT(acceptorInputKey, Money.Coins(0.4m)); var initiator = new DLCTransactionBuilder(true, null, null, null, Network.RegTest); var acceptor = new DLCTransactionBuilder(false, null, null, null, Network.RegTest); var oracleInfo = OracleInfo.Parse("156c7d1c7922f0aa1168d9e21ac77ea88bbbe05e24e70a08bbe0519778f2e5daea3a68d8749b81682513b0479418d289d17e24d4820df2ce979f1a56a63ca525"); var offer = initiator.Offer(PSBTFundingTemplate.Parse(fund1), oracleInfo, ContractInfo.CreateContract( ("Republicans_win", Money.Coins(1.0m)), ("Democrats_win", Money.Coins(0m)), ("other", Money.Coins(0.6m))), new Timeouts() { ContractMaturity = 100, ContractTimeout = 200 }); var accept = acceptor.Accept(offer, PSBTFundingTemplate.Parse(fund2)); initiator.VerifySign(accept); var fundPSBT = initiator.BuildFundingPSBT(); fundPSBT.SignWithKeys(initiatorInputKey); var sign = initiator.EndSign(fundPSBT); acceptor.VerifySign(sign); fundPSBT = acceptor.BuildFundingPSBT(); fundPSBT.SignWithKeys(acceptorInputKey); var psbt = acceptor.CombineFunding(fundPSBT); psbt = psbt.Finalize(); var fullyVerified = psbt.ExtractTransaction(); foreach (var i in fullyVerified.Inputs) { Assert.NotNull(i.WitScript); } var cet = initiator.BuildCET(offer.ContractInfo[0].Outcome); var keyBytes = Encoders.Hex.DecodeData("39eabd151030f4f2d518fb8a8d00f679aa9e034c66263032a1245a04cfbc592b"); //Array.Reverse(keyBytes); var oracleSecret = new Key(keyBytes); initiator.BuildSignedCET(oracleSecret); }
public virtual void FillFromTemplateFunding(PSBTFundingTemplate fundingTemplate, PubKey fundingKey) { FundingInputs = fundingTemplate.FundingCoins .Select(input => new FundingInput() { Outpoint = input.Outpoint, Output = input.TxOut }).ToArray(); ChangeAddress = fundingTemplate.Change?.GetDestinationAddress(fundingTemplate.Network) ?? throw new InvalidOperationException("No change address output found"); PubKeys = new PubKeyObject() { PayoutAddress = fundingTemplate.PayoutAddress.GetDestinationAddress(fundingTemplate.Network) ?? throw new InvalidOperationException("No payout address output found"), FundingKey = fundingKey }; TotalCollateral = fundingTemplate.Collateral; } }
public Offer Offer(PSBTFundingTemplate fundingTemplate, OracleInfo oracleInfo, ContractInfo[] contractInfo, Timeouts timeouts) { if (!isInitiator) { throw new InvalidOperationException("The acceptor can't initiate an offer"); } var fundingKey = this.FundingKey ?? new Key(); Offer offer = new Offer() { OracleInfo = oracleInfo, ContractInfo = contractInfo, Timeouts = timeouts }; offer.FillFromTemplateFunding(fundingTemplate, fundingKey.PubKey); this.FundingKey = fundingKey; this.OracleInfo = oracleInfo; FillStateFrom(offer); return(offer); }
public Accept Accept(Offer offer, PSBTFundingTemplate fundingTemplate) { if (isInitiator) { throw new InvalidOperationException("The initiator can't accept"); } if (fundingTemplate == null) { throw new ArgumentNullException(nameof(fundingTemplate)); } this.FillStateFrom(offer); this.FundingKey = this.FundingKey ?? new Key(); Accept accept = new Accept(); accept.FillFromTemplateFunding(fundingTemplate, FundingKey.PubKey); FillStateFrom(accept); accept.CetSigs = CreateCetSigs(); accept.EventId = "14965dcd10a1f0464c4c5cf7f2e9c67b2bcc6f8a971ccc647d7fec1c885f3afe"; //accept.EventId = CalculateEventId(); return(accept); }
public static AcceptorTest Open(string folder, Network network) { var settings = network == Network.RegTest ? Settings : TestnetSettings; AcceptorTest t = new AcceptorTest(); var fundingOverride = Path.Combine(folder, "FundingOverride.hex"); if (File.Exists(fundingOverride)) { t.FundingOverride = Transaction.Parse(File.ReadAllText(fundingOverride), network); } t.Offer = Parse <Offer>(Path.Combine(folder, "Offer.json"), settings); t.Sign = Parse <Sign>(Path.Combine(folder, "Sign.json"), settings); var attestation = Path.Combine(folder, "OracleAttestation.hex"); if (File.Exists(attestation)) { t.OracleAttestation = new Key(Encoders.Hex.DecodeData(File.ReadAllText(attestation))); } t.Builder = new DLCTransactionBuilder(false, null, null, null, network); t.FundingTemplate = PSBTFundingTemplate.Parse(File.ReadAllText(Path.Combine(folder, "FundingTemplate.psbt")), network); return(t); }
public void FullExchange() { var offerExample = Parse <Messages.Offer>("Data/Offer2.json"); var initiatorInputKey = new Key(); var acceptorInputKey = new Key(); var fund1 = GetFundingPSBT(initiatorInputKey, Money.Coins(0.6m)); var fund2 = GetFundingPSBT(acceptorInputKey, Money.Coins(0.4m)); var initiator = new DLCTransactionBuilder(true, null, null, null, Network.RegTest); var acceptor = new DLCTransactionBuilder(false, null, null, null, Network.RegTest); var offer = initiator.Offer(PSBTFundingTemplate.Parse(fund1), offerExample.OracleInfo, offerExample.ContractInfo, offerExample.Timeouts); var accept = acceptor.Accept(offer, PSBTFundingTemplate.Parse(fund2)); initiator.VerifySign(accept); var fundPSBT = initiator.BuildFundingPSBT(); fundPSBT.SignWithKeys(initiatorInputKey); var sign = initiator.EndSign(fundPSBT); acceptor.VerifySign(sign); fundPSBT = acceptor.BuildFundingPSBT(); fundPSBT.SignWithKeys(acceptorInputKey); fundPSBT = acceptor.CombineFunding(fundPSBT); fundPSBT = fundPSBT.Finalize(); var fullyVerified = fundPSBT.ExtractTransaction(); foreach (var i in fullyVerified.Inputs) { Assert.NotNull(i.WitScript); } if (fundPSBT.TryGetEstimatedFeeRate(out var estimated)) { Assert.True(estimated > new FeeRate(1.0m), "Fee Rate of the funding PSBT are too low"); } }
public override void FillFromTemplateFunding(PSBTFundingTemplate fundingTemplate, PubKey fundingKey) { FeeRate = fundingTemplate.FeeRate; base.FillFromTemplateFunding(fundingTemplate, fundingKey); }