예제 #1
0
        public void QuickTestsOnKeyIdBytes()
        {
            var a  = new KeyId("93e5d305cad2588d5fb254065fe48ce446028ba3");
            var b  = new ScriptId("93e5d305cad2588d5fb254065fe48ce446028ba3");
            var b2 = new WitKeyId("93e5d305cad2588d5fb254065fe48ce446028ba3");

            Assert.Equal(a.ToString(), b.ToString());
            Assert.Equal(a.ToString(), b2.ToString());
            Assert.Equal("93e5d305cad2588d5fb254065fe48ce446028ba3", a.ToString());
            var bytes = Encoders.Hex.DecodeData("93e5d305cad2588d5fb254065fe48ce446028ba3");

            Assert.True(StructuralComparisons.StructuralComparer.Compare(a.ToBytes(), b.ToBytes()) == 0);
            Assert.True(StructuralComparisons.StructuralComparer.Compare(b2.ToBytes(), b.ToBytes()) == 0);

            var c  = new KeyId(bytes);
            var d  = new ScriptId(bytes);
            var d2 = new WitKeyId(bytes);

            Assert.Equal(a, c);
            Assert.Equal(d, b);
            Assert.Equal(b2, d2);
            Assert.Equal(c.ToString(), d.ToString());
            Assert.Equal(c.ToString(), d2.ToString());
            Assert.Equal("93e5d305cad2588d5fb254065fe48ce446028ba3", c.ToString());
            Assert.True(StructuralComparisons.StructuralComparer.Compare(c.ToBytes(), d.ToBytes()) == 0);
            Assert.True(StructuralComparisons.StructuralComparer.Compare(c.ToBytes(), d2.ToBytes()) == 0);

            var e = new WitScriptId("93e5d305cad2588d5fb254065fe48ce446028ba380e6ee663baea9cd10550089");

            Assert.Equal("93e5d305cad2588d5fb254065fe48ce446028ba380e6ee663baea9cd10550089", e.ToString());
            bytes = Encoders.Hex.DecodeData("93e5d305cad2588d5fb254065fe48ce446028ba380e6ee663baea9cd10550089");
            var e2 = new WitScriptId(bytes);

            Assert.Equal(e, e2);
        }
 public Script GenerateScriptPubKey(KeyId pubkeyHash)
 {
     return(new Script(
                OpcodeType.OP_DUP,
                OpcodeType.OP_HASH160,
                Op.GetPushOp(pubkeyHash.ToBytes()),
                OpcodeType.OP_EQUALVERIFY,
                OpcodeType.OP_CHECKSIG
                ));
 }
예제 #3
0
 public static void CheckTransaction(IStateRepositoryRoot stateRepositoryRoot, Transaction transaction)
 {
     foreach (TxOut output in transaction.Outputs)
     {
         if (PayToPubkeyHashTemplate.Instance.CheckScriptPubKey(output.ScriptPubKey))
         {
             KeyId p2pkhParams = PayToPubkeyHashTemplate.Instance.ExtractScriptPubKeyParameters(output.ScriptPubKey);
             var   to          = new uint160(p2pkhParams.ToBytes());
             if (stateRepositoryRoot.GetAccountState(to) != null)
             {
                 new ConsensusError("p2pkh-to-contract", "attempted send directly to contract address. use OP_CALL instead.").Throw();
             }
         }
     }
 }
예제 #4
0
 private void CheckTransaction(Transaction transaction)
 {
     foreach (TxOut output in transaction.Outputs)
     {
         if (PayToPubkeyHashTemplate.Instance.CheckScriptPubKey(output.ScriptPubKey))
         {
             KeyId   p2pkhParams = PayToPubkeyHashTemplate.Instance.ExtractScriptPubKeyParameters(output.ScriptPubKey);
             uint160 to          = new uint160(p2pkhParams.ToBytes());
             if (this.ContractCoinviewRule.OriginalStateRoot.GetAccountState(to) != null)
             {
                 new ConsensusError("p2pkh-to-contract", "attempted send directly to contract address. use OP_CALL instead.").Throw();
             }
         }
     }
 }
예제 #5
0
        public void ReadWrite(BitcoinStream stream)
        {
            if (stream.Serializing)
            {
                var ms = new MemoryStream();
                var bs = new BitcoinStream(ms, true)
                {
                    Type = SerializationType.Hash
                };

                if (KeyId != null)
                {
                    stream.ReadWrite(new uint160(KeyId.ToBytes()));
                }
                else
                {
                    bs.ReadWriteAsCompactVarInt(ref Height);
                    bs.ReadWriteAsCompactVarInt(ref Index);
                }

                var packBytes = ms.ToArray();
                stream.ReadWriteAsVarString(ref packBytes);
            }
            else
            {
                var packVar = new VarString();
                stream.ReadWrite(ref packVar);

                var bs = new BitcoinStream(packVar.GetString());

                if (packVar.Length >= 20)
                {
                    var keyHash = uint160.Zero;
                    stream.ReadWrite(ref keyHash);
                    KeyId = new KeyId(keyHash);
                }
                else
                {
                    bs.ReadWriteAsCompactVarInt(ref Height);
                    bs.ReadWriteAsCompactVarInt(ref Index);
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Creates a cold staking script.
        /// </summary>
        /// <remarks>Two keys control the balance associated with the script.
        /// The hot wallet key allows transactions to only spend amounts back to themselves while the cold
        /// wallet key allows amounts to be moved to different addresses. This makes it possible to perform
        /// staking using the hot wallet key so that even if the key becomes compromised it can't be used
        /// to reduce the balance. Only the person with the cold wallet key can retrieve the coins and move
        /// them elsewhere. This behavior is enforced by the <see cref="OP_CHECKCOLDSTAKEVERIFY"/>
        /// opcode within the script flow related to hot wallet key usage. It sets the <see cref="PosTransaction.IsColdCoinStake"/>
        /// flag if the transaction spending an output, which contains this instruction, is a coinstake
        /// transaction. If this flag is set then further rules are enforced by <see cref="Stratis.Bitcoin.Features.Consensus.Rules.CommonRules.PosColdStakingRule"/>.
        /// </remarks>
        /// <param name="hotPubKeyHash">The hot wallet public key hash to use.</param>
        /// <param name="coldPubKeyHash">The cold wallet public key hash to use.</param>
        /// <returns>The cold staking script.</returns>
        /// <seealso cref="Consensus.Rules.CommonRules.PosColdStakingRule"/>
        public Script GenerateScriptPubKey(KeyId hotPubKeyHash, KeyId coldPubKeyHash)
        {
            // The initial stack consumed by this script will be set up differently depending on whether a
            // hot or cold pubkey is used - i.e. either <scriptSig> 0 <coldPubKey> OR <scriptSig> 1 <hotPubKey>.
            return(new Script(
                       // Duplicates the last stack entry resulting in:
                       // <scriptSig> 0/1 <coldPubKey/hotPubKey> <coldPubKey/hotPubKey>.
#pragma warning disable SA1114 // Parameter list must follow declaration
                       OP_DUP,
#pragma warning restore SA1114 // Parameter list must follow declaration
                               // Replaces the last stack entry with its hash resulting in:
                               // <scriptSig> 0/1 <coldPubKey/hotPubKey> <coldPubKeyHash/hotPubKeyHash>.
                       OP_HASH160,
                       // Rotates the top 3 stack entries resulting in:
                       // <scriptSig> <coldPubKey/hotPubKey> <coldPubKeyHash/hotPubKeyHash> 0/1.
                       OP_ROT,
                       // Consumes the top stack entry and continues from the OP_ELSE if the value was 0. Results in:
                       // <scriptSig> <coldPubKey/hotPubKey> <coldPubKeyHash/hotPubKeyHash>.
                       OP_IF,
                       // Reaching this point means that the value was 1 - i.e. the hotPubKey is being used.
                       // Executes the opcode as described in the remarks section. Stack remains unchanged.
                       OP_CHECKCOLDSTAKEVERIFY,
                       // Pushes the expected hotPubKey value onto the stack for later comparison purposes. Results in:
                       // <scriptSig> <hotPubKey> <hotPubKeyHash> <hotPubKeyHash for comparison>.
                       Op.GetPushOp(hotPubKeyHash.ToBytes()),
                       // The code contained in the OP_ELSE is executed when the value was 0 - i.e. the coldPubKey is used.
                       OP_ELSE,
                       // Pushes the expected coldPubKey value onto the stack for later comparison purposes. Results in:
                       // <scriptSig> <coldPubKey> <coldPubKeyHash> <coldPubKeyHash for comparison>.
                       Op.GetPushOp(coldPubKeyHash.ToBytes()),
                       OP_ENDIF,
                       // Checks that the <coldPubKeyHash/hotPubKeyHash> matches the comparison value and removes both values
                       // from the stack. The script fails at this point if the values mismatch. Results in:
                       // <scriptSig> <coldPubKey/hotPubKey>.
                       OP_EQUALVERIFY,
                       // Consumes the top 2 stack entries and uses those values to verify the signature. Results in:
                       // true/false - i.e. true if the signature is valid and false otherwise.
                       OP_CHECKSIG));
        }
예제 #7
0
 public AccountRestrictedKeyId(KeyId keyId, int accountId) : this(keyId.ToBytes(), accountId)
 {
 }