Возможность легко управлять атрибутами в Solidity Struct

Ниже приведен очень простой смарт-контракт, в котором есть структура Instructor, которая прямо сейчас имеет 3 атрибута, то есть age, fNameи lName. Теперь, если завтра я захочу добавить новый атрибут, мне нужно будет обновить все места, где эта структура использовалась в соответствующем смарт-контракте, что является плохим моментом с точки зрения масштабируемости и обслуживания кода.

поэтому вопрос, есть ли лучший способ справиться с этой ситуацией?

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;
}

}
Вы можете включить поле 'extraInfo' bytes[] в свою структуру и передать ему любые дополнительные данные в формате json - это может быть не самый аккуратный способ сделать это, поэтому мне интересно посмотреть, какие другие способы люди могут придумать !
Я также подумал об этом, что-то, что мы используем много времени в веб-приложении для обработки динамических полей, хранит JSON в базе данных как столбец для метаданных, но проблема, которую я вижу здесь, в Solidity, заключается в том, что это может привести к большому количеству итерация или проверка IF/ELSE в JSON для новых добавленных столбцов или старых удаленных столбцов

Ответы (1)

Вы можете использовать вложенные сопоставления, это некрасиво, но вы можете скрыть некоторые сложности в библиотеке.

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) {
         ..
    }

}