Gostaria de compartilhar como os contratos inteligentes podem ser implementados no ramo imobiliário, para fins de aprendizagem e diversão. Acredito que existe um potencial significativo para contratos inteligentes em transações imobiliárias. Para este caso de uso simples, desenvolvi três cenários diferentes para ilustrar as interações básicas entre o proprietário do contrato, compradores e vendedores no processo de transferência de terras. É essencial reconhecer que as implementações reais de contratos inteligentes para o setor imobiliário podem exigir considerações adicionais, medidas de segurança e interações do usuário além desses cenários simplificados. No entanto, para o escopo do nosso tutorial atual, vamos nos concentrar nos cenários básicos fornecidos.
Cenário para o Proprietário do Contrato:
- Implantação do contrato: O governo, como proprietário do contrato, implanta o contrato inteligente na blockchain para criar um sistema descentralizado de registro de terras.
- Adição de terreno: O proprietário do contrato adiciona terrenos ao contrato chamando a função addLand com a localização e o custo de cada terreno.
- Acordo sobre Aprovadores: O proprietário do contrato facilita o acordo entre compradores e vendedores sobre um aprovador comum para cada transferência de terreno chamando a função agreeOnApprover.
Cenário para um comprador:
- Encontrando um Terreno: O comprador identifica um terreno disponível para venda no contrato verificando os detalhes do terreno usando a função getLand.
- Concordar com um aprovador: O comprador se comunica com o vendedor e ambas as partes concordam com um aprovador comum para a transferência do terreno.
- Iniciando a transferência: Oo comprador chama a função activateTransfer, fornecendo o ID do terreno e o endereço do aprovador acordado como argumentos.
- Aprovação: O comprador aprova a transferência chamando a função aproveTransferAsBuyer.
- Conclusão da transferência: Sse o vendedor também aprovar a transferência chamando a função aproveTransferAsSeller, a transferência será concluída e a propriedade do terreno será transferida para o aprovador.
Cenário para um vendedor:
- Verificação de propriedade: O vendedor confirma a propriedade do terreno verificando o token que representa o terreno e garantindo que este pertence a ele.
- Concordar com um aprovador: O vendedor se comunica com o comprador e ambas as partes concordam com um aprovador comum para a transferência do terreno.
- Iniciando Transferência: O vendedor chama a função generateTransfer, fornecendo o ID do terreno e o endereço do aprovador acordado como argumentos.
- Aprovação: O vendedor então aprova a transferência chamando a função aproveTransferAsSeller.
- Conclusão da transferência:S se o comprador também aprovar a transferência chamando a função aproveTransferAsBuyer, a transferência será concluída e a propriedade do terreno será transferida para o aprovador.
Este é o código do contrato inteligente no Solidity que implementa os cenários descritos acima:
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyLandContract is ERC721Enumerable, Ownable {
struct Land {
string location;
uint cost;
uint landID;
uint wantSell;
address approver;
bool buyerApproved;
bool sellerApproved;
}
uint public totalLandsCounter; // número total de terras através deste contrato
mapping (uint => Land) public lands;
constructor() ERC721("MyContract", "LAND") {
totalLandsCounter = 0;
}
//Evento de adição de terreno
event Add(address indexed _owner, uint _landID);
// Evento de transferência de terreno
event Transfer(address indexed _from, address indexed _to, uint _landID);
// Modificador para verificar se o chamador é dono de um terreno específico
modifier isLandOwner(uint _landID) {
require(_exists(_landID), "Land with this ID does not exist");
require(ownerOf(_landID) == msg.sender, "Caller is not the owner of this land");
_;
}
// Modificador para verificar se o chamador é o aprovador acordado para uma transferência de terreno específica
modifier isAgreedApprover(uint _landID) {
require(_exists(_landID), "Land with this ID does not exist");
require(lands[_landID].approver == msg.sender, "Caller is not the agreed approver for this land transfer");
require(lands[_landID].buyerApproved == false && lands[_landID].sellerApproved == false, "Approval already given");
require(lands[_landID].wantSell == 1, "Land is not available for sale");
require(lands[_landID].cost <= msg.value, "Insufficient payment");
_;
}
// O proprietário deve adicionar terrenos através desta função
function addLand(string memory _location, uint _cost) public onlyOwner {
totalLandsCounter++;
uint landID = totalLandsCounter;
lands[landID] = Land({
location: _location,
cost: _cost,
landID: landID,
wantSell: 1,
approver: address(0),
buyerApproved: false,
sellerApproved: false
});
_mint(msg.sender, landID);
emit Add(msg.sender, landID);
}
// Comprador e Vendedor concordam com o aprovador antes de iniciar o processo de transferência
function agreeOnApprover(uint _landID, address _approver) public isLandOwner(_landID) {
require(lands[_landID].approver == address(0), "Approver already set");
lands[_landID].approver = _approver;
}
//O comprador aprova a transferência
function approveTransferAsBuyer(uint _landID) public {
require(lands[_landID].approver == msg.sender, "Caller is not the agreed approver for this land transfer");
require(lands[_landID].buyerApproved == false, "Transfer already approved by the buyer");
lands[_landID].buyerApproved = true;
checkAndCompleteTransfer(_landID);
}
// Vendedor aprova a transferência
function approveTransferAsSeller(uint _landID) public isLandOwner(_landID) {
require(lands[_landID].sellerApproved == false, "Transfer already approved by the seller");
lands[_landID].sellerApproved = true;
checkAndCompleteTransfer(_landID);
}
//Função para verificar se comprador e vendedor aprovaram a transferência
// Se aprovado, concluia a transferência
function checkAndCompleteTransfer(uint _landID) private {
if (lands[_landID].buyerApproved && lands[_landID].sellerApproved) {
_transfer(ownerOf(_landID), lands[_landID].approver, _landID);
lands[_landID].ownerAddress = lands[_landID].approver;
lands[_landID].wantSell = 0;
address payable seller = payable(ownerOf(_landID));
seller.transfer(lands[_landID].cost);
emit Transfer(ownerOf(_landID), lands[_landID].approver, _landID);
}
}
// Obtém detalhes do terreno de uma conta
function getLand(uint _landID) public view returns (string memory, uint, address, uint, uint) {
require(_exists(_landID), "Land with this ID does not exist");
Land memory land = lands[_landID];
return (land.location, land.cost, ownerOf(_landID), land.landID, land.wantSell);
}
//Retirar o terreno da venda
function removeFromSale(uint _landID) public isLandOwner(_landID) {
lands[_landID].wantSell = 0;
}
}
Vamos decompor o código para explicar as principais funções:
Em primeiro lugar, o contrato herda dois contratos importantes do OpenZeppelin: ERC721Enumerable e Ownable. Ao aproveitar o padrão ERC-721, o contrato permite a criação de tokens únicos e não fungíveis. Cada token serve como representação de uma parcela distinta de terreno.
A função addLand concede ao proprietário do contrato (governo) a capacidade de adicionar terras ao contrato. Esta função é definida como pública e vem com o modificador onlyOwner, que garante que somente o proprietário do contrato possa utilizá-la. Quando invocada, a função requer dois parâmetros: _location (a localização do terreno) e _cost (o custo do terreno).
Como parte do processo, totalLandsCounter é incrementado em um para gerar um landID exclusivo para o terreno recém-adicionado. Uma nova struct Land é então criada, capturando os atributos fornecidos, como localização e preço, juntamente com as configurações padrão para aprovador, buyerApproved e sellerApproved.
Em seguida, a estrutura Land recentemente formada é incluída no mapeamento das terras usando o landID como chave. Isso garante que todos os detalhes essenciais do terreno recém-adicionado sejam armazenados com segurança.
Para finalizar o processo, a função _mint do ERC721 é chamada para estabelecer um novo token ERC-721 que representa com precisão o terreno. A propriedade do token é atribuída ao proprietário do contrato (governo), e todos os detalhes pertinentes do terreno são mantidos com segurança no mapeamento do terreno. Isso permite referência futura e transferência contínua dos tokens de terreno.
Por fim, o evento Add é acionado, notificando imediatamente os ouvintes de que um novo terreno foi adicionado com sucesso ao contrato. O evento contém o endereço do proprietário do contrato (msg.sender) e o landID do terreno recentemente adicionado.
Deixe-me explicar melhor como funciona a venda e transferência de um token de terreno no contrato inteligente:
- Venda do terreno (acordo com um aprovador)
Digamos que um vendedor queira vender seu terreno a um comprador e ambas as partes cheguem a um acordo sobre um aprovador antes de iniciar o processo de transferência.
- O vendedor chama a função
agreeOnApprover
e fornece olandID
do terreno que deseja vender, juntamente com o endereço doaprovador
acordado. - A função
agreeOnApprover
verifica se o chamador é o proprietário do terreno (o vendedor) e define oaprovador
para aquele terreno específico.
- Iniciando a transferência (comprador inicia transferência)
Após concordar com o aprovador, o comprador toma a iniciativa de iniciar a transferência do terreno:
- O comprador chama a função
initiateTransfer
e fornece olandID
do terreno que pretende comprar, juntamente com o endereço doaprovador
acordado. - A função
initiateTransfer
verifica se quem chama é o comprador e se o terreno está disponível para venda. - A função atualiza o sinalizador
buyerApproved
para indicar que o comprador iniciou a transferência.
- Aprovação do Vendedor e do Comprador
Tanto o vendedor quanto o comprador precisam aprovar a transferência antes que ela possa ser concluída:
- O vendedor aprova a transferência chamando a função
approveTransferAsSeller
e fornecendo olandID
. - O comprador aprova a transferência chamando a função
approveTransferAsBuyer
e fornecendo olandID
.
- Concluindo a transferência
Depois que o comprador e o vendedor aprovarem a transferência, a transferência será concluída:
- A função
checkAndCompleteTransfer
é invocada, verificando sebuyerApproved
esellerApproved
estão definidos como verdadeiros. - Se ambas as aprovações forem verdadeiras, a função transfere a propriedade do terreno do vendedor para o “aprovador” acordado.
- O sinalizador
wantSell
do terreno é definido como 0, indicando que o terreno não está mais disponível para venda. - O “aprovador” acordado assume a propriedade do token do terreno e o custo do terreno é transferido para o vendedor.
Desta forma, o token de terreno é vendido e transferido com sucesso do vendedor para o comprador, com o envolvimento do aprovador acordado.
Em conclusão, o contrato inteligente apresentado demonstra como a tecnologia blockchain, através do uso de Solidity e OpenZeppelin, pode ser aproveitada para implementar um sistema descentralizado de registo imobiliário. O contrato utiliza o padrão ERC-721 para criar tokens únicos e não fungíveis, cada um representando uma parcela distinta de terreno.
O proprietário do contrato, normalmente uma entidade governamental, tem autoridade para adicionar terras ao contrato, facilitando a criação de um registo imobiliário digital. Compradores e vendedores interagem com o contrato para iniciar transferências de terras, e um aprovador acordado desempenha um papel crucial na conclusão do processo de transferência.
Embora o contrato aqui apresentado sirva como um exemplo simplificado para fins educativos e ilustrativos, em implementações no mundo real, deve ser dada especial atenção à segurança, auditabilidade e conformidade com os regulamentos relevantes para garantir a praticidade e fiabilidade do contrato no tratamento de transações imobiliárias.
Num futuro próximo, os contratos inteligentes têm o potencial de revolucionar o setor imobiliário, oferecendo transparência, imutabilidade e automação nas transferências de propriedade de terras, simplificando e melhorando a eficiência do processo.
Se você achar esta informação útil, considere me apoiar e me seguir para obter mais atualizações.🙂
Blockchain de contrato inteligente
Este artigo foi escrito por Brian e traduzido por Diogo Jorge. O artigo original pode ser encontrado aqui.
Latest comments (0)