--- /dev/null
+\feffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Novacoin
+{
+ public class COutPoint
+ {
+ /// <summary>
+ /// Hash of parent transaction.
+ /// </summary>
+ public Hash256 hash;
+
+ /// <summary>
+ /// Parent input number.
+ /// </summary>
+ public uint n;
+
+ public COutPoint()
+ {
+ hash = new Hash256();
+ n = uint.MaxValue;
+ }
+
+ public COutPoint(Hash256 hashIn, uint nIn)
+ {
+ hash = hashIn;
+ n = nIn;
+ }
+
+ public COutPoint(COutPoint o)
+ {
+ hash = new Hash256(o.hash);
+ n = o.n;
+ }
+
+ public COutPoint(IEnumerable<byte> bytes)
+ {
+ hash = new Hash256(bytes.Take(32));
+ n = BitConverter.ToUInt32(bytes.Skip(32).Take(4).ToArray(), 0);
+ }
+
+ public bool IsNull
+ {
+ get { return hash.IsZero && n == uint.MaxValue; }
+ }
+
+ public IList<byte> Bytes
+ {
+ get
+ {
+ List<byte> r = new List<byte>();
+ r.AddRange(hash.hashBytes);
+ r.AddRange(BitConverter.GetBytes(n));
+
+ return r;
+ }
+ }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendFormat("COutPoint({0}, {1})", hash.ToString(), n);
+
+ return sb.ToString();
+ }
+
+
+ }
+
+}
/// <summary>
/// Is it true that script doesn't contain anything except push value operations?
/// </summary>
- /// <returns>Checking result</returns>
public bool IsPushonly
{
get
/// <summary>
/// Is it true that script doesn't contain non-canonical push operations?
/// </summary>
- /// <returns>Checking result</returns>
public bool HasOnlyCanonicalPushes
{
get
/// <summary>
/// Quick test for pay-to-script-hash CScripts
/// </summary>
- /// <returns>Checking result</returns>
public bool IsPayToScriptHash
{
get
/// <summary>
/// Quick test for pay-to-pubkeyhash CScripts
/// </summary>
- /// <returns>Checking result</returns>
public bool IsPayToPubKeyHash
{
get
}
/// <summary>
+ /// Quick test for Null destination
+ /// </summary>
+ public bool IsNull
+ {
+ get { return codeBytes.Count == 0; }
+ }
+
+ /// <summary>
/// Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs
/// as 20 sigops. With pay-to-script-hash, that changed:
/// CHECKMULTISIGs serialized in scriptSigs are
namespace Novacoin
{
- /// <summary>
- /// Represents the transaction. Any transaction must provide one input and one output at least.
- /// </summary>
- public class CTransaction
- {
- /// <summary>
- /// Version of transaction schema.
- /// </summary>
- public uint nVersion = 1;
-
- /// <summary>
- /// Transaction timestamp.
- /// </summary>
- public uint nTime = 0;
-
- /// <summary>
- /// Array of transaction inputs
- /// </summary>
- public CTxIn[] vin;
-
- /// <summary>
- /// Array of transaction outputs
- /// </summary>
- public CTxOut[] vout;
-
- /// <summary>
- /// Block height or timestamp when transaction is final
- /// </summary>
- public uint nLockTime = 0;
+ /// <summary>
+ /// Represents the transaction. Any transaction must provide one input and one output at least.
+ /// </summary>
+ public class CTransaction
+ {
+ /// <summary>
+ /// Version of transaction schema.
+ /// </summary>
+ public uint nVersion = 1;
+
+ /// <summary>
+ /// Transaction timestamp.
+ /// </summary>
+ public uint nTime = 0;
+
+ /// <summary>
+ /// Array of transaction inputs
+ /// </summary>
+ public CTxIn[] vin;
+
+ /// <summary>
+ /// Array of transaction outputs
+ /// </summary>
+ public CTxOut[] vout;
+
+ /// <summary>
+ /// Block height or timestamp when transaction is final
+ /// </summary>
+ public uint nLockTime = 0;
/// <summary>
/// Initialize an empty instance
/// Parse byte sequence and initialize new instance of CTransaction
/// </summary>
/// <param name="txBytes">Byte sequence</param>
- public CTransaction (IList<byte> txBytes)
- {
+ public CTransaction(IList<byte> txBytes)
+ {
WrappedList<byte> wBytes = new WrappedList<byte>(txBytes);
- nVersion = BitConverter.ToUInt32(wBytes.GetItems(4),0);
- nTime = BitConverter.ToUInt32(wBytes.GetItems(4),0);
+ nVersion = BitConverter.ToUInt32(wBytes.GetItems(4), 0);
+ nTime = BitConverter.ToUInt32(wBytes.GetItems(4), 0);
int nInputs = (int)VarInt.ReadVarInt(ref wBytes);
vin = new CTxIn[nInputs];
// Fill inputs array
vin[nCurrentInput] = new CTxIn();
- vin[nCurrentInput].txID = new Hash256(wBytes.GetItems(32));
- vin[nCurrentInput].n = BitConverter.ToUInt32(wBytes.GetItems(4), 0);
+ vin[nCurrentInput].prevout = new COutPoint(wBytes.GetItems(36));
int nScriptSigLen = (int)VarInt.ReadVarInt(ref wBytes);
vin[nCurrentInput].scriptSig = new CScript(wBytes.GetItems(nScriptSigLen));
{
// Fill outputs array
vout[nCurrentOutput] = new CTxOut();
- vout[nCurrentOutput].nValue = BitConverter.ToUInt64(wBytes.GetItems(8), 0);
+ vout[nCurrentOutput].nValue = BitConverter.ToInt64(wBytes.GetItems(8), 0);
int nScriptPKLen = (int)VarInt.ReadVarInt(ref wBytes);
vout[nCurrentOutput].scriptPubKey = new CScript(wBytes.GetItems(nScriptPKLen));
}
nLockTime = BitConverter.ToUInt32(wBytes.GetItems(4), 0);
- }
+ }
/// <summary>
/// Read transactions array which is encoded in the block body.
public static CTransaction[] ReadTransactionsList(ref WrappedList<byte> wTxBytes)
{
CTransaction[] tx;
-
+
// Read amount of transactions
- int nTransactions = (int) VarInt.ReadVarInt(ref wTxBytes);
+ int nTransactions = (int)VarInt.ReadVarInt(ref wTxBytes);
tx = new CTransaction[nTransactions];
for (int nTx = 0; nTx < nTransactions; nTx++)
return tx;
}
+ public bool IsCoinBase
+ {
+ get { return (vin.Length == 1 && vin[0].prevout.IsNull && vout.Length >= 1); }
+ }
+
+ public bool IsCoinStake
+ {
+ get
+ {
+ return (vin.Length > 0 && (!vin[0].prevout.IsNull) && vout.Length >= 2 && vout[0].IsEmpty);
+ }
+ }
+
+
public IList<byte> Bytes
{
get
/// </summary>
public class CTxIn
{
- /// <summary>
- /// Hash of parent transaction.
- /// </summary>
- public Hash256 txID;
-
- /// <summary>
- /// Parent input number.
- /// </summary>
- public uint n = 0;
+ /// <summary>
+ /// Previous input data
+ /// </summary>
+ public COutPoint prevout;
/// <summary>
/// First half of script, signatures for the scriptPubKey
/// <param name="i">CTxIn instance.</param>
public CTxIn(CTxIn i)
{
- txID = i.txID;
- n = i.n;
+ prevout = new COutPoint(i.prevout);
scriptSig = i.scriptSig;
nSequence = i.nSequence;
}
/// </summary>
public CTxIn()
{
- txID = new Hash256();
+ prevout = new COutPoint();
scriptSig = new CScript();
}
{
// Fill inputs array
vin[nIndex] = new CTxIn();
-
- vin[nIndex].txID = new Hash256(wBytes.GetItems(32));
- vin[nIndex].n = BitConverter.ToUInt32(wBytes.GetItems(4), 0);
+ vin[nIndex].prevout = new COutPoint(wBytes.GetItems(36));
vin[nIndex].scriptSig = new CScript(wBytes.GetItems((int)VarInt.ReadVarInt(ref wBytes)));
vin[nIndex].nSequence = BitConverter.ToUInt32(wBytes.GetItems(4), 0);
}
{
List<byte> inputBytes = new List<byte>();
- inputBytes.AddRange(txID.hashBytes); // Input transaction id
- inputBytes.AddRange(BitConverter.GetBytes(n)); // Output number
+ inputBytes.AddRange(prevout.Bytes); // prevout
List<byte> s = new List<byte>(scriptSig.Bytes);
}
}
- public bool IsCoinBase
+ public bool IsFinal
{
- get { return txID.IsZero; }
+ get { return (nSequence == uint.MaxValue); }
}
-
- public override string ToString ()
+ public override string ToString ()
{
StringBuilder sb = new StringBuilder ();
+ /*
if (IsCoinBase)
{
sb.AppendFormat("CTxIn(txId={0}, coinbase={2}, nSequence={3})", txID.ToString(), n, Interop.ToHex(scriptSig.Bytes), nSequence);
{
sb.AppendFormat("CTxIn(txId={0}, n={1}, scriptSig={2}, nSequence={3})", txID.ToString(), n, scriptSig.ToString(), nSequence);
}
+ */
+
+
+ sb.AppendFormat("CTxIn(");
+ sb.Append(prevout.ToString());
+
+ if(prevout.IsNull)
+ {
+ sb.AppendFormat(", coinbase={0}", Interop.ToHex(scriptSig.Bytes));
+ }
+ else
+ {
+ sb.AppendFormat(", scriptsig={0}", scriptSig.ToString());
+ }
+
+ if (nSequence != uint.MaxValue)
+ {
+ sb.AppendFormat(", nSequence={0}", nSequence);
+ }
+
+ sb.Append(")");
+
- return sb.ToString ();
+ return sb.ToString ();
}
}
/// <summary>
/// Input value.
/// </summary>
- public ulong nValue;
+ public long nValue = -1;
/// <summary>
/// Second half of script which contains spending instructions.
}
}
+ public void SetNull()
+ {
+ nValue = -1;
+ scriptPubKey.SetNullDestination();
+ }
+
+ public void SetEmpty()
+ {
+ nValue = 0;
+ scriptPubKey.SetNullDestination();
+ }
+
+ public bool IsNull
+ {
+ get { return (nValue == -1); }
+ }
+
+ public bool IsEmpty
+ {
+ get { return nValue == 0 && scriptPubKey.IsNull; }
+ }
+
public override string ToString ()
{
StringBuilder sb = new StringBuilder ();
public Hash(Hash h)
{
+ _hashBytes = new byte[h.hashSize];
h._hashBytes.CopyTo(_hashBytes, 0);
}
<Compile Include="CKeyID.cs" />
<Compile Include="CKeyPair.cs" />
<Compile Include="CNovacoinAddress.cs" />
+ <Compile Include="COutPoint.cs" />
<Compile Include="CPubKey.cs" />
<Compile Include="CryptoUtils.cs" />
<Compile Include="CScriptID.cs" />