Ejemplo n.º 1
0
 private static bool TryCreate(ReadOnlySpan <byte> input64, [MaybeNullWhen(false)] out OracleInfo oracleInfo)
 {
     oracleInfo = null;
     if (input64.Length != 64)
     {
         return(false);
     }
     if (!ECXOnlyPubKey.TryCreate(input64.Slice(0, 32), Context.Instance, out var pubkey) || pubkey is null)
     {
         return(false);
     }
     if (!SchnorrNonce.TryCreate(input64.Slice(32), out var rValue) || rValue is null)
     {
         return(false);
     }
     oracleInfo = new OracleInfo(pubkey, rValue);
     return(true);
 }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        public static bool TryParse(string str, out OracleInfo?oracleInfo)
        {
            oracleInfo = null;
            if (str == null)
            {
                throw new ArgumentNullException(nameof(str));
            }
            var bytes = Encoders.Hex.DecodeData(str);

            if (bytes.Length != 64)
            {
                return(false);
            }
            if (!ECXOnlyPubKey.TryCreate(bytes.AsSpan().Slice(0, 32), Context.Instance, out var pubkey) || pubkey is null)
            {
                return(false);
            }
            if (!SchnorrNonce.TryCreate(bytes.AsSpan().Slice(32), out var rValue) || rValue is null)
            {
                return(false);
            }
            oracleInfo = new OracleInfo(pubkey, rValue);
            return(true);
        }
Ejemplo n.º 4
0
        public void WriteTLV(TLVWriter writer)
        {
            if (ChainHash is null)
            {
                throw new InvalidOperationException($"{nameof(ChainHash)} is not set");
            }
            if (ContractInfo is null)
            {
                throw new InvalidOperationException($"{nameof(ContractInfo)} is not set");
            }
            if (OracleInfo is null)
            {
                throw new InvalidOperationException($"{nameof(OracleInfo)} is not set");
            }
            if (TotalCollateral is null)
            {
                throw new InvalidOperationException($"{nameof(TotalCollateral)} is not set");
            }
            if (PubKeys?.FundingKey is null)
            {
                throw new InvalidOperationException($"{nameof(PubKeys.FundingKey)} is not set");
            }
            if (PubKeys?.PayoutAddress is null)
            {
                throw new InvalidOperationException($"{nameof(PubKeys.PayoutAddress)} is not set");
            }
            if (FundingInputs is null)
            {
                throw new InvalidOperationException($"{nameof(FundingInputs)} is not set");
            }
            if (ChangeAddress is null)
            {
                throw new InvalidOperationException($"{nameof(ChangeAddress)} is not set");
            }
            if (FeeRate is null)
            {
                throw new InvalidOperationException($"{nameof(FeeRate)} is not set");
            }
            if (Timeouts is null)
            {
                throw new InvalidOperationException($"{nameof(Timeouts)} is not set");
            }
            writer.WriteU16(TLVType);
            writer.WriteByte(0);             // contract_flags
            writer.WriteUInt256(ChainHash);
            using (var ciRecord = writer.StartWriteRecord(TLVContractInfoType))
            {
                foreach (var ci in ContractInfo)
                {
                    ciRecord.WriteBytes(ci.Outcome.Hash);
                    ciRecord.WriteU64((ulong)ci.Payout.Satoshi);
                }
            }
            Span <byte> buf = stackalloc byte[64];

            using (var oracleRecord = writer.StartWriteRecord(TLVOracleInfoType))
            {
                OracleInfo.WriteToBytes(buf);
                oracleRecord.WriteBytes(buf);
            }
            PubKeys.FundingKey.Compress().ToBytes(buf, out _);
            writer.WriteBytes(buf.Slice(0, 33));
            writer.WriteScript(PubKeys.PayoutAddress.ScriptPubKey);
            writer.WriteU64((ulong)TotalCollateral.Satoshi);
            writer.WriteU16((ushort)FundingInputs.Length);
            foreach (var input in FundingInputs)
            {
                input.WriteTLV(writer);
            }
            writer.WriteScript(ChangeAddress.ScriptPubKey);
            writer.WriteU64((ulong)FeeRate.SatoshiPerByte);
            writer.WriteU32((uint)Timeouts.ContractMaturity);
            writer.WriteU32((uint)Timeouts.ContractTimeout);
        }
Ejemplo n.º 5
0
        public void ReadTLV(TLVReader reader, Network network)
        {
            if (reader.ReadU16() != TLVType)
            {
                throw new FormatException("Invalid TLV type for offer");
            }
            reader.ReadByte();             // contract_flags
            ChainHash = reader.ReadUInt256();
            if (network.GenesisHash != network.GenesisHash)
            {
                throw new FormatException("Invalid ChainHash");
            }
            Span <byte> buf = stackalloc byte[64];

            using (var ciRecord = reader.StartReadRecord())
            {
                if (ciRecord.Type != TLVContractInfoType)
                {
                    throw new FormatException("Invalid TLV type for contract info");
                }
                List <ContractInfo> cis = new List <ContractInfo>();
                while (!ciRecord.IsEnd)
                {
                    ciRecord.ReadBytes(buf.Slice(0, 32));
                    var sats = ciRecord.ReadU64();
                    cis.Add(new Messages.ContractInfo(new DiscreteOutcome(buf.Slice(0, 32).ToArray()), Money.Satoshis(sats)));
                }
                ContractInfo = cis.ToArray();
            }
            using (var oracleRecord = reader.StartReadRecord())
            {
                if (oracleRecord.Type != TLVOracleInfoType)
                {
                    throw new FormatException("Invalid TLV type for oracle info");
                }
                oracleRecord.ReadBytes(buf.Slice(0, 64));
                OracleInfo = OracleInfo.Create(buf);
            }
            PubKeys = new PubKeyObject();
            reader.ReadBytes(buf.Slice(0, 33));
            PubKeys.FundingKey    = new PubKey(buf.Slice(0, 33).ToArray());
            PubKeys.PayoutAddress = reader.ReadScript().GetDestinationAddress(network);
            if (PubKeys.PayoutAddress is null)
            {
                throw new FormatException("Invalid script");
            }
            TotalCollateral = Money.Satoshis(reader.ReadU64());
            var fiCount             = reader.ReadU16();
            List <FundingInput> fis = new List <FundingInput>();

            while (fiCount > 0)
            {
                fis.Add(FundingInput.ParseFromTLV(reader, network));
                fiCount--;
            }
            FundingInputs = fis.ToArray();
            ChangeAddress = reader.ReadScript().GetDestinationAddress(network);
            if (ChangeAddress is null)
            {
                throw new FormatException("Invalid script");
            }
            FeeRate  = new FeeRate(Money.Satoshis(reader.ReadU64()), 1);
            Timeouts = new Timeouts()
            {
                ContractMaturity = reader.ReadU32(),
                ContractTimeout  = reader.ReadU32()
            };
        }