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?
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.
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.