コード例 #1
0
        /// <summary>
        /// Get the 'sender' of a transaction.
        /// </summary>
        /// <param name="tx"></param>
        /// <param name="coinView"></param>
        /// <param name="blockTxs"></param>
        /// <returns></returns>
        public static GetSenderResult GetSender(Transaction tx, CoinView coinView, IList <Transaction> blockTxs)
        {
            OutPoint prevOut = tx.Inputs[0].PrevOut;

            // Check the txes in this block first
            if (blockTxs != null && blockTxs.Count > 0)
            {
                foreach (Transaction btx in blockTxs)
                {
                    if (btx.GetHash() == prevOut.Hash)
                    {
                        Script script = btx.Outputs[prevOut.N].ScriptPubKey;
                        return(GetAddressFromScript(script));
                    }
                }
            }

            // Check the utxoset for the p2pk of the unspent output for this transaction
            if (coinView != null)
            {
                FetchCoinsResponse fetchCoinResult = coinView.FetchCoinsAsync(new uint256[] { prevOut.Hash }).Result;
                UnspentOutputs     unspentOutputs  = fetchCoinResult.UnspentOutputs.FirstOrDefault();

                if (unspentOutputs == null)
                {
                    throw new Exception("Unspent outputs to smart contract transaction are not present in coinview");
                }

                Script script = unspentOutputs.Outputs[prevOut.N].ScriptPubKey;

                return(GetAddressFromScript(script));
            }

            return(GetSenderResult.CreateFailure("Unable to get the sender of the transaction"));
        }
コード例 #2
0
        /// <inheritdoc />
        public GetSenderResult GetSender(Transaction tx, ICoinView coinView, IList <Transaction> blockTxs)
        {
            OutPoint prevOut = tx.Inputs[0].PrevOut;

            // Check the txes in this block first
            if (blockTxs != null && blockTxs.Count > 0)
            {
                foreach (Transaction btx in blockTxs)
                {
                    if (btx.GetHash() == prevOut.Hash)
                    {
                        if (prevOut.N >= btx.Outputs.Count)
                        {
                            return(GetSenderResult.CreateFailure(InvalidOutputIndex));
                        }

                        Script script = btx.Outputs[prevOut.N].ScriptPubKey;
                        return(this.GetAddressFromScript(script));
                    }
                }
            }

            // Check the utxoset for the p2pk of the unspent output for this transaction
            if (coinView != null)
            {
                FetchCoinsResponse fetchCoinResult = coinView.FetchCoins(new OutPoint[] { prevOut });

                // The result from the coinview should never be null, so we do not check for that condition here.
                // It will simply not contain the requested outputs in the dictionary if they did not exist in the coindb.
                if (fetchCoinResult.UnspentOutputs.All(o => o.Key != prevOut))
                {
                    return(GetSenderResult.CreateFailure(OutputsNotInCoinView));
                }

                UnspentOutput unspentOutputs = fetchCoinResult.UnspentOutputs.First(o => o.Key == prevOut).Value;

                // Since we now fetch a specific UTXO from the coindb instead of an entire transaction, it is no longer meaningful to check
                // (for the coindb at least - block transactions are handled separately above) whether the prevOut index is within bounds.
                // So that check has been removed from here and we proceed directly to checking spent-ness.
                if (unspentOutputs.Coins == null)
                {
                    return(GetSenderResult.CreateFailure(OutputAlreadySpent));
                }

                TxOut senderOutput = unspentOutputs.Coins.TxOut;

                return(this.GetAddressFromScript(senderOutput.ScriptPubKey));
            }

            return(GetSenderResult.CreateFailure(UnableToGetSender));
        }
コード例 #3
0
        /// <inheritdoc />
        public GetSenderResult GetSender(Transaction tx, ICoinView coinView, IList <Transaction> blockTxs)
        {
            OutPoint prevOut = tx.Inputs[0].PrevOut;

            // Check the txes in this block first
            if (blockTxs != null && blockTxs.Count > 0)
            {
                foreach (Transaction btx in blockTxs)
                {
                    if (btx.GetHash() == prevOut.Hash)
                    {
                        if (prevOut.N >= btx.Outputs.Count)
                        {
                            return(GetSenderResult.CreateFailure(InvalidOutputIndex));
                        }

                        Script script = btx.Outputs[prevOut.N].ScriptPubKey;
                        return(this.GetAddressFromScript(script));
                    }
                }
            }

            // Check the utxoset for the p2pk of the unspent output for this transaction
            if (coinView != null)
            {
                FetchCoinsResponse fetchCoinResult = coinView.FetchCoinsAsync(new uint256[] { prevOut.Hash }).Result;
                UnspentOutputs     unspentOutputs  = fetchCoinResult.UnspentOutputs.FirstOrDefault();

                if (unspentOutputs == null)
                {
                    return(GetSenderResult.CreateFailure(OutputsNotInCoinView));
                }

                if (prevOut.N >= unspentOutputs.Outputs.Length)
                {
                    return(GetSenderResult.CreateFailure(InvalidOutputIndex));
                }

                TxOut senderOutput = unspentOutputs.Outputs[prevOut.N];

                if (senderOutput == null)
                {
                    return(GetSenderResult.CreateFailure(OutputAlreadySpent));
                }

                return(this.GetAddressFromScript(senderOutput.ScriptPubKey));
            }

            return(GetSenderResult.CreateFailure(UnableToGetSender));
        }
コード例 #4
0
        /// <summary>
        /// Get the address from a P2PK or a P2PKH
        /// </summary>
        /// <param name="script"></param>
        /// <returns></returns>
        public static GetSenderResult GetAddressFromScript(Script script)
        {
            PubKey payToPubKey = PayToPubkeyTemplate.Instance.ExtractScriptPubKeyParameters(script);

            if (payToPubKey != null)
            {
                var address = new uint160(payToPubKey.Hash.ToBytes());
                return(GetSenderResult.CreateSuccess(address));
            }

            if (PayToPubkeyHashTemplate.Instance.CheckScriptPubKey(script))
            {
                var address = new uint160(PayToPubkeyHashTemplate.Instance.ExtractScriptPubKeyParameters(script).ToBytes());
                return(GetSenderResult.CreateSuccess(address));
            }
            return(GetSenderResult.CreateFailure("Addresses can only be retrieved from Pay to Pub Key or Pay to Pub Key Hash"));
        }