Exemplo n.º 1
0
        public static Transaction CreateCoinbaseTransaction(ECPublicKeyParameters publicKey, byte[] coinbase)
        {
            var tx = new Transaction
            (
                version: 1,
                inputs: ImmutableArray.Create
                (
                    new TxInput
                    (
                        previousTxOutputKey: new TxOutputKey
                        (
                            txHash: 0,
                            txOutputIndex: 0
                        ),
                        scriptSignature: ImmutableArray.Create(coinbase),
                        sequence: 0
                    )
                ),
                outputs: ImmutableArray.Create
                (
                    new TxOutput
                    (
                        value: 50L * (100 * 1000 * 1000),
                        scriptPublicKey: ImmutableArray.Create(CreatePublicKeyScript(publicKey))
                    )
                ),
                lockTime: 0
            );

            return tx;
        }
Exemplo n.º 2
0
        public void TestCalculateTransactionHash()
        {
            var expectedHash = UInt256.Parse("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b", NumberStyles.HexNumber);
            var tx = new Transaction
            (
                version: 1,
                inputs: ImmutableArray.Create(
                    new TxInput
                    (
                        previousTxOutputKey: new TxOutputKey(txHash: 0, txOutputIndex: 4294967295),
                        scriptSignature: ImmutableArray.Create("04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73".HexToByteArray()),
                        sequence: 4294967295
                    )),
                outputs: ImmutableArray.Create(
                    new TxOutput
                    (
                        value: (UInt64)(50L * 100.MILLION()),
                        scriptPublicKey: ImmutableArray.Create("4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac".HexToByteArray())
                    )),
                lockTime: 0
            );

            Assert.AreEqual(expectedHash, DataCalculator.CalculateTransactionHash(tx));
            Assert.AreEqual(expectedHash, DataCalculator.CalculateTransactionHash(tx.Version, tx.Inputs, tx.Outputs, tx.LockTime));
        }
Exemplo n.º 3
0
        public bool TryReadTransaction(TxKey txKey, out Transaction transaction)
        {
            using (var conn = this.OpenConnection())
            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = @"
                    SELECT TxHash, TxBytes
                    FROM BlockTransactions
                    WHERE BlockHash = @blockHash AND TxIndex = @txIndex";

                cmd.Parameters.SetValue("@blockHash", SqlDbType.Binary, 32).Value = txKey.BlockHash.ToDbByteArray();
                cmd.Parameters.SetValue("@txIndex", SqlDbType.Int).Value = txKey.TxIndex.ToIntChecked();

                using (var reader = cmd.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        var txHash = reader.GetUInt256(0);
                        var txBytes = reader.GetBytes(1);

                        transaction = StorageEncoder.DecodeTransaction(txBytes.ToMemoryStream(), txHash);
                        return true;
                    }
                    else
                    {
                        transaction = default(Transaction);
                        return false;
                    }
                }
            }
        }
Exemplo n.º 4
0
        public bool TryReadValue(UInt256 txHash, out Transaction transaction)
        {
            using (var conn = this.OpenConnection())
            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = @"
                    SELECT TxBytes
                    FROM BlockTransactions
                    WHERE TxHash = @txHash";

                cmd.Parameters.SetValue("@txHash", FbDbType.Char, FbCharset.Octets, 32).Value = txHash.ToDbByteArray();

                using (var reader = cmd.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        var txBytes = reader.GetBytes(0);

                        transaction = StorageEncoder.DecodeTransaction(txBytes.ToMemoryStream(), txHash);
                        return true;
                    }
                    else
                    {
                        transaction = default(Transaction);
                        return false;
                    }
                }
            }
        }
Exemplo n.º 5
0
        public byte[] TxSignature(ImmutableArray<byte> scriptPubKey, Transaction tx, int inputIndex, byte hashType)
        {
            ///TODO
            Debug.Assert(inputIndex < tx.Inputs.Length);

            // Blank out other inputs' signatures
            var empty = ImmutableArray.Create<byte>();
            var newInputs = new TxInput[tx.Inputs.Length];
            for (var i = 0; i < tx.Inputs.Length; i++)
            {
                var oldInput = tx.Inputs[i];
                var newInput = oldInput.With(scriptSignature: i == inputIndex ? scriptPubKey : empty);
                newInputs[i] = newInput;
            }

            //// Blank out some of the outputs
            //if ((hashType & 0x1F) == (int)ScriptHashType.SIGHASH_NONE)
            //{
            //    //TODO
            //    Debug.Assert(false);

            //    // Wildcard payee

            //    // Let the others update at will
            //}
            //else if ((hashType & 0x1F) == (int)ScriptHashType.SIGHASH_SINGLE)
            //{
            //    //TODO
            //    Debug.Assert(false);

            //    // Only lock-in the txout payee at same index as txin

            //    // Let the others update at will
            //}

            //// Blank out other inputs completely, not recommended for open transactions
            //if ((hashType & 0x80) == (int)ScriptHashType.SIGHASH_ANYONECANPAY)
            //{
            //    //TODO
            //    Debug.Assert(false);
            //}

            // create simplified transaction
            var newTx = tx.With(Inputs: newInputs.ToImmutableArray());

            // return wire-encoded simplified transaction with the 4-byte hashType tacked onto the end
            var stream = new MemoryStream();
            using (var writer = new BinaryWriter(stream))
            {
                writer.WriteBytes(DataCalculator.EncodeTransaction(newTx));
                writer.Write4Bytes(hashType);

                return stream.ToArray();
            }
        }
Exemplo n.º 6
0
        public static byte[] CreatePrivateKeyScript(Transaction tx, int inputIndex, byte hashType, ECPrivateKeyParameters privateKey, ECPublicKeyParameters publicKey)
        {
            //TODO
            var scriptEngine = new ScriptEngine();

            var publicAddress = CreatePublicAddress(publicKey);
            var publicKeyScript = CreatePublicKeyScript(publicAddress);
            var txSignature = scriptEngine.TxSignature(publicKeyScript.ToImmutableArray(), tx, inputIndex, hashType);
            var txSignatureHash = Crypto.DoubleSHA256(txSignature);

            //Debug.WriteLine("Signing Tx:       {0}".Format2(txSignature.ToHexDataString()));
            //Debug.WriteLine("Signing Tx  Hash: {0}".Format2(txSignatureHash.ToHexDataString()));

            var signer = new ECDsaSigner();
            signer.Init(forSigning: true, parameters: privateKey);
            var signature = signer.GenerateSignature(txSignatureHash);
            var r = signature[0];
            var s = signature[1];

            byte[] sigEncoded;
            using (var stream = new MemoryStream())
            {
                using (var asn1Stream = new Asn1OutputStream(stream))
                {
                    asn1Stream.WriteObject(new DerSequence(new DerInteger(r), new DerInteger(s)));
                }

                sigEncoded = stream.ToArray().Concat(hashType);
            }

            //Debug.WriteLine("Sig R:       {0}".Format2(r.ToHexNumberStringUnsigned()));
            //Debug.WriteLine("Sig S:       {0}".Format2(s.ToHexNumberStringUnsigned()));
            //Debug.WriteLine("Sig Encoded: {0}".Format2(sigEncoded.ToHexDataString()));

            var privateKeyScript = new ScriptBuilder();
            privateKeyScript.WritePushData(sigEncoded);
            privateKeyScript.WritePushData(publicAddress);
            //Debug.WriteLine("Private Script: {0}".Format2(privateKeyScript.GetScript().ToHexDataString()));

            return privateKeyScript.GetScript();
        }
Exemplo n.º 7
0
        public Block CreateEmptyBlock(UInt256 previousBlockHash)
        {
            var coinbaseTx = new Transaction
            (
                version: 0,
                inputs: ImmutableArray.Create
                (
                    new TxInput
                    (
                        previousTxOutputKey: new TxOutputKey
                        (
                            txHash: 0,
                            txOutputIndex: 0
                        ),
                        scriptSignature: ImmutableArray.Create(random.NextBytes(100)),
                        sequence: 0
                    )
                ),
                outputs: ImmutableArray.Create
                (
                    new TxOutput
                    (
                        value: 50 * SATOSHI_PER_BTC,
                        scriptPublicKey: ImmutableArray.Create(TransactionManager.CreatePublicKeyScript(_coinbasePublicKey))
                    )
                ),
                lockTime: 0
            );

            //Debug.WriteLine("Coinbase Tx Created: {0}".Format2(coinbaseTx.Hash.ToHexNumberString()));

            var transactions = ImmutableArray.Create(coinbaseTx);
            var merkleRoot = DataCalculator.CalculateMerkleRoot(transactions);

            var block = new Block
            (
                header: new BlockHeader
                (
                    version: 0,
                    previousBlock: previousBlockHash,
                    merkleRoot: merkleRoot,
                    time: 0,
                    bits: DataCalculator.TargetToBits(this._rules.HighestTarget),
                    nonce: 0
                ),
                transactions: transactions
            );

            return block;
        }
Exemplo n.º 8
0
 public bool TryGetTransaction(TxKey txKey, out Transaction transaction, bool saveInCache = true)
 {
     if (this.CacheContext.TransactionCache.TryGetValue(txKey, out transaction))
     {
         this.missingTransactions.TryRemove(txKey.TxHash);
         return true;
     }
     else
     {
         this.missingTransactions.TryAdd(txKey.TxHash);
         transaction = default(Transaction);
         return false;
     }
 }
Exemplo n.º 9
0
        //TODO utxo needs to be as-at transaction, with regards to a transaction being fully spent and added back in in the same block
        public virtual void ValidateTransaction(long blockHeight, Block block, Transaction tx, int txIndex, ImmutableDictionary<UInt256, UnspentTx> utxo, ImmutableDictionary<UInt256, ImmutableHashSet<int>> newTransactions, out long unspentValue /*, ImmutableDictionary<UInt256, Transaction> transactions*/)
        {
            unspentValue = -1;

            // lookup all previous outputs
            var prevOutputMissing = false;
            var previousOutputs = new Dictionary<TxOutputKey, Tuple<TxInput, int, TxOutput>>();
            for (var inputIndex = 0; inputIndex < tx.Inputs.Length; inputIndex++)
            {
                var input = tx.Inputs[inputIndex];

                // find previous transaction
                var prevTx = GetPreviousTransaction(block, txIndex, input.PreviousTxOutputKey, utxo, newTransactions);

                // find previous transaction output
                if (input.PreviousTxOutputKey.TxOutputIndex >= prevTx.Outputs.Length)
                    throw new ValidationException();
                var prevOutput = prevTx.Outputs[input.PreviousTxOutputKey.TxOutputIndex.ToIntChecked()];

                previousOutputs.Add(input.PreviousTxOutputKey, Tuple.Create(input, inputIndex, prevOutput));
            }

            if (prevOutputMissing)
            {
                throw new ValidationException();
            }

            // verify spend amounts
            var txInputValue = (UInt64)0;
            var txOutputValue = (UInt64)0;

            for (var inputIndex = 0; inputIndex < tx.Inputs.Length; inputIndex++)
            {
                var input = tx.Inputs[inputIndex];

                // add transactions previous value to unspent amount (used to calculate allowed coinbase reward)
                var prevOutput = previousOutputs[input.PreviousTxOutputKey].Item3;
                txInputValue += prevOutput.Value;
            }

            for (var outputIndex = 0; outputIndex < tx.Outputs.Length; outputIndex++)
            {
                // remove transactions spend value from unspent amount (used to calculate allowed coinbase reward)
                var output = tx.Outputs[outputIndex];
                txOutputValue += output.Value;
            }

            // ensure that amount being output from transaction isn't greater than amount being input
            if (txOutputValue > txInputValue)
            {
                throw new ValidationException("Failing tx {0}: Transaction output value is greater than input value".Format2(tx.Hash.ToHexNumberString()));
            }

            // calculate unspent value
            unspentValue = (long)(txInputValue - txOutputValue);

            // sanity check
            if (unspentValue < 0)
            {
                throw new ValidationException();
            }

            // all validation has passed
        }
Exemplo n.º 10
0
        private void TestTransactionVerifyScript(Transaction tx, IDictionary<UInt256, Transaction> txLookup)
        {
            var scriptEngine = new ScriptEngine();

            for (var inputIndex = 0; inputIndex < tx.Inputs.Length; inputIndex++)
            {
                var input = tx.Inputs[inputIndex];
                var prevOutput = txLookup[input.PreviousTxOutputKey.TxHash].Outputs[input.PreviousTxOutputKey.TxOutputIndex.ToIntChecked()];

                var script = GetScriptFromInputPrevOutput(input, prevOutput);

                var result = scriptEngine.VerifyScript(0 /*blockIndex*/, -1 /*txIndex*/, prevOutput.ScriptPublicKey.ToArray(), tx, inputIndex, script.ToArray());

                Assert.IsTrue(result);
            }
        }
Exemplo n.º 11
0
        private void TestTransactionVerifySignature(byte[] expectedHashTypes, byte[][] expectedSignatures, byte[][] expectedSignatureHashes, byte[][] expectedX, byte[][] expectedY, byte[][] expectedR, byte[][] expectedS, Transaction tx, IDictionary<UInt256, Transaction> txLookup)
        {
            var scriptEngine = new ScriptEngine();

            for (var inputIndex = 0; inputIndex < tx.Inputs.Length; inputIndex++)
            {
                var input = tx.Inputs[inputIndex];
                var prevOutput = txLookup[input.PreviousTxOutputKey.TxHash].Outputs[input.PreviousTxOutputKey.TxOutputIndex.ToIntChecked()];

                var hashType = GetHashTypeFromScriptSig(input.ScriptSignature);
                var sig = GetSigFromScriptSig(input.ScriptSignature);
                var pubKey = GetPubKeyFromScripts(input.ScriptSignature, prevOutput.ScriptPublicKey);

                byte[] txSignature, txSignatureHash; BigInteger x, y, r, s;
                var result = scriptEngine.VerifySignature(prevOutput.ScriptPublicKey, tx, sig.ToArray(), pubKey.ToArray(), inputIndex, out hashType, out txSignature, out txSignatureHash, out x, out y, out r, out s);

                Debug.WriteLine(hashType);
                Debug.WriteLine(txSignature.ToHexDataString());
                Debug.WriteLine(txSignatureHash.ToHexNumberString());
                Debug.WriteLine(x.ToHexNumberString());
                Debug.WriteLine(y.ToHexNumberString());
                Debug.WriteLine(r.ToHexNumberString());
                Debug.WriteLine(s.ToHexNumberString());

                Assert.AreEqual(expectedHashTypes[inputIndex], hashType);
                CollectionAssert.AreEqual(expectedSignatures[inputIndex].ToList(), txSignature.ToList());
                CollectionAssert.AreEqual(expectedSignatureHashes[inputIndex].ToList(), txSignatureHash.ToList());
                CollectionAssert.AreEqual(expectedX[inputIndex], x.ToByteArrayUnsigned());
                CollectionAssert.AreEqual(expectedY[inputIndex], y.ToByteArrayUnsigned());
                CollectionAssert.AreEqual(expectedR[inputIndex], r.ToByteArrayUnsigned());
                CollectionAssert.AreEqual(expectedS[inputIndex], s.ToByteArrayUnsigned());
                Assert.IsTrue(result);
            }
        }
Exemplo n.º 12
0
 public bool TryReadTransaction(TxKey txKey, out Transaction transaction)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 13
0
        private void TestTransactionSignature(byte[][] expectedSignatures, Transaction tx, IDictionary<UInt256, Transaction> txLookup)
        {
            var scriptEngine = new ScriptEngine();
            for (var inputIndex = 0; inputIndex < tx.Inputs.Length; inputIndex++)
            {
                var input = tx.Inputs[inputIndex];
                var prevOutput = txLookup[input.PreviousTxOutputKey.TxHash].Outputs[input.PreviousTxOutputKey.TxOutputIndex.ToIntChecked()];

                var hashType = GetHashTypeFromScriptSig(input.ScriptSignature);

                var actual = scriptEngine.TxSignature(prevOutput.ScriptPublicKey, tx, inputIndex, hashType);
                CollectionAssert.AreEqual(expectedSignatures[inputIndex].ToList(), actual.ToList());
            }
        }
Exemplo n.º 14
0
        public static void GetFirstTransaction(BlockProvider blockProvider, out Block block, out Transaction tx, out IDictionary<UInt256, Transaction> txLookup)
        {
            txLookup = new Dictionary<UInt256, Transaction>();

            // prior outputs for first transaction
            GetTransaction(blockProvider, 9, 0, out block, out tx);
            txLookup.Add(tx.Hash, tx);

            // first transaction
            // do this last so its output is what is returned
            GetTransaction(blockProvider, 170, 1, out block, out tx);
            txLookup.Add(tx.Hash, tx);
        }
Exemplo n.º 15
0
 public static void GetTransaction(BlockProvider blockProvider, int blockIndex, int txIndex, out Block block, out Transaction tx)
 {
     block = blockProvider.GetBlock(blockIndex);
     tx = block.Transactions[txIndex];
 }
Exemplo n.º 16
0
        private bool ExecuteOps(ImmutableArray<byte> scriptPubKey, Transaction tx, int inputIndex, byte[] script, out Stack stack, out Stack altStack)
        {
            stack = new Stack();
            altStack = new Stack();

            using (var opReader = new BinaryReader(script.ToMemoryStream()))
            {
                while (opReader.BaseStream.Position < script.Length)
                {
                    var opByte = opReader.ReadByte();
                    var op = (ScriptOp)Enum.ToObject(typeof(ScriptOp), opByte);

                    //logger.LogTrace("Executing {0} with stack count: {1}", OpName(opByte), stack.Count);

                    switch (op)
                    {
                        // Constants
                        case ScriptOp.OP_PUSHDATA1:
                            {
                                if (opReader.BaseStream.Position + 1 >= script.Length)
                                    return false;

                                var length = opReader.ReadByte();
                                stack.PushBytes(opReader.ReadBytes(length));
                            }
                            break;

                        case ScriptOp.OP_PUSHDATA2:
                            {
                                if (opReader.BaseStream.Position + 2 >= script.Length)
                                    return false;

                                var length = opReader.Read2Bytes();
                                stack.PushBytes(opReader.ReadBytes(length));
                            }
                            break;

                        case ScriptOp.OP_PUSHDATA4:
                            {
                                if (opReader.BaseStream.Position + 4 >= script.Length)
                                    return false;

                                var length = opReader.Read4Bytes();
                                stack.PushBytes(opReader.ReadBytes(length.ToIntChecked()));
                            }
                            break;

                        // Flow control
                        case ScriptOp.OP_NOP:
                            {
                            }
                            break;

                        // Stack
                        case ScriptOp.OP_DROP:
                            {
                                if (stack.Count < 1)
                                    return false;

                                var value = stack.PopBytes();

                                //logger.LogTrace("{0} dropped {1}", OpName(opByte), value);
                            }
                            break;

                        case ScriptOp.OP_DUP:
                            {
                                if (stack.Count < 1)
                                    return false;

                                var value = stack.PeekBytes();
                                stack.PushBytes(value);

                                //logger.LogTrace("{0} duplicated {2}", OpName(opByte), value);
                            }
                            break;

                        // Splice

                        // Bitwise logic
                        case ScriptOp.OP_EQUAL:
                        case ScriptOp.OP_EQUALVERIFY:
                            {
                                if (stack.Count < 2)
                                    return false;

                                var value1 = stack.PopBytes();
                                var value2 = stack.PopBytes();

                                var result = value1.SequenceEqual(value2);
                                stack.PushBool(result);

                                //                            logger.LogTrace(
                                //@"{0} compared values:
                                //value1: {1}
                                //value2: {2}
                                //result: {3}", OpName(opByte), value1, value2, result);

                                if (op == ScriptOp.OP_EQUALVERIFY)
                                {
                                    if (result)
                                        stack.PopBool();
                                    else
                                        return false;
                                }
                            }
                            break;

                        // Arithmetic
                        // Note: Arithmetic inputs are limited to signed 32-bit integers, but may overflow their output.

                        // Crypto
                        case ScriptOp.OP_SHA256:
                            {
                                if (stack.Count < 1)
                                    return false;

                                var value = stack.PopBytes().ToArray();

                                var hash = Crypto.SingleSHA256(value);
                                stack.PushBytes(hash);

                                //                            logger.LogTrace(
                                //@"{0} hashed value:
                                //value:  {1}
                                //hash:   {2}", OpName(opByte), value, hash);
                            }
                            break;

                        case ScriptOp.OP_HASH160:
                            {
                                if (stack.Count < 1)
                                    return false;

                                var value = stack.PopBytes().ToArray();

                                var hash = Crypto.SingleRIPEMD160(Crypto.SingleSHA256(value));
                                stack.PushBytes(hash);

                                //                            logger.LogTrace(
                                //@"{0} hashed value:
                                //value:  {1}
                                //hash:   {2}", OpName(opByte), value, hash);
                            }
                            break;

                        case ScriptOp.OP_CHECKSIG:
                        case ScriptOp.OP_CHECKSIGVERIFY:
                            {
                                if (stack.Count < 2)
                                    return false;

                                var pubKey = stack.PopBytes().ToArray();
                                var sig = stack.PopBytes().ToArray();

                                var startTime = DateTime.UtcNow;

                                byte hashType; byte[] txSignature, txSignatureHash; BigIntegerBouncy x, y, r, s;
                                var result = VerifySignature(scriptPubKey, tx, sig, pubKey, inputIndex, out hashType, out txSignature, out txSignatureHash, out x, out y, out r, out s);
                                stack.PushBool(result);

                                var finishTime = DateTime.UtcNow;
                                //                            logger.LogTrace(
                                //@"{0} executed in {13} ms:
                                //tx:                 {1}
                                //inputIndex:         {2}
                                //pubKey:             {3}
                                //sig:                {4}
                                //hashType:           {5}
                                //txSignature:        {6}
                                //txSignatureHash:    {7}
                                //x:                  {8}
                                //y:                  {9}
                                //r:                  {10}
                                //s:                  {11}
                                //result:             {12}", OpName(opByte), tx.ToRawBytes(), inputIndex, pubKey, sig, hashType, txSignature, txSignatureHash, x, y, r, s, result, (finishTime - startTime).TotalMilliseconds.ToString("0"));

                                if (op == ScriptOp.OP_CHECKSIGVERIFY)
                                {
                                    if (result)
                                        stack.PopBool();
                                    else
                                        return false;
                                }
                            }
                            break;

                        // Pseudo-words
                        // These words are used internally for assisting with transaction matching. They are invalid if used in actual scripts.

                        // Reserved words
                        // Any opcode not assigned is also reserved. Using an unassigned opcode makes the transaction invalid.

                        default:
                            //OP_PUSHBYTES1-75
                            if (opByte >= (int)ScriptOp.OP_PUSHBYTES1 && opByte <= (int)ScriptOp.OP_PUSHBYTES75)
                            {
                                stack.PushBytes(opReader.ReadBytes(opByte));
                                //logger.LogTrace("{0} loaded {1} bytes onto the stack: {2}", OpName(opByte), opByte, stack.PeekBytes());
                            }
                            // Unknown op
                            else
                            {
                                var message = string.Format("Invalid operation in tx {0} input {1}: {2} {3}", tx.Hash.ToHexNumberString(), inputIndex, new[] { opByte }.ToHexNumberString(), OpName(opByte));
                                Debug.WriteLine(message);
                                throw new Exception(message);
                            }
                            break;
                    }

                    //logger.LogTrace(new string('-', 80));
                }
            }

            // TODO verify no if/else blocks left over

            // TODO not entirely sure what default return should be
            return true;
        }
Exemplo n.º 17
0
        public bool VerifySignature(ImmutableArray<byte> scriptPubKey, Transaction tx, byte[] sig, byte[] pubKey, int inputIndex, out byte hashType, out byte[] txSignature, out byte[] txSignatureHash, out BigIntegerBouncy x, out BigIntegerBouncy y, out BigIntegerBouncy r, out BigIntegerBouncy s)
        {
            // get the 1-byte hashType off the end of sig
            hashType = sig[sig.Length - 1];

            // get the DER encoded portion of sig, which is everything except the last byte (the last byte being hashType)
            var sigDER = sig.Take(sig.Length - 1).ToArray();

            // get the simplified/signing version of the transaction
            txSignature = TxSignature(scriptPubKey, tx, inputIndex, hashType);

            // get the hash of the simplified/signing version of the transaction
            txSignatureHash = Crypto.DoubleSHA256(txSignature);

            // load pubKey
            ReadPubKey(pubKey, out x, out y);
            var publicKeyPoint = curve.Curve.CreatePoint(x, y, withCompression: false);
            var publicKeyParameters = new ECPublicKeyParameters(publicKeyPoint, domainParameters);

            // load sig
            ReadSigKey(sigDER, out r, out s);

            // init signer
            var signer = new ECDsaSigner();
            signer.Init(forSigning: false, parameters: publicKeyParameters);

            // verify that sig is a valid signature from pubKey for the simplified/signing transaction's hash
            var txSignatureHash2 = txSignatureHash;
            var r2 = r;
            var s2 = s;
            //TODO
            var result = BypassVerifySignature || new MethodTimer(false).Time("ECDsa Verify", () => signer.VerifySignature(txSignatureHash2.ToArray(), r2, s2));

            return result;
        }
Exemplo n.º 18
0
 public static void EncodeTransaction(Stream stream, Transaction tx)
 {
     using (var writer = new BinaryWriter(stream, Encoding.ASCII, leaveOpen: true))
     {
         writer.Write4Bytes(tx.Version);
         writer.EncodeList(tx.Inputs, input => EncodeTxInput(stream, input));
         writer.EncodeList(tx.Outputs, output => EncodeTxOutput(stream, output));
         writer.Write4Bytes(tx.LockTime);
     }
 }
Exemplo n.º 19
0
        public static Transaction CreateSpendTransaction(Transaction prevTx, int prevInputIndex, byte hashType, UInt64 value, ECPrivateKeyParameters fromPrivateKey, ECPublicKeyParameters fromPublicKey, ECPublicKeyParameters toPublicKey)
        {
            var tx = new Transaction
            (
                version: 1,
                inputs: ImmutableArray.Create
                (
                    new TxInput
                    (
                        previousTxOutputKey: new TxOutputKey
                        (
                            txHash: prevTx.Hash,
                            txOutputIndex: (UInt32)prevInputIndex
                        ),
                        scriptSignature: ImmutableArray.Create<byte>(),
                        sequence: 0
                    )
                ),
                outputs: ImmutableArray.Create
                (
                    new TxOutput
                    (
                        value: value,
                        scriptPublicKey: ImmutableArray.Create(CreatePublicKeyScript(toPublicKey))
                    )
                ),
                lockTime: 0
            );

            // sign the transaction
            var scriptSignature = ImmutableArray.Create(CreatePrivateKeyScript(tx, 0, hashType, fromPrivateKey, fromPublicKey));

            // add the signature script to the transaction
            tx = tx.With(Inputs: ImmutableArray.Create(tx.Inputs[0].With(scriptSignature: scriptSignature)));

            return tx;
        }
Exemplo n.º 20
0
 public static byte[] EncodeTransaction(Transaction tx)
 {
     var stream = new MemoryStream();
     EncodeTransaction(stream, tx);
     return stream.ToArray();
 }
Exemplo n.º 21
0
 public static UInt256 CalculateTransactionHash(Transaction tx)
 {
     return new UInt256(Crypto.DoubleSHA256(EncodeTransaction(tx)));
 }
Exemplo n.º 22
0
 public static byte[] EncodeTransaction(Transaction tx)
 {
     return EncodeTransaction(tx.Version, tx.Inputs, tx.Outputs, tx.LockTime);
 }
Exemplo n.º 23
0
 public static long SizeEstimator(Transaction tx)
 {
     return tx.SizeEstimate;
 }
Exemplo n.º 24
0
        public bool VerifyScript(UInt256 blockHash, int txIndex, byte[] scriptPubKey, Transaction tx, int inputIndex, byte[] script)
        {
            //            logger.LogTrace(
            //@"
            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            //Verifying script for block {0}, transaction {1}, input {2}
            //{3}
            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
            //                , blockHash, txIndex, inputIndex, script.ToArray().ToHexDataString());

            Stack stack, altStack;
            if (
                ExecuteOps(scriptPubKey.ToImmutableArray(), tx, inputIndex, script, out stack, out altStack)
                && stack.Count == 1 && altStack.Count == 0)
            {
                var success = stack.PeekBool(); //TODO Pop? does it matter?

                // Additional validation for spend-to-script-hash transactions:
                //TODO

                return success;
            }
            else
            {
                return false;
            }
        }