【问题标题】:How to include Array (of a struct) in a Struct in Solidity如何在 Solidity 结构中包含(结构的)数组
【发布时间】:2022-01-03 15:11:50
【问题描述】:

我最近开始学习 Solidity,我看过两个关于它的讲座视频并阅读了官方文档,但我似乎无法找到解决方案。 [我还检查了几个资源以寻求帮助,但找不到任何帮助]

需要:两个structs,其中一个引用另一个(Reader 结构有一个Book 结构书籍), 当创建reader 时,books 是空的,直到他们拿起(pickUp 函数)一本书。 [可用书籍的列表由我制作]。

我尝试过的:

pragma solidity ^0.6.0

contract School {
   struct Book {
      string name;
   }
   Book[2] public books = [Book("we1"), Book("uer")];
    
   struct Reader {
      string name;
      uint booksRead; //for every added book this increments
      Book[] books;
   }

   Reader public readers;
  
   function _createReader(string memory _name) public returns (uint) {
      #some logic
      readers.push(Reader("Freddie", 0, books[0])); 
      uint256 readerID = readers.length - 1;
      return readerID;
      
   }


}

错误(无法编译):TypeError: Invalid type for argument in function call. Invalid implicit conversion from struct School.Book storage ref to struct School.Book memory[] memory requested.

我无法理解这个错误。

预期输出:

读者 1(创建时):"Fred", 0, [] //name Fred, booksRead 0, empty list of books

读者 1(更新时):"Fred", 2, [Book("SomeBookI"), ("SomeBookII")]

谢谢。

【问题讨论】:

    标签: struct blockchain solidity smartcontracts web3


    【解决方案1】:

    由于还没有人参与,我将提供我的两分钱。首先,我会确保 readers 状态变量是一个数组(因为您似乎是这样使用它的),如下所示:

    Reader[] public readers;
    

    接下来,检查以下语句:

    readers.push(Reader("Freddie", 0, books[0]));
    

    如果您查看Reader 结构,最后一个参数books 是一个数组,但您传入的是Book 实例。

    要解决此问题,您需要创建一个新数组并将其传入。由于数组是引用类型,因此您还需要指定 data location。从你的代码来看,你希望这个数组是动态的并且在整个智能合约中都可用,所以storage 是唯一的选择。不幸的是,在 _createReader 函数中执行此操作是 anything but pragmatic,我能想到的任何解决方案充其量都是 hacky。

    如果我是你,我会重新考虑合同的设计,也许会做点什么:

    contract CoolSchool {
        mapping(string => string) public books; // ISBN => Book title
        mapping(string => string[]) public readers; // Reader name => ISBNs read
    
        constructor() {
            _loadBooks();
        }
    
        function addBook(string memory isbn, string memory title) public {
            require(!_isEmpty(isbn), "isbn is required");
            require(!_isEmpty(title), "title is required");
            books[isbn] = title;
        }
    
        function addReadBook(string memory reader, string memory isbn) public {
            string[] storage read = readers[reader];
            require(!_isEmpty(books[isbn]), "unknown book");
            read.push(isbn);
        }
    
        function _loadBooks() private {
            books["0333791037"] = "The Great Gatsby";
            books["0684833395"] = "Catch-22";
            books["9780451524935"] = "1984";
        }
    
        function _isEmpty(string memory s) private pure returns (bool) {
            return bytes(s).length == 0;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-16
      • 1970-01-01
      • 1970-01-01
      • 2018-09-29
      • 1970-01-01
      • 1970-01-01
      • 2012-12-30
      相关资源
      最近更新 更多