protected override async Task InvokeAsyncBase(InvocationContext context) { var name = context.ParseResult.CommandResult.GetArgumentValueOrDefault <string>("name")?.Trim(); if (name is null) { throw new CommandOptionRequiredException("name"); } var dlc = await GetDLC("name", name); if (dlc?.OracleInfo is null) { throw new CommandException("name", "This DLC does not exist"); } if (dlc.BuilderState is null || dlc.FundKeyPath is null) { throw new CommandException("name", "This DLC is not in the right state to get executed"); } var evt = await Repository.GetEvent(dlc.OracleInfo.PubKey, dlc.OracleInfo.RValue); var attestation = context.ParseResult.CommandResult.GetArgumentValueOrDefault <string>("attestation")?.Trim(); Key oracleKey; try { if (attestation is null) { var k = evt?.Attestations?.Select(o => o.Value).FirstOrDefault(); if (k is null) { throw new CommandOptionRequiredException("attestation"); } oracleKey = k; } else { oracleKey = new Key(Encoders.Hex.DecodeData(attestation)); } } catch (CommandOptionRequiredException) { throw; } catch { throw new CommandException("attestation", "Cannot parse the attestation"); } var builder = new DLCTransactionBuilder(dlc.BuilderState.ToString(), Network); var key = await Repository.GetKey(dlc.FundKeyPath); try { var execution = builder.Execute(key, oracleKey); if (evt is Repository.Event) { await Repository.AddAttestation(dlc.OracleInfo, oracleKey); } context.WriteTransaction(execution.CET, Network); } catch (Exception ex) { throw new CommandException("attestation", $"Error while building the CET. ({ex.Message})"); } }
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)); var execution = initiator.Execute(offerKey, oracleSecret); // Can extract? initiator.ExtractAttestation(execution.CET); acceptor.ExtractAttestation(execution.CET); this.testOutputHelper.WriteLine("----Final state------"); testOutputHelper.WriteLine(JObject.Parse(initiator.ExportState()).ToString(Formatting.Indented)); this.testOutputHelper.WriteLine("---------------------"); }