public TrustedBroadcastRequest FulfillOffer(
            TransactionSignature clientSignature,
            Script cashout,
            FeeRate feeRate)
        {
            if (clientSignature == null)
            {
                throw new ArgumentNullException(nameof(clientSignature));
            }
            if (feeRate == null)
            {
                throw new ArgumentNullException(nameof(feeRate));
            }
            AssertState(SolverServerStates.WaitingFulfillment);
            Script offerScript = GetOfferScript();

            var offer = GetUnsignedOfferTransaction();
            TransactionBuilder builder = new TransactionBuilder();

            builder.Extensions.Add(new EscrowBuilderExtension());
            builder.AddCoins(InternalState.EscrowedCoin);
            builder.AddKeys(InternalState.EscrowKey);
            var clientKey = InternalState.GetClientEscrowPubKey();

            builder.AddKnownSignature(clientKey, clientSignature);
            builder.SignTransactionInPlace(offer);
            if (!builder.Verify(offer))
            {
                throw new PuzzleException("invalid-signature");
            }
            var offerCoin = offer.Outputs.AsCoins().First().ToScriptCoin(offerScript);

            var         solutions = InternalState.SolvedPuzzles.Select(s => s.SolutionKey).ToArray();
            Transaction fulfill   = new Transaction();

            fulfill.Inputs.Add(new TxIn(offerCoin.Outpoint));
            fulfill.Outputs.Add(new TxOut(offerCoin.Amount, cashout));
            var size = new OfferBuilderExtension().EstimateScriptSigSize(offerCoin.Redeem);

            fulfill.Outputs[0].Value -= feeRate.GetFee(size);

            var signature     = fulfill.Inputs.AsIndexedInputs().First().Sign(InternalState.FulfillKey, offerCoin, SigHash.All);
            var fulfillScript = SolverScriptBuilder.CreateFulfillScript(signature, solutions);

            fulfill.Inputs[0].ScriptSig = fulfillScript + Op.GetPushOp(offerCoin.Redeem.ToBytes());

            InternalState.OfferClientSignature = clientSignature;
            InternalState.Status = SolverServerStates.Completed;
            return(new TrustedBroadcastRequest
            {
                Key = InternalState.FulfillKey,
                PreviousScriptPubKey = offerCoin.ScriptPubKey,
                Transaction = fulfill
            });
        }
示例#2
0
        private PubKey AssertValidSignature(TransactionSignature clientSignature, Transaction offer)
        {
            var signedHash = offer.Inputs.AsIndexedInputs().First().GetSignatureHash(InternalState.EscrowedCoin, clientSignature.SigHash);
            var clientKey  = InternalState.GetClientEscrowPubKey();

            if (!clientKey.Verify(signedHash, clientSignature.Signature))
            {
                throw new PuzzleException("invalid-client-signature");
            }
            return(clientKey);
        }
示例#3
0
        private PubKey AssertValidSignature(TransactionSignature clientSignature, Transaction offer)
        {
            var escrow = EscrowScriptPubKeyParameters.GetFromCoin(InternalState.EscrowedCoin);
            var coin   = InternalState.EscrowedCoin.Clone();

            coin.OverrideScriptCode(escrow.GetInitiatorScriptCode());
            var signedHash = offer.Inputs.AsIndexedInputs().First().GetSignatureHash(coin, clientSignature.SigHash);
            var clientKey  = InternalState.GetClientEscrowPubKey();

            if (!clientKey.Verify(signedHash, clientSignature.Signature))
            {
                throw new PuzzleException("invalid-client-signature");
            }
            return(clientKey);
        }
        public TrustedBroadcastRequest GetSignedOfferTransaction()
        {
            AssertState(SolverServerStates.Completed);
            var offerTransaction         = GetUnsignedOfferTransaction();
            TransactionBuilder txBuilder = new TransactionBuilder();

            txBuilder.Extensions.Add(new EscrowBuilderExtension());
            txBuilder.AddCoins(EscrowedCoin);
            txBuilder.AddKnownSignature(InternalState.EscrowKey.PubKey, InternalState.OfferSignature);
            txBuilder.AddKnownSignature(InternalState.GetClientEscrowPubKey(), InternalState.OfferClientSignature);
            txBuilder.SignTransactionInPlace(offerTransaction);
            return(new TrustedBroadcastRequest
            {
                Key = InternalState.EscrowKey,
                Transaction = offerTransaction,
                PreviousScriptPubKey = EscrowedCoin.ScriptPubKey
            });
        }