GPT - Smart Contracts

Greener - Rede Ethereum

Acreditamos que a transparência é o passo mais importante

contract GPT is ERC20, Ownable { address _admin; bytes32 generatedHash; mapping(bytes32 => string[]) public compensatedData; mapping(address => bool) public approvedBurners;

No contrato GPT, herdamos o ERC20 do Openzeppelin, e o Ownable personalizado, que será explicado abaixo. Temos as variáveis para guardar o admin do contrato (ou owner), e bytes32 generatedHash, que são as hashs geradas com a compensação. Contamos com 2 mappings, o primeiro, toma como chave a hash criada na compensação, e mostra os dados, como id da fazenda, quantidade etc. O segundo mapping é apenas para verificar se um endereço está como true, para poder chamar a função de compensar. (Só é possível adicionar o admin como approvedBurner).

constructor( string memory name, string memory symbol, uint256 initialSupply, address admin ) ERC20(name, symbol) { _admin = admin; _mint(msg.sender, initialSupply); } Iniciamos o contrato normalmente, passando os 4 parametros. Admin deve ser o endereço da fireblocks, e mintamos o valor total para o msg.sender, que também será a fireblocks.

function mint(address to, uint256 amount) public onlyOwner { _mint(to, amount); } Função padrão de mint. onlyOwner, pois, a fireblocks, e qualquer owner adicionado pode mintar (bridge, por exemplo).

function decimals() public view virtual override returns (uint8) { return 6; } Função para decimais, pois, por padrão é 18. Mudando para 6.

function approveBurner() public { require(msg.sender != _admin, "admin can't self approve"); approvedBurners[address(_admin)] = true; função para aprovar o admin a compensar o GPT. Admin não pode se auto aprovar function revokeBurnerApproval() internal { approvedBurners[address(_admin)] = false; } Função interna, após a compensação, o admin retorna para false, aguardando outro pedido de compensação para poder burnar novamente.

function generate(string[] memory data) internal returns (bytes32) { generatedHash = keccak256(abi.encode(data)); compensatedData[generatedHash] = data; return generatedHash; } Função interna, utilizada pela função de compensar. Essa função recebe um array de string com os dados da compensação, e codifica, gerando uma hash.

function burnFrom(address from, uint256 amount) internal returns (bool) { require( approvedBurners[msg.sender] == true, "Only approved burner can call this function" ); _burn(from, amount); revokeBurnerApproval(); return true; } Burn from, função interna, onde o msg.sender deve estar aprovado em approvedBurners, realiza o burn no endereço passado como parâmetro, e perde seu direito de burnar. É utilizada na função abaixo.

function compensate( address from, uint256 amount, string[] memory data ) public onlyOwner returns (bytes32) { generate(data); require(burnFrom(from, amount), "Burn didn't worked"); return (generatedHash); } Função de compensar. Recebe o endereço do usuário, quantidade a ser compensada e os dados da compensação. Gera a hash, depois realiza o burn e retorna essa hash, para podermos guardar e consultá-la futuramente.

function burn( address from, uint256 amount ) public onlyOwner returns (bool) { _burn(from, amount); return true; } Função padrão de burn. Onlyowner, pois, a fireblocks, e qualquer owner adicionado pode burnar (bridge, por exemplo).

CONTRATO OWNABLE:

abstract contract Ownable is Context { mapping(address => bool) private _owner;

event OwnershipAdded(address indexed newOwner); event OwnershipRemoved(address indexed removedOwner);

mapping que salva o endereço do owner, com true ou false. E dois eventos indicando owner added ou removed

constructor() { _addOwnership(_msgSender()); } Já é iniciado adicionando o msg sender como owner (no caso a fireblocks, que fará o deploy).

modifier onlyOwner() { _checkOwner(); _; } Modifier que estamos utilizando.

function _checkOwner() internal view virtual { require( _owner[_msgSender()] == true, "Ownable: caller is not the owner" ); } Check owner, conforme usado no modifier, verifica se o endereço está como true, se não tiver, não é owner.

function addOwnership(address newOwner) public virtual onlyOwner { require( newOwner != address(0), "Ownable: new owner is the zero address" ); _addOwnership(newOwner); } Add ownership, recebe um endereço e o muda para true, permitindo que este seja owner (fireblocks pode add um outro endereço, tornando possível a bridge). Só um owner pode add outro.

function _addOwnership(address newOwner) internal virtual { _owner[newOwner] = true; emit OwnershipAdded(newOwner); } Função interna que de fato adiciona o endereço como true, e emite o evento de owner adicionado.

function renounceOwnership(address removedOwner) public virtual onlyOwner { _owner[removedOwner] = false; emit OwnershipRemoved(removedOwner); } Função que apenas um owner pode chamar, recebe um endereço e o torna falso como owner. Removendo as permissões.

function readOwner(address owner) public view returns (bool) { return _owner[owner]; } Read owner recebe o endereço e verifica se está true ou false. Função de leitura apenas

Last updated