¿Cómo rastrear la propiedad de un objeto del mundo real?

Caso de uso

Tengo varios objetos del mundo real que están almacenados en una ubicación central. La escritura de ese objeto se puede comprar y vender sin que el objeto real vaya a ninguna parte. Las escrituras se pueden vender por fichas o canjearse por el objeto físico y las fichas se pueden canjear por dinero en efectivo o usarse para comprar escrituras de otros objetos.

Pregunta

Estoy en las primeras etapas de proponer un nuevo dapp a mi empleador. Entiendo los conceptos detrás de dapps y la cadena de bloques de Ethereum, pero aún no me he sumergido profundamente en Solidity y los detalles de implementación. Lo que estoy tratando de determinar es si los contratos inteligentes de Ethereum pueden rastrear la propiedad de un objeto particular del mundo real. Todos los ejemplos que he encontrado hasta ahora demuestran cómo crear una moneda personalizada para que el contrato realmente solo ajuste los saldos numéricos, no transfiera la propiedad de un objeto discreto. Sé que la cadena de bloques de Ethereum puede manejar pagos por estas escrituras usando un token ERC20, pero ¿se puede usar también para rastrear la propiedad de cada escritura o tiene que suceder fuera de la cadena?

Actualizar

Pasé el día mirando muestras y experimentando con Remix y comencé a moverme en la siguiente dirección. Para tu información, acabo de empezar a aprender Solidity hoy, así que sé amable si estoy haciendo algo completamente mal.

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

También acabo de ver el comentario de Ismael sobre los estándares de tokens no fungibles ERC721. Parece que estaba en el camino correcto, pero necesito profundizar en ERC721.

Pregunta de seguimiento: si tuviera que implementar un sistema de pedidos donde los compradores y vendedores de artículos pudieran crear ofertas y demandas, ¿es algo que debería hacer fuera de la cadena y solo usar la cadena de bloques para la transferencia real de fondos y propiedad?

Esta es una pregunta muy amplia. Se puede rastrear cualquier cosa en la cadena (aunque el almacenamiento de datos en la cadena es relativamente costoso). ¿Está preguntando cómo el contrato inteligente sabría la propiedad de un objeto si la persona A y B se conocieron en persona y A vendió el objeto a B sin tocar la cadena?
Si sus objetos tienen algo como un número de serie, puede intentar usar algo como ERC 721 Non-fungible Token Standard .

Respuestas (1)

Si el objeto del mundo real tiene algunos parámetros o atributos que se pueden digitalizar y son únicos para cada objeto, entonces se puede cargar en una cadena de bloques y podemos rastrear su propiedad.

Supongamos que alguien compró un artículo usando ether/token, luego puede agregar un evento de su compra y almacenar su propietario actual. Si la persona quiere vendérselo a otra persona, debe utilizar su contrato o, de lo contrario, estará realizando una transacción ilegal.

Hay una startup que rastrea la propiedad de los diamantes. Dado que los diamantes son indestructibles (casi), sus ángulos y parámetros de reflexión de la luz se pueden almacenar en la cadena de bloques. De esta forma podemos comprobar si el propietario actual es propietario verificado o no.

Puede pensar en algo como esto para hacer su contrato inteligente, use erc20, encuentre algún parámetro que sea distrito, haga que el comprador sea el propietario de esos parámetros en la compra (estructura => mapeo de direcciones), entregue el producto a él / ella.

Espero que esto ayude.:)