Smart contract GPT 2.0
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