c#当对象存储在链表

时间:2018-04-24 22:28:20

标签: c# hash linked-list blockchain

这个应用程序应该是区块链如何工作的一种演示。我有一个块链类和一个块类,程序类是主类。在区块链类中,我在createGenesisBlock()方法中创建了一个名为gensis块的初始块。在我的区块链类的构造函数中,我调用createGenesisBlock()方法并将对象插入到我的链表中,该链表称为链。我遇到的问题是当对象被添加到我的区块链类中的链表时,我无法访问该对象或方法。我想要完成的是在块链类中使用我的getLatestBlock()方法来检索放入链中的最后一个对象的哈希值。因此能够在区块链中调用我的addBlock方法设置previousHash的值等于链表中对象的哈希值

namespace BlockChainProject
{
    class Program
    {
        static void Main(string[] args)
        {
            Blockchain blockChain = new Blockchain();
            blockChain.addBlock();
            blockChain.display();
            Console.ReadKey();
        }
    }
}

namespace BlockChainProject
{

    class Block
    {
        private int index;
        private string timeStamp;
        private string data;
        private string previousHash;
        private string hash;


        public Block(int index, string timeStamp, string data, string previousHash) {
            this.index = index;
            this.timeStamp = timeStamp;
            this.data = data;
            this.previousHash = previousHash;
            this.hash = this.calculateHash();
        }

        public string calculateHash() {
            SHA256Managed hashString = new SHA256Managed();
            byte[] dataArray = hashString.ComputeHash(Encoding.UTF8.GetBytes(index.ToString() + previousHash + timeStamp + data));
            StringBuilder stringBuilder = new StringBuilder();
            foreach (byte x in dataArray)
            {
                stringBuilder.AppendFormat("{0:X2}", x);
            }

            string hashed = stringBuilder.ToString();
            return hashed;
        }

        public string getHash() {
            return hash;
        }
    }

}

namespace BlockChainProject
{
    class Blockchain
    {
        LinkedList<object> chain;
        private int index = 0;
        private string time = DateTime.Now.ToString();

        public Blockchain(){
            chain = new LinkedList<object>();
            chain.AddLast(createGenesisBlock());
        }

        private object createGenesisBlock() {
            index++;
            return new Block(index, time, "Genesis Block", "0"); ;
        }

        public object getLatestBlock() {
            return chain.Last.Value;
        }

        public void addBlock() {
            string data = Console.ReadLine();
            //string previousHash = <The hash of linked lists last object here>;
            chain.AddLast(new Block(index, time, data, previousHash));
            index++;

        }

        public void display() {
            foreach (var item in chain)
            {
                Console.WriteLine(item);
            }
        }

    }
}

2 个答案:

答案 0 :(得分:1)

我很快就运行了你的代码,我认为我已经找到了你的问题。您需要在“对象”上进行查找和替换,并将其替换为“Block”,或者您需要将从getLast函数返回的对象强制转换为“Block”。

更改的示例如下:

LinkedList<Block> chain;

...

public Block getLatestBlock() {
    return chain.Last.Value;
}

这是对Blockchain课程所做的更改的一些例子,可能有其他但我不记得。

现在,当您调用display函数时,您可以访问链表中每个Block类实例的函数和方法,如下所示:

public void display()
{
    foreach (var item in chain)
    {
        Console.WriteLine(item.getHash());
    }
}

现在将打印一个哈希列表,前提是您已将链接列表中使用对象的所有返回,类型和实例更改为阻止。

原因是如果你创建一个通用“对象”的链表,那么在编译时C#不知道链表中可能有什么。它可能是块或它可能是香蕉,因此它不知道每个对象可用于调用的函数和方法。因此,让C#知道我们必须在从列表中获取项目之后使用“as Block”来投射它,或者在您的情况下,只需将链接中的所有值的类型设置为“Block”,就像程序的外观一样你不会在列表中有通用条目。

希望这能回答你的问题。如果不让我知道。

答案 1 :(得分:0)

将链指定为

LinkedList<object> chain

您告诉编译器链变量是一个包含对象类或任何对象后代的链表。

因此,根据您对链

的定义,以下代码是合法的
chain.Add("Hi there!");
chain.Add(new Dictionary<int, decimal>());
chain.Add(new Giraffe());
chain.Add(42);

你不能调用calculateHash(),因为不幸的是,我们的字符串,Dictionary,Giraffe和int类不知道如何处理这样的方法调用。

相反,链应声明为

LinkedList<Block> chain;

这意味着链只能包含Block类型的元素(或者Block的后代类)。

虽然代码中没有显示对这些方法的调用,但您需要更改createGenesisBlock()getLatestBlock()方法以返回Block而不是object,因为您不允许添加任何再次反对链接列表,它必须是一个阻止。