Rückgabe eines dynamischen Arrays von der Funktion

Ich muss auf das Bücher-Array des Studentenvertrags im ClassRoom-Vertrag zugreifen.

Wenn ich so schreibe function readStudentStruct (uint ID) constant returns (address, uint, bool,address[])dann Fehler

Different number of arguments in return statement than in returns declaration.
        return student.StudentNames(ID);

oder wenn es ohne address[] geschrieben wird, dann funktioniert es gut.

pragma solidity ^0.4.0;
contract Student{

    struct stu{
        address name;
        uint age;
        bool tookTest;
        address[] books;
    }

    stu public s;

    mapping(uint => stu) public StudentNames;

    function addStudent (uint ID, address _name, uint _age,address[] books) {
        StudentNames[ID] = stu(_name, _age, false, books);
    }
    function updateStudent (uint ID) {
        StudentNames[ID].tookTest = true;
    }

    function getBooks(uint ID) returns(address[]){
        return StudentNames[ID].books;
    }

}
contract ClassRoom {
    address studentAddr;

    Student student;

    function ClassRoom(address addr) {
        studentAddr = addr;
        student = Student(addr);
    }
    function updateTookTest (uint ID) {
        student.updateStudent(ID);
    }

    //working fine
    function readStudentStruct (uint ID) constant returns (address, uint, bool) {
        return student.StudentNames(ID);
    }

   //showing error
   function readStudentStruct (uint ID) constant returns (address, uint, bool,address[]) {
        return student.StudentNames(ID);
    }
}

gemäß struct with address array function sollte funktionieren, tat es aber nicht.

Warum kommen Bücher nicht in den Muttervertrag? oder eine Möglichkeit, ein Bücher-Array in den übergeordneten Vertrag zu bekommen?

Antworten (1)

Das Hauptproblem ist, dass wir kein dynamisches Array[] in/out der Funktion übergeben können. Wir müssen es in eine Schnittstelle fester Größe zerlegen.

Hier ist eine Skizze, die einem einfachen Muster mit 4 verfolgten Entitäten und einigen Beziehungen folgt.

  1. Klasse
  2. Student
  3. Bücher
  4. und ein Many-to-Many für Klassenschüler

Das Muster ist nicht kompliziert, aber die Arbeit mit 4 Entitäten gleichzeitig und die Verbindungen sorgen für eine schwierige Einführung.

Schauen Sie hier für mehr anschaulichen Code: Gibt es gut gelöste und einfache Speichermuster für Solidity?

Wahrscheinlich möchten Sie eine logische Löschung unterstützen, damit ein Schüler seine Bücher zurückgeben kann. Ich habe es übersprungen, weil es ein kniffligeres Muster erfordert.

Keine Prüfung. Keine Garantie. Bringt hoffentlich ein paar Ideen.

pragma solidity ^0.4.0;

contract School {

    struct ClassStruct {
        bytes32 title;
        bytes32 teacher;
        mapping(address => ClassStudentStruct) classStudentStructs;
        address[] studentList;
        bool isClass;
    }

    mapping(bytes32 => ClassStruct) public classStructs; // access by Id
    bytes32[] public classList; // enumerate the keys to the mapping

    struct StudentStruct {
        bytes32 name;
        bytes32[] bookList; // student has books
        mapping(bytes32 => bool) isStudentBook;
        bool isStudent;
    }

    mapping(address => StudentStruct) public studentStructs;
    address[] public studentList;

    struct BookStruct {
        bytes32 title;
        bytes32 author;
        bool isBook;
    }

    mapping(bytes32 => BookStruct) public bookStructs;
    bytes32[] public bookList;

    // many-to-many

    struct ClassStudentStruct {
        address student;
        bool tookTest;
        bool isClassStudent;
    }

    function getClassCount()   public constant returns(uint count) { return classList.length; }
    function getStudentCount() public constant returns(uint count) { return studentList.length; }
    function getBookCount()    public constant returns(uint count) { return bookList.length; }

    function newClass(bytes32 classId, bytes32 title, bytes32 teacher) returns(bool success) {
        if(classStructs[classId].isClass) throw; // duplicate key
        classStructs[classId].title = title;
        classStructs[classId].teacher = teacher;
        classStructs[classId].isClass = true;
        classList.push(classId);
        return true;
    }

    function newStudent(address studentAddress, bytes32 name) returns(bool success) {
        if(studentStructs[studentAddress].isStudent) throw;
        studentStructs[studentAddress].name = name;
        studentList.push(studentAddress);
        studentStructs[studentAddress].isStudent = true;
        studentList.push(studentAddress);
        return true;
    }

    function newBook(bytes32 bookId, bytes32 title, bytes32 author) returns(bool success) {
        if(bookStructs[bookId].isBook) throw;
        bookStructs[bookId].title = title;
        bookStructs[bookId].author = author;
        bookStructs[bookId].isBook = true;
        bookList.push(bookId);
        return true;
    }

    function addClassStuduent(bytes32 classId, address studentAddress) returns(bool success) {
        if(!studentStructs[studentAddress].isStudent) throw; // not a student
        if(!classStructs[classId].isClass) throw; // not a class
        if(classStructs[classId].classStudentStructs[studentAddress].isClassStudent) throw; // student already enrolled in this class

        ClassStudentStruct memory newStudent;
        newStudent.student = studentAddress;
        newStudent.isClassStudent = true;
        classStructs[classId].studentList.push(studentAddress);
        return true;
    }

    function addStudentBook(bytes32 bookId, address studentAddress) returns(bool success) {
        if(!bookStructs[bookId].isBook) throw;
        if(!studentStructs[studentAddress].isStudent) throw;
        if(studentStructs[studentAddress].isStudentBook[bookId]) throw;

        studentStructs[studentAddress].isStudentBook[bookId] = true;
        studentStructs[studentAddress].bookList.push(bookId);
        return true;
    }


    // logical deletes need a more intricate pattern - Last one here:
    // https://ethereum.stackexchange.com/questions/13167/are-there-well-solved-and-simple-storage-patterns-for-solidity 

    function delStudentBook(bytes32 bookId, address studentAddress) returns(bool success) {}
    function delClassStudent(bytes32 classId, address studentAddress) returns(bool success) {}

}

Ich hoffe es hilft.