Как отследить право собственности на объект реального мира?

Пример использования

У меня есть ряд объектов реального мира, которые хранятся в центральном месте. Документ на этот объект может быть куплен и продан без фактического объекта. Документы можно продать за жетоны или обменять на физический объект, а токены можно обменять на наличные или использовать для покупки документов на другие объекты.

Вопрос

Я на самом раннем этапе предложения нового децентрализованного приложения своему работодателю. Я понимаю концепции, лежащие в основе децентрализованных приложений и блокчейна Ethereum, но еще не углублялся в Solidity и детали реализации. Я пытаюсь определить, могут ли смарт-контракты Ethereum отслеживать право собственности на конкретный объект реального мира. Все примеры, которые я нашел до сих пор, демонстрируют, как создать пользовательскую валюту, поэтому контракт на самом деле просто корректирует числовые балансы, а не передает право собственности на отдельный объект. Я знаю, что блокчейн Ethereum может обрабатывать платежи за эти действия с использованием токена ERC20, но можно ли его использовать для отслеживания прав собственности на каждое действие или это должно происходить вне сети?

Обновлять

Я провел сегодняшний день за просмотром семплов и экспериментами с Remix и начал двигаться в следующем направлении. К вашему сведению, я только сегодня начал изучать Solidity, так что будьте добры, если я делаю что-то совершенно неправильно.

pragma solidity ^0.4.0;

/*************************
 * Managed abstract contract
 *************************/
contract Managed
{
    address internal _manager;

    function isManager(address addr) internal view returns (bool yes)
    {
        return addr == _manager;
    }
}

/*************************
 * MyToken concrete contract
 *************************/
contract MyToken is Managed
{
    string private _name;
    string private _symbol;
    uint8 private _decimals = 18;
    uint256 _totalSupply;

    mapping (address => uint256) private _balances;

    function MyToken(string name, string symbol, uint256 initialSupply) public 
    {
        _manager = msg.sender;
        _name = name;
        _symbol = symbol;
        _totalSupply = initialSupply * 10 ** uint256(_decimals);
        _balances[_manager] = _totalSupply;
    }

    function _getBalance(address from) private view returns (uint256 balance)
    {
        return _balances[from];
    }

    function getBalance() public view returns (uint256 balance)
    {
        return _getBalance(msg.sender);
    }

    event Transfer(address indexed from, address indexed to, uint256 amount);

    function _transfer(address from, address to, uint256 amount) private
    {
        _remove(from, amount);
        _add(to, amount);
    }

    function transfer(address to, uint256 amount) public 
    {
        _transfer(msg.sender, to, amount);
    }

    event Add(address indexed to, uint256 amount);

    function _add(address to, uint256 amount) private
    {
        require(to != 0x0);
        require(amount >= 0);
        require(_balances[to] + amount >= _balances[to]);

        _balances[to] += amount;
        _totalSupply += amount;

        Add(to, amount);
    }

    function add(address to, uint256 amount) public
    {
        require(isManager(msg.sender));
        _add(to, amount);
    }

    function add(uint256 amount) public
    {
        _add(msg.sender, amount);
    }

    event Remove(address indexed from, uint256 amount);

    function _remove(address from, uint256 amount) private
    {
        require(from != 0x0);
        require(amount >= 0);
        require(amount <= _balances[from]);

        _balances[from] -= amount;
        _totalSupply -= amount;

        Remove(from, amount);
    }

    function remove(address from, uint256 amount) public
    {
        require(isManager(msg.sender));
        _remove(from, amount);
    }

    function remove(uint256 amount) public
    {
        _remove(msg.sender, amount);
    }
}

/*************************
 * Ownership concrete contract
 *************************/
contract Ownership is Managed
{
    mapping (address => mapping (uint64 => uint64)) private _holdings;

    function Ownership() public 
    {
        _manager = msg.sender;
    }

    function _getHoldings(address owner, uint64 itemId) private view returns (uint64 quantity)
    {
        return _holdings[owner][itemId];
    }

    function getHoldings(address owner, uint64 itemId) public view returns (uint64 quantity)
    {
        require(isManager(msg.sender));
        return _getHoldings(owner, itemId);
    }

    function getHoldings(uint64 itemId) public view returns (uint64 quantity)
    {
        return _getHoldings(msg.sender, itemId);
    }

    event Transfer(address indexed from, address indexed to, uint64 itemId, uint64 quantity);

    function _transfer(address from, address to, uint64 itemId, uint64 quantity) private
    {
        _remove(from, itemId, quantity);
        _add(to, itemId, quantity);
    }

    function transfer(address to, uint64 itemId, uint64 quantity) public
    {
        _transfer(msg.sender, to, itemId, quantity);
    }

    event Add(address indexed to, uint64 itemId, uint64 quantity);

    function _add(address to, uint64 itemId, uint64 quantity) private
    {
        require(to != 0x0);
        require(itemId > 0);
        require(quantity >= 0);
        require(_holdings[to][itemId] + quantity >= _holdings[to][itemId]);

        _holdings[to][itemId] += quantity;

        Add(to, itemId, quantity);
    }

    function add(address to, uint64 itemId, uint64 quantity) public
    {
        require(isManager(msg.sender));
        _add(to, itemId, quantity);
    }

    function add(uint64 itemId, uint64 quantity) public
    {
        _add(msg.sender, itemId, quantity);
    }

    event Remove(address indexed from, uint64 itemId, uint64 quantity);

    function _remove(address from, uint64 itemId, uint64 quantity) private
    {
        require(from != 0x0);
        require(itemId > 0);
        require(quantity >= 0);
        require(quantity <= _holdings[from][itemId]);

        _holdings[from][itemId] -= quantity;

        Remove(from, itemId, quantity);
    }

    function remove(address from, uint64 itemId, uint64 quantity) public
    {
        require(isManager(msg.sender));
        _remove(from, itemId, quantity);
    }

    function remove(uint64 itemId, uint64 quantity) public
    {
        _remove(msg.sender, itemId, quantity);
    }
}

Я также только что видел комментарий Исмаэля о стандартах невзаимозаменяемых токенов ERC721. Похоже, я был на правильном пути, но мне нужно углубиться в ERC721.

Дополнительный вопрос: если бы я реализовал систему заказов, в которой покупатели и продавцы предметов могли бы создавать заявки и запросы, должен ли я делать это вне сети и использовать блокчейн только для фактической передачи средств и владения?

Это очень широкий вопрос. Все можно отслеживать в цепочке (хотя хранение данных в цепочке относительно дорого). Вы спрашиваете, как смарт-контракт узнает право собственности на объект, если лица A и B встретились лично, а A продал объект B, не касаясь цепочки?
Если у ваших объектов есть что-то вроде серийного номера, вы можете попробовать использовать что-то вроде ERC 721 Non-fungible Token Standard .

Ответы (1)

Если объект реального мира имеет некоторые параметры или атрибуты, которые могут быть оцифрованы и уникальны для каждого объекта, тогда его можно загрузить в блокчейн, и мы можем отследить его право собственности.

Предположим, кто-то купил предмет, используя эфир/токен, тогда вы можете добавить событие его покупки и сохранить его текущего владельца. Если человек хочет продать его кому-то другому, он должен использовать ваш контракт, иначе он совершит незаконную сделку.

Есть стартап, который отслеживает право собственности на бриллианты. Поскольку бриллианты неразрушимы (почти), их углы и параметры отражения света могут быть сохранены в блокчейне. Таким образом, мы можем проверить, является ли текущий владелец подтвержденным владельцем или нет.

Вы можете придумать что-то вроде этого, чтобы создать свой смарт-контракт, использовать erc20, найти какой-то параметр, который является районом, сделать покупателя владельцем этого параметра при покупке (структура => сопоставление адресов), доставить ему/ей продукт.

Надеюсь это поможет.:)