Example #1
0
        private static Script CombineMultisig(Script scriptPubKey, TransactionChecker checker, byte[][] sigs1, byte[][] sigs2, HashVersion hashVersion)
        {
            // Combine all the signatures we've got:
            List <TransactionSignature> allsigs = new List <TransactionSignature>();

            foreach (var v in sigs1)
            {
                if (TransactionSignature.IsValid(v))
                {
                    allsigs.Add(new TransactionSignature(v));
                }
            }


            foreach (var v in sigs2)
            {
                if (TransactionSignature.IsValid(v))
                {
                    allsigs.Add(new TransactionSignature(v));
                }
            }

            var multiSigParams = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(scriptPubKey);

            if (multiSigParams == null)
            {
                throw new InvalidOperationException("The scriptPubKey is not a valid multi sig");
            }

            Dictionary <PubKey, TransactionSignature> sigs = new Dictionary <PubKey, TransactionSignature>();

            foreach (var sig in allsigs)
            {
                foreach (var pubkey in multiSigParams.PubKeys)
                {
                    if (sigs.ContainsKey(pubkey))
                    {
                        continue;                         // Already got a sig for this pubkey
                    }
                    ScriptEvaluationContext eval = new ScriptEvaluationContext();
                    if (eval.CheckSig(sig, pubkey, scriptPubKey, checker, hashVersion))
                    {
                        sigs.AddOrReplace(pubkey, sig);
                    }
                }
            }


            // Now build a merged CScript:
            int    nSigsHave = 0;
            Script result    = new Script(OpcodeType.OP_0);          // pop-one-too-many workaround

            foreach (var pubkey in multiSigParams.PubKeys)
            {
                if (sigs.ContainsKey(pubkey))
                {
                    result += Op.GetPushOp(sigs[pubkey].ToBytes());
                    nSigsHave++;
                }
                if (nSigsHave >= multiSigParams.SignatureCount)
                {
                    break;
                }
            }

            // Fill any missing with OP_0:
            for (int i = nSigsHave; i < multiSigParams.SignatureCount; i++)
            {
                result += OpcodeType.OP_0;
            }

            return(result);
        }
		public static Script operator +(Script a, IEnumerable<byte> bytes)
		{
			if(a == null)
				return new Script(Op.GetPushOp(bytes.ToArray()));
			return a + Op.GetPushOp(bytes.ToArray());
		}
        /// <summary>
        /// Mines a new genesis block, to use with a new network.
        /// Typically, 3 such genesis blocks need to be created when bootstrapping a new coin: for Main, Test and Reg networks.
        /// </summary>
        /// <param name="consensusFactory">
        /// The consensus factory used to create transactions and blocks.
        /// Use <see cref="PosConsensusFactory"/> for proof-of-stake based networks.
        /// </param>
        /// <param name="coinbaseText">
        /// Traditionally a news headline from the day of the launch, but could be any string or link.
        /// This will be inserted in the input coinbase transaction script.
        /// It should be shorter than 92 characters.
        /// </param>
        /// <param name="target">
        /// The difficulty target under which the hash of the block need to be.
        /// Some more details: As an example, the target for the Stratis Main network is 00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.
        /// To make it harder to mine the genesis block, have more zeros at the beginning (keeping the length the same). This will make the target smaller, so finding a number under it will be more difficult.
        /// To make it easier to mine the genesis block ,do the opposite. Example of an easy one: 00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.
        /// Make the Test and Reg targets ones easier to find than the Main one so that you don't wait too long to mine the genesis block.
        /// </param>
        /// <param name="genesisReward">
        /// Specify how many coins to put in the genesis transaction's output. These coins are unspendable.
        /// </param>
        /// <param name="version">
        /// The version of the transaction and the block header set in the genesis block.
        /// </param>
        /// <example>
        /// The following example shows the creation of a genesis block.
        /// <code>
        /// Block genesis = MineGenesisBlock(new PosConsensusFactory(), "Some topical headline.", new Target(new uint256("000fffff00000000000000000000000000000000000000000000000000000000")), Money.Coins(50m));
        /// BlockHeader header = genesis.Header;
        /// Console.WriteLine("Make a note of the following values:");
        /// Console.WriteLine("bits: " + header.Bits);
        /// Console.WriteLine("nonce: " + header.Nonce);
        /// Console.WriteLine("time: " + header.Time);
        /// Console.WriteLine("version: " + header.Version);
        /// Console.WriteLine("hash: " + header.GetHash());
        /// Console.WriteLine("merkleroot: " + header.HashMerkleRoot);
        /// </code>
        /// </example>
        /// <returns>A genesis block.</returns>
        public static Block MineGenesisBlock(ConsensusFactory consensusFactory, string coinbaseText, Target target, Money genesisReward, int version = 1)
        {
            if (target == null)
            {
                throw new ArgumentException($"Parameter '{nameof(target)}' cannot be null. Example use: new Target(new uint256(\"0000ffff00000000000000000000000000000000000000000000000000000000\"))");
            }

            if (consensusFactory == null)
            {
                throw new ArgumentException($"Parameter '{nameof(consensusFactory)}' cannot be null. Use 'new ConsensusFactory()' for Bitcoin-like proof-of-work blockchains" +
                                            "and 'new PosConsensusFactory()' for Stratis-like proof-of-stake blockchains.");
            }

            if (string.IsNullOrEmpty(coinbaseText))
            {
                throw new ArgumentException($"Parameter '{nameof(coinbaseText)}' cannot be null. Use a news headline or any other appropriate string.");
            }

            if (coinbaseText.Length >= 92)
            {
                throw new ArgumentException($"Parameter '{nameof(coinbaseText)}' should be shorter than 92 characters.");
            }

            if (genesisReward == null)
            {
                throw new ArgumentException($"Parameter '{nameof(genesisReward)}' cannot be null. Example use: 'Money.Coins(50m)'.");
            }

            DateTimeOffset time     = DateTimeOffset.Now;
            uint           unixTime = Utils.DateTimeToUnixTime(time);

            Transaction txNew = consensusFactory.CreateTransaction();

            txNew.Version = (uint)version;
            txNew.Time    = unixTime;
            txNew.AddInput(new TxIn()
            {
                ScriptSig = new Script(
                    Op.GetPushOp(0),
                    new Op()
                {
                    Code     = (OpcodeType)0x1,
                    PushData = new[] { (byte)42 }
                },
                    Op.GetPushOp(Encoders.ASCII.DecodeData(coinbaseText)))
            });

            txNew.AddOutput(new TxOut()
            {
                Value = genesisReward,
            });

            Block genesis = consensusFactory.CreateBlock();

            genesis.Header.BlockTime = time;
            genesis.Header.Bits      = target;
            genesis.Header.Nonce     = 0;
            genesis.Header.Version   = version;
            genesis.Transactions.Add(txNew);
            genesis.Header.HashPrevBlock = uint256.Zero;
            genesis.UpdateMerkleRoot();

            // Iterate over the nonce until the proof-of-work is valid.
            // This will mean the block header hash is under the target.
            while (!genesis.CheckProofOfWork())
            {
                genesis.Header.Nonce++;
                if (genesis.Header.Nonce == 0)
                {
                    genesis.Header.Time++;
                }
            }

            return(genesis);
        }
Example #4
0
        public Script GenerateScriptSig(Op[] ops, Script script)
        {
            var pushScript = Op.GetPushOp(script._Script);

            return(new Script(ops.Concat(new[] { pushScript })));
        }
Example #5
0
 public Script GenerateScriptSig(TransactionSignature signature)
 {
     return(new Script(
                Op.GetPushOp(signature.ToBytes())
                ));
 }
 public TransactionSignature[] GetMultisigSignatures(Network network)
 {
     return(PayToMultiSigTemplate.Instance.ExtractScriptSigParameters(network,
                                                                      new Script(this.Pushes.Select(p => Op.GetPushOp(p)).ToArray())));
 }
        public Script GenerateScriptSig(Op[] ops, Script redeemScript)
        {
            Op pushScript = Op.GetPushOp(redeemScript._Script);

            return(new Script(ops.Concat(new[] { pushScript })));
        }
Example #8
0
 public TransactionSignature?[]? GetMultisigSignatures()
 {
     return(PayToMultiSigTemplate.Instance.ExtractScriptSigParameters(new Script(Pushes.Select(p => Op.GetPushOp(p)).ToArray())));
 }
Example #9
0
 public Script ToScript()
 {
     return(new Script(_Pushes.Select(p => Op.GetPushOp(p)).ToArray()));
 }
 private static Block CreateGenesisBlock(uint nTime, uint nNonce, uint nBits, int nVersion, Money genesisReward)
 {
     string pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
     Script genesisOutputScript = new Script(Op.GetPushOp(Encoders.Hex.DecodeData("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f")), OpcodeType.OP_CHECKSIG);
     return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
 }