Möglichkeit zur einfachen Verwaltung von Attributen in Solidity Struct

Unten ist ein sehr einfacher Smart Contract, der einen struct Instructor hat, der jetzt 3 Attribute hat, dh age, fNameund lName. Wenn ich morgen ein neues Attribut hinzufügen möchte, muss ich alle Stellen aktualisieren, an denen diese Struktur im jeweiligen Smart Contract verwendet wurde, was aus Sicht der Skalierbarkeit und Codewartung ein Nachteil ist.

Frage also: Gibt es einen besseren Weg, mit dieser Situation umzugehen?

pragma solidity ^0.4.18;

contract Courses {

struct Instructor {
    uint age;
    string fName;
    string lName;
}

mapping (address => Instructor) instructors;
address[] public instructorAccts;

function setInstructor(address _address, uint _age, string _fName, string _lName) public {
    instructors[_address].age = _age;
    instructors[_address].fName = _fName;
    instructors[_address].lName = _lName;

    instructorAccts.push(_address) -1;
}

function getInstructors() view public returns(address[]) {
    return instructorAccts;
}

function getInstructor(address _address) view public returns (uint, string, string) {
    return (instructors[_address].age, instructors[_address].fName, instructors[_address].lName);
}

function countInstructors() view public returns (uint) {
    return instructorAccts.length;
}

}
Sie könnten ein 'extraInfo' bytes[]-Feld in Ihre Struktur aufnehmen und ihm alle zusätzlichen Daten im json-Format übergeben - dies ist jedoch möglicherweise nicht die sauberste Methode, daher bin ich daran interessiert, andere Möglichkeiten zu sehen, die sich die Leute einfallen lassen können !
Ich habe auch darüber nachgedacht, etwas, das wir in einer Webanwendung viel Zeit verwenden, um dynamische Felder zu verarbeiten, ist das Speichern von JSON in der Datenbank als Spalte für Metadaten, aber die Herausforderung, die ich hier in Solidity sehe, ist, dass dies zu einer Menge führen könnte Iteration oder IF/ELSE-Prüfung im JSON auf neu hinzugefügte Spalten oder alte entfernte Spalten

Antworten (1)

Sie können verschachtelte Mappings verwenden, es ist ziemlich hässlich, aber Sie können einen Teil der Komplexität in einer Bibliothek verbergen

contract Db {

    mapping (address => mapping (bytes32 => bytes32)) data;

    // 

    function getAge(address usr) public view returns (uint) {
        return getUint(usr, keccak256('age'));
    }

    function setAge(address usr, uint age) public {
        setUint(usr, keccak256('age'), age);
    }

    function getName(address usr) public view returns (string) {
        return getString(usr, keccak256('name'));
    }

    function setName(address usr, string name) public {
        setString(usr, keccak256('name'), name);
    }

    // Low level access/storage

    function getUint(address usr, bytes32 ky) internal view returns (uint) {
        return uint(data[usr][ky]);
    }

    function setUint(address usr, bytes32 ky, uint val) internal {
        data[usr][ky] = bytes32(val);
    }

    function getString(address usr, bytes32 ky) internal view returns (string) {
        return bytes32ToString(data[usr][ky]);
    }

    function setString(address usr, bytes32 ky, string val) internal {
        data[usr][ky] = stringToBytes32(val);
    }

    // Utility functions to pack/unpack a string into bytes32

    function bytes32ToString(bytes32) internal returns (string) {
         ..
    }

    function stringToBytes32(string) internal returns (bytes32) {
         ..
    }

}