Here is the structure of the main functions that explain how the registrar works in simpler terms.
contract NotaRegistrar {// Mint a Nota and escrow tokens insidefunctionwrite(currencyAddress, escrowedAmount, instantAmount, ownerAddress, hookAddress, hookBytes) {validateWrite(currencyAddress, hookAddress);// Reverts on validation OR hookBytes is stored on the hook hookFee = hookAddress.beforeWrite();transferEscrowAndInstantTokens();mintNotaToOwner();increaseHookRevenue();emitWrite();returnincrementedTotalSupply(); }// Transfer your Nota to another ownerfunctionsafeTransferFrom(fromAddress, toAddress, notaId, hookBytes) {// Reverts on validation OR hookBytes is stored on the hook hookFee = nota.hook.beforeTransfer();reduceNotaEscrow();increaseHookRevenue(); ERC721.safeTransferFrom(); }// Add more tokens inside your Notafunctionfund(notaId, escrowAmount, instantAmount, hookBytes) {// Reverts on validation OR hookBytes is stored on the hook hookFee = nota.hook.beforeFund();transferEscrowAndInstantTokens();increaseNotaEscrow();increaseHookRevenue();emitFund(); }// Remove tokens from inside your Notafunctioncash(notaId, cashAmount, recipientAddress, hookBytes) {// Reverts on validation OR hookBytes is stored on the hook hookFee = nota.hook.beforeCash();decreaseNotaEscrow();unEscrowCashingAmount();increaseHookRevenue();emitCash(); }// Approve an address to transfer your Notafunctionapprove(approvedAddress, notaId) {// Reverts on validation OR hookBytes is stored on the hook hookFee = nota.hook.beforeApprove();decreaseNotaEscrow();increaseHookRevenue(); ERC721.approve(); }// Get metadata about your NotafunctiontokenURI(notaId) { HookJSONString = nota.hook.beforeTokenURI();returnconstructNotaJSON(notaId, JSONString); }}
Note that transferFrom() is the exact same as safeTransferFrom() but with empty bytes for the bytesData parameter.