{"id":38990261,"url":"https://github.com/uncopied/epoch_smart_contract","last_synced_at":"2026-01-17T17:02:17.265Z","repository":{"id":114241586,"uuid":"372752749","full_name":"uncopied/epoch_smart_contract","owner":"uncopied","description":"Smart Contract for EPOCH \"FREEPORT\" NFT.","archived":false,"fork":false,"pushed_at":"2021-06-12T05:40:51.000Z","size":29,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2023-09-25T03:55:22.556Z","etag":null,"topics":["algorand","nft","smartcontract","teal"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/uncopied.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-06-01T08:15:21.000Z","updated_at":"2021-10-25T10:32:32.000Z","dependencies_parsed_at":"2023-09-25T03:52:47.856Z","dependency_job_id":null,"html_url":"https://github.com/uncopied/epoch_smart_contract","commit_stats":{"total_commits":11,"total_committers":2,"mean_commits":5.5,"dds":0.09090909090909094,"last_synced_commit":"528475fef416906fe20792746f74d22d56383937"},"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"purl":"pkg:github/uncopied/epoch_smart_contract","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uncopied%2Fepoch_smart_contract","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uncopied%2Fepoch_smart_contract/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uncopied%2Fepoch_smart_contract/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uncopied%2Fepoch_smart_contract/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/uncopied","download_url":"https://codeload.github.com/uncopied/epoch_smart_contract/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uncopied%2Fepoch_smart_contract/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28511876,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T13:38:16.342Z","status":"ssl_error","status_checked_at":"2026-01-17T13:37:44.060Z","response_time":85,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorand","nft","smartcontract","teal"],"created_at":"2026-01-17T17:02:17.174Z","updated_at":"2026-01-17T17:02:17.250Z","avatar_url":"https://github.com/uncopied.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Smart Contract to manage NFTs minted on Algorand By Epoch\nThis is an explanation of the smart contract for artistic NTFs on Algorand. The NFTs will be traded on the Epoch website based on agreed standards for asset identification and metadata. This contract is meant for Epoch and allows the management of royalties not just on initial NFT transaction but also on all future NFT transactions.\n\n\n## What Does this Contract Achieve\nThe purpose of this contract is to enable royalty transactions for Epoch and to also guide the creation of NFTs, for this purpose, the Algorand blockchain and  TEAL(Transaction Execution Approval Language) has been chosen as the desired Blockchain and smart contract language.\n\n## Things to understand before proceeding\n- A royalty transaction is a transaction that allows a creator of a content to be rewarded for his content by a buyer of such content, in our case, the content is the NFT.\n\n- NFTs are created as ASA (Algorand Standard Assets) under the Algorand public blockchain.\n- Atomic transactions are transactions that are grouped together such that if one fails, all fail.\n\n## How do we achieve this?\nWe are going to solve this particular problem using an Atomic transaction that contains 10 transactions and another that contains 11 transactions, but first, it is good that you understand that there are two types of royalty transactions in our case :\n1. A creator selling his NFT to a buyer.\n2. A buyer giving or selling his NFT to a new Buyer\n\n##  A creator selling his NFT to a buyer.\n- The first transaction is a transaction sending the NFT to the new Buyer\n- The second transaction sends 30% of the sales to Epoch(The address that created the contract).\n- The third transaction is an application call transaction that calls the required Application(Stateful Smart Contract)\n- The fourth to 10th transaction send  10% of the initial sale to 7 other artists\n\n## A buyer giving or selling his NFT to a new Buyer\n- The first transaction sends 12.5% of 20% of the new sale to  Epoch(Creator of the Contract)\n- The second transaction sends 80% of the new sale to the seller of the NFT\n- The third transaction makes the application call.\n- The fourth transaction sends the NFT to the new buyer \n- The fifth to eleventh transaction sends 12.5% each of 20% of the new sale to the 7 artists\n\n# Order Of Transactions For A Royalty Transaction To Take Place\n1. An atomic transaction that creates an asset with default frozen true and also a stateful smart contract which stores the price of a single unit of the NFT, the address of the sender of the **create application** call  transaction along with the address of the 7 other artists that receive royalties\n\n2. A compilation of a stateless smart contract that includes the application id of the stateful smart contract, will give us an address.\n\n3. Funding the stateless smart contract address.\n4. Performing an asset configuration transaction of the created asset to make the clawback address be the stateless smart contract address\n5. Performing an opt-in transaction to opt the buyer of the NFT(asset) into the asset\n6. An atomic transaction groups the 10 or 11 transactions described earlier together in order to have a successful transaction\n\n\n# Code And Explanation\n## Stateful Smart Contract\nA stateful smart contract allows us to store certain values on the Algorand blockchain, for our use case, we will be storing the price of the NFT along with the address of the creator and the seven artists. Let's write the TEAL code for this in a file and call it freeport.teal\n\n```TEAL\n#pragma version 3\nint 0\ntxn ApplicationID\n==\nbnz creation\n```\nthe first line defines the version of the Teal programming language we are using. In our case, its version 3, the next three lines load 0 and the current application ID to the stack and compare them, this returns 1 if they are equal and 0 if they are not. Make sure to note that for a stateful smart contract that is just being created, the Application ID is always 0, so, with this, we can always specify the actions we intend to take when our Stateful smart contract is just being created. so the fourth line in the code above uses the bnz(Branch Not Zero) command to jump to a branch in our code called creation if the comparison is not zero(false). And when we call this Teal program for the first time, the comparison of 0 and the application id will definitely not be zero since it is just being created. So let's proceed to create this branch of our code called creation.\n```TEAL\n\ncreation:\nbyte \"Creator\"\ntxn Sender\napp_global_put\nbyte \"Neil\"\ngtxna 1 ApplicationArgs 2\napp_global_put\nbyte \"Sarah\"\ngtxna 1 ApplicationArgs 3\napp_global_put\nbyte \"Alice\"\ngtxna 1 ApplicationArgs 4\napp_global_put\nbyte \"Juan\"\ngtxna 1 ApplicationArgs 5\napp_global_put\nbyte \"Alexandra\"\ngtxna 1 ApplicationArgs 6\napp_global_put\nbyte \"Amanda\"\ngtxna 1 ApplicationArgs 7 \napp_global_put\nbyte \"Hirad\"\ngtxna 1 ApplicationArgs 8\napp_global_put\nbyte \"Price\"\ngtxna 1 ApplicationArgs 0\nbtoi\napp_global_put\n\nglobal GroupSize\nint 2\n\u003e=\ngtxn 0 TypeEnum\nint acfg\n==\n\u0026\u0026\ngtxn 0 ConfigAssetDefaultFrozen\nint 1\n==\n\u0026\u0026\nreturn\n```\n\nWe store the address of the Caller of the **Create Application** call transaction, then we  proceed to store the address of the 7 other artists using their names as the key. We also make sure that the asset that is created with this Application has a default frozen of true.\n\n That's presently all for our Stateful smart contract creation logic, let's look at the rest of our code after the `bnz creation` line earlier:\n\n```TEAL\nint UpdateApplication\ntxn OnCompletion\n==\nbnz updateApp\n\n```\nIn the code above, we check if the application is being updated and we send program execution to the updateApp branch, lets take a look at this branch\n\n```TEAL\nupdateApp:\nbyte \"Creator\"\napp_global_get\ntxn Sender\n==\nreturn\n```\nThe updateApp branch simply checks if the creator of the contract is the one calling the contract and allows the app(contract) to be updated, if not, it doesn't allow the app to be updated.\n\nLet's proceed with our code after the bnz updateApp Line:\n\n```TEAL\nint DeleteApplication\ntxn OnCompletion\n==\nbnz DeleteApp\n```\nIn the code above, we check if the application(contract) is being deleted and we send program execution to the DeleteApp branch, lets take a look at this branch\n\n```TEAL\nDeleteApp:\nbyte \"Creator\"\napp_global_get\ntxn Sender\n==\nreturn\n```\nThe DeleteApp branch simply checks if the creator of the contract is the one calling the contract and allows the app(contract) to be deleted, if not, it doesn't allow the app to be deleted.\n\nLet's proceed with our code after the bnz DeleteApp Line:\n\n```\nbyte \"Creator\"\napp_global_get\ngtxn 0 AssetSender\n==\nbnz txSentFromCreator\n```\nWe simply check if the Person sending the asset is the creator of the asset and then send him to the `txSentFromCreator` branch as this is how we know if this is an initial transaction of that NFT or a secondary transaction.\n\nLets check the code in this branch out:\n\n```TEAL\ntxSentFromCreator:\nglobal GroupSize\nint 10\n==\ngtxn 0 AssetAmount\nint 1 \n==\n\u0026\u0026\ngtxn 1 Receiver\ngtxn 0 AssetSender\n==\n\u0026\u0026\nbyte \"Neil\"\napp_global_get\ngtxn 3 Receiver\n==\n\u0026\u0026\nbyte \"Sarah\"\napp_global_get\ngtxn 4 Receiver\n==\n\u0026\u0026\nbyte \"Alice\"\napp_global_get\ngtxn 5 Receiver\n==\n\u0026\u0026\nbyte \"Juan\"\napp_global_get\ngtxn 6 Receiver\n==\n\u0026\u0026\nbyte \"Alexandra\"\napp_global_get\ngtxn 7 Receiver\n==\n\u0026\u0026\nbyte \"Amanda\"\napp_global_get\ngtxn 8 Receiver\n==\n\u0026\u0026\nbyte \"Hirad\"\napp_global_get\ngtxn 9 Receiver\n==\n\u0026\u0026\ngtxn 3 Amount\ngtxn 4 Amount\n+\ngtxn 5 Amount\n+\ngtxn 6 Amount\n+\ngtxn 7 Amount\n+\ngtxn 8 Amount\n+\ngtxn 9 Amount\n+\ngtxn 1 Amount\n+\nstore 10\ngtxn 3 Amount\nint 100\n*\nload 10\n/\nint 10\n==\n\u0026\u0026\ngtxn 4 Amount\nint 100\n*\nload 10\n/\nint 10\n==\n\u0026\u0026\ngtxn 5 Amount\nint 100\n*\nload 10\n/\nint 10\n==\n\u0026\u0026\ngtxn 6 Amount\nint 100\n*\nload 10\n/\nint 10\n==\n\u0026\u0026\ngtxn 7 Amount\nint 100\n*\nload 10\n/\nint 10\n==\n\u0026\u0026\ngtxn 8 Amount\nint 100\n*\nload 10\n/\nint 10\n==\n\u0026\u0026\ngtxn 9 Amount\nint 100\n*\nload 10\n/\nint 10\n==\n\u0026\u0026\ngtxn 1 Amount\nint 100\n*\nload 10\n/\nint 30\n==\n\u0026\u0026\nbyte \"Price\"\napp_global_get\nload 10\n==\n\u0026\u0026\nreturn\n```\n\n\nIn the code above we make several checks in the following order:\n\n- We  check that there are exactly 10 transactions.\n- We check that it is only 1 unit of this asset that is sent.\n- We check that the Receiver of the 30% Royalty in the second transaction is equal to the AssetSender.\n- We then Check that transactions 4 to 10 contain the right receivers which are the seven artists.\n- We add up all the amounts in  every transaction together then save it in a scratchpad\n- We confirm that the amount transferred in transaction 4 to 10 is 10% of the total amount in all transactions.\n- We check that the Amount in transaction 2 sent to the Creator of the Application is equal to 30% of the total amounts in all transactions.\n- We check that the total amounts in all transaction is equal to the price set by the creator\n\nAnd finally we return.\n\n\nSo let's proceed to the lines after our `bnz txSentFromCreator` line:\nDo note that this is the line of code that executes if its a secondary sale\n```\n\nglobal GroupSize\nint 11\n==\ngtxn 3 AssetAmount\nint 1 \n==\n\u0026\u0026\nbyte \"Creator\"\napp_global_get\ngtxn 0 Receiver\n==\n\u0026\u0026\nbyte \"Neil\"\napp_global_get\ngtxn 4 Receiver\n==\n\u0026\u0026\nbyte \"Sarah\"\napp_global_get\ngtxn 5 Receiver\n==\n\u0026\u0026\nbyte \"Alice\"\napp_global_get\ngtxn 6 Receiver\n==\n\u0026\u0026\nbyte \"Juan\"\napp_global_get\ngtxn 7 Receiver\n==\n\u0026\u0026\nbyte \"Alexandra\"\napp_global_get\ngtxn 8 Receiver\n==\n\u0026\u0026\nbyte \"Amanda\"\napp_global_get\ngtxn 9 Receiver\n==\n\u0026\u0026\nbyte \"Hirad\"\napp_global_get\ngtxn 10 Receiver\n==\n\u0026\u0026\ngtxn 4 Amount\ngtxn 5 Amount\n+\ngtxn 6 Amount\n+\ngtxn 7 Amount\n+\ngtxn 8 Amount\n+\ngtxn 9 Amount\n+\ngtxn 10 Amount\n+\ngtxn 1 Amount\n+\ngtxn 0 Amount\n+\nstore 11\nload 11\nint 20\n*\nint 100\n/\nstore 12\ngtxn 0 Amount\nint 1000\n*\nload 12\n/\nint 125\n==\n\u0026\u0026\ngtxn 4 Amount\nint 1000\n*\nload 12\n/\nint 125\n==\n\u0026\u0026\ngtxn 5 Amount\nint 1000\n*\nload 12\n/\nint 125\n==\n\u0026\u0026\ngtxn 6 Amount\nint 1000\n*\nload 12\n/\nint 125\n==\n\u0026\u0026\ngtxn 7 Amount\nint 1000\n*\nload 12\n/\nint 125\n==\n\u0026\u0026\ngtxn 8 Amount\nint 1000\n*\nload 12\n/\nint 125\n==\n\u0026\u0026\ngtxn 9 Amount\nint 1000\n*\nload 12\n/\nint 125\n==\n\u0026\u0026\ngtxn 10 Amount\nint 1000\n*\nload 12\n/\nint 125\n==\n\u0026\u0026\nreturn\n\n```\nWe make the following checks for secondary sales in the code above:\n\n- We check that there at exactly 11 transactions\n- We check that the asset amount transferred in the fourth transaction is equal to 1\n- We make sure that the Creator of the application is the receiver of the 12.5% of 20% of the new sale in the first transaction.\n- We make sure that the receivers in transaction 5 to 11 are equal to the address of the 7 artists we saved earlier.\n- We add up all the amounts in all the transactions and store it to the scratch space\n- We store 20 % of the total amount in all transactions to the scratchspace\n- We check that the amount sent in the first transaction to the creator is equal to 12.5% of the 20% the total transaction\n- We check that the amount sent in transaction 5 to 11 is equal to 12.5% of the 20% of the total transaction.\n\n# Stateless Smart Contract\nLet's create a file and call it Epoch.teal, this file will house our stateless smart contract which when compiled will be used as our clawback address, let's look at the code for this file\n```TEAL\n#pragma version 3\ngtxn 0 RekeyTo\nglobal ZeroAddress\n==\ngtxn 1 RekeyTo\nglobal ZeroAddress\n==\n\u0026\u0026\ngtxn 2 RekeyTo\nglobal ZeroAddress\n==\n\u0026\u0026\ngtxn 0 CloseRemainderTo\nglobal ZeroAddress\n==\n\u0026\u0026 \ngtxn 1 CloseRemainderTo\nglobal ZeroAddress\n==\n\u0026\u0026 \ngtxn 2 CloseRemainderTo\nglobal ZeroAddress\n==\n\u0026\u0026 \ngtxn 0 AssetCloseTo\nglobal ZeroAddress\n==\n\u0026\u0026\ngtxn 1 AssetCloseTo\nglobal ZeroAddress\n==\n\u0026\u0026\ngtxn 2 AssetCloseTo\nglobal ZeroAddress\n==\n\u0026\u0026\ntxn Fee\nint 10000\n\u003c=\n\u0026\u0026\nglobal GroupSize\nint 10\n\u003e=\n\u0026\u0026\ngtxn 2 TypeEnum\nint appl\n==\n\u0026\u0026\ngtxn 2 ApplicationID\nint 16016196\n==\n\u0026\u0026\n```\n\nWe check for that the rekeyto address of the first three transactions is a zeroadddress so no one can rekey our transaction to use a different clawback address for sending, we check that the closeRemainderTo for the first three transactions is also a zero address and that the AssetCloseTo of the first three transactions should be the zero Address. \nLastly, we make sure the transaction fee is not more than 10000 micro algos so a malicious party does not try to exhaust our funds by setting a high transaction fee, we make sure this transaction is grouped with at least 9 other transactions, then we make sure the third transaction is an application call transaction and lastly we check if the application id of the third transaction is equal to the application id of our stateful smart contract address, the nos 16016196 should be changed to the application id of the stateful smart contract before this is compiled, a simple find and replace transaction with any programming language should do this fine.\n\n# Transactions Demo\nSo now, let's try to run through the order of transactions above using the goal command-line tool.\n1. An atomic transaction that creates an asset with default frozen true and also a stateful smart contract which stores the price of a single unit of the NFT, the address of the sender of the **create application** call  transaction along with the address of the 7 other artists that receive royalties:\n\n```bash\ngoal asset create  --assetmetadatab64 \"16efaa3924a6fd9d3a4824799a4ac65d\"  --asseturl \"www.coolade.com\" --creator \"6OQQDT3FI2FY4TY6XFW7I7QFTSTQWH2TP3AF5U3W42TR6SMQPXEJX7TZAA\" --decimals 0 --defaultfrozen=true --total 1000 --unitname nljh --name myas --out=unsginedtransaction1.tx\n\ngoal app create --creator 6OQQDT3FI2FY4TY6XFW7I7QFTSTQWH2TP3AF5U3W42TR6SMQPXEJX7TZAA --app-arg \"int:1000000\" --app-arg \"int:5\" --app-arg \"addr:BN5DMMUOAJCR4SZUGPK3ICQFZ3JXSS24GWDY2B6P56K2SH4EADO6XN56GQ\"  --app-arg \"addr:DG5UXOMPCEPT2SKQ4UJMRNEYDCOABYM3EFR4UW6E3OXF2ME2LF5APS5KLA\"  --app-arg \"addr:DQIEID66TVX55BYECL7UUPIB2OE5ZQGNMFDLE7HRQDNGLTG3UXRBBXOWF4\"  --app-arg \"addr:EJKLHQS5GRXAKEY2U62YIFBSZPMVTDPL6EQD7XKNN7A33Z7XSYPUCMOODQ\"  --app-arg \"addr:F5N2DN7KIX5EL646GMGV4AQVZHGQJBEIFJR3FEIDVAZP7RGUTBU7LGRRO4\"  --app-arg \"addr:JYURMSAFWF3BFC6ZJ2WXNQFHBKZONXSVLB6GIH3EH4ZA7Y4PPITDZYVDXU\"  --app-arg \"addr:VEKJYW4IIOKGVBI67S5VDQB7ZOHPGJPLRXMI2GG53BAYTB6MZA27S4ALQA\"     --approval-prog ../contracts/freeport.teal --global-byteslices 10 --global-ints 2 --local-byteslices 1 --local-ints 1 --clear-prog ../contracts/clear.teal --out=unsginedtransaction2.tx\n\n# group both transactions\ncat unsginedtransaction1.tx unsginedtransaction2.tx  \u003e combinedtransactions.tx\n\ngoal clerk group -i combinedtransactions.tx -o groupedtransactions.tx \n\ngoal clerk split -i groupedtransactions.tx -o split.tx \n\ngoal clerk sign -i split-0.tx -o signout-0.tx\n\ngoal clerk sign -i split-1.tx -o signout-1.tx\n\ncat signout-0.tx signout-1.tx  \u003e signout.tx\n\ngoal clerk rawsend -f signout.tx\n```\nWhen i run the commands above on my PC presently, the atomic transaction is successful with the following transaction IDs VMWUIQ22RI2MA5R4F7DQUBPSERWQVPBMVKHXX2PEJLUFOCN2RE7A,Y2TJZZ2HZOXTJ23S6SSHZYXYJQTCJL6IBHXAXTEYIB5KTZFBQNEA\n\nWhen i inspect both of them on testnet.algoexplorer.io, I find out the following information\n\nAsset Id: 16016195\n\nApplication Id : 16016196\n\n2. A compilation of a stateless smart contract that includes the application id of the stateful smart contract, will give us an address.\n```bash\ngoal clerk compile ../contracts/epoch.teal\n```\nwhen I run the command above, I get XA5WEWCKTSR246S7I566J7NLGSBH24QUUAWYOSMBBZOI2DQDFHUB2GO2RU as the address.\n\n3. Funding the stateless smart contract address you can fund the address on https://bank.testnet.algorand.network/\n\n4. Performing an asset configuration transaction of the created asset to make the clawback address be the stateless smart contract address\n\n```bash\ngoal asset config --manager 6OQQDT3FI2FY4TY6XFW7I7QFTSTQWH2TP3AF5U3W42TR6SMQPXEJX7TZAA  --new-clawback  XA5WEWCKTSR246S7I566J7NLGSBH24QUUAWYOSMBBZOI2DQDFHUB2GO2RU --assetid 16016195      \n```\nWhen I do this, I get a successful transaction with a transaction id of XSXQCK6DO2XGZ6Z4FZS2L6NAYOELCVSY2LJTEB4UZIYOHGWWGU7A, feel free to inspect this id on https://testnet.algoexplorer.io/\n\n\n5. Performing an opt-in transaction to opt the buyer of the NFT(asset) into the asset. Next, we need to opt-in the account of the buyer so he can receive the NFTs.\n```bash\ngoal asset send -a 0 -f XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY -t XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY   --assetid 16016195   \n```\nAfter running this, I get a transaction with the following id AEFUJKO4JWQF5XOMQOHO4YB6RBV2OO32YXRWRTY6IPKDTVIEPCPA, feel free to inspect this id on https://testnet.algoexplorer.io/\n\n6. An atomic transaction groups the 10 or 11 transactions described earlier together in order to have a successful transaction\n\n```bash\ngoal asset send --amount 1 --assetid 16016195       --from 6OQQDT3FI2FY4TY6XFW7I7QFTSTQWH2TP3AF5U3W42TR6SMQPXEJX7TZAA --to XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --clawback  XA5WEWCKTSR246S7I566J7NLGSBH24QUUAWYOSMBBZOI2DQDFHUB2GO2RU  --out unsignedAssetSend.tx\n\ngoal clerk send --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --to 6OQQDT3FI2FY4TY6XFW7I7QFTSTQWH2TP3AF5U3W42TR6SMQPXEJX7TZAA --amount 300000 --out unsignedSend.tx\n\ngoal app call --from 6OQQDT3FI2FY4TY6XFW7I7QFTSTQWH2TP3AF5U3W42TR6SMQPXEJX7TZAA --app-id 16016196 --out unsignedFreeportCall.tx\n\ngoal clerk send --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --to BN5DMMUOAJCR4SZUGPK3ICQFZ3JXSS24GWDY2B6P56K2SH4EADO6XN56GQ --amount 100000 --out unsignedSend0.tx\ngoal clerk send --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --to DG5UXOMPCEPT2SKQ4UJMRNEYDCOABYM3EFR4UW6E3OXF2ME2LF5APS5KLA --amount 100000 --out unsignedSend1.tx\ngoal clerk send --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --to DQIEID66TVX55BYECL7UUPIB2OE5ZQGNMFDLE7HRQDNGLTG3UXRBBXOWF4 --amount 100000 --out unsignedSend2.tx\ngoal clerk send --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --to EJKLHQS5GRXAKEY2U62YIFBSZPMVTDPL6EQD7XKNN7A33Z7XSYPUCMOODQ --amount 100000 --out unsignedSend3.tx\ngoal clerk send --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --to F5N2DN7KIX5EL646GMGV4AQVZHGQJBEIFJR3FEIDVAZP7RGUTBU7LGRRO4 --amount 100000 --out unsignedSend4.tx\ngoal clerk send --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --to JYURMSAFWF3BFC6ZJ2WXNQFHBKZONXSVLB6GIH3EH4ZA7Y4PPITDZYVDXU --amount 100000 --out unsignedSend5.tx\ngoal clerk send --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --to VEKJYW4IIOKGVBI67S5VDQB7ZOHPGJPLRXMI2GG53BAYTB6MZA27S4ALQA --amount 100000 --out unsignedSend6.tx\n\n\n\ncat  unsignedAssetSend.tx unsignedSend.tx unsignedFreeportCall.tx  unsignedSend0.tx unsignedSend1.tx unsignedSend2.tx unsignedSend3.tx unsignedSend4.tx unsignedSend5.tx unsignedSend6.tx \u003e combinedNftTransactions.tx\n\n\ngoal clerk group -i combinedNftTransactions.tx -o groupedNftTransactions.tx \n\ngoal clerk split -i groupedNftTransactions.tx -o splitNft.tx\n\ngoal clerk sign -i splitNft-0.tx --program ../contracts/epoch.teal -o signoutNft-0.tx\n\ngoal clerk sign -i splitNft-1.tx -o signoutNft-1.tx\n\ngoal clerk sign -i splitNft-2.tx -o signoutNft-2.tx\n\ngoal clerk sign -i splitNft-3.tx -o signoutNft-3.tx\n\ngoal clerk sign -i splitNft-4.tx -o signoutNft-4.tx\n\ngoal clerk sign -i splitNft-5.tx -o signoutNft-5.tx\n\ngoal clerk sign -i splitNft-6.tx -o signoutNft-6.tx\n\ngoal clerk sign -i splitNft-7.tx -o signoutNft-7.tx\n\ngoal clerk sign -i splitNft-8.tx -o signoutNft-8.tx\n\ngoal clerk sign -i splitNft-9.tx -o signoutNft-9.tx\n\ncat signoutNft-0.tx signoutNft-1.tx signoutNft-2.tx signoutNft-3.tx signoutNft-4.tx signoutNft-5.tx signoutNft-6.tx signoutNft-7.tx signoutNft-8.tx signoutNft-9.tx \u003e signoutNft.tx\n\ngoal clerk rawsend -f signoutNft.tx\n```\nAfter doing this, I get 10 successful transactions with ids, `QU4NRMWV5UDOFDRDUB2BGBNGBOEZ3VSOHFV5EHCOQVZKCJ2VNPRA` `2XKCJONXX3LTZTG4BLZH5AOY2OX2M3R2T76VN6CCE2H6RN26AJUQ` `G3IFYCRNYO6O3QTN5FO4EI52QQBRXFK36OXZFEUYRKIWCJR65DKQ` `J5XLEQOJWU3447A34NYWPPSTC4DWLKFPH6M6UIPMITHUU66Y4GOA` `VZOCEAIN3AO7EQXCQV5RFFKHYAMMVNDRNNUIOIRF4EDSAIVFACGA` `D3MSHP2Y3WRWKFGIL76TKRSB52425BNXZWYOPY7TZ6LJP4NQGTYQ` `JFXEM5SN2MQOMIM5GIESQLR7HXYJFH5Z5EEMD34P75ZBFLKMLTQA` `UBVUMQ5B6NDHP6HASBAFXT4PX4ORITTPJSSTZMOHCFC2PRP7PVQQ` `OBSQRB4AYW6OVARYSFA2X7K4WPMGGUGQ5QOLBOVF3PTK44OQRRSA` `FEYHLSAW6SSE5SWMISFGY425TLQOQXRQIWCN6WRXUSXT4UB5F2AA`\n\nMeaning our transactions were successful.\n\nUp next is the second type of royalty transaction, where someone who has already bought the NFT sends it to a new buyer:\n\nThe first step here is to opt the new user into the nft:\n```bash\ngoal asset send -a 0 -f WOOWCYJU4DV3LY4BFTRVIF3B3XRQF67YXBM64VC3NJN3OY35C4APYBW6EY -t WOOWCYJU4DV3LY4BFTRVIF3B3XRQF67YXBM64VC3NJN3OY35C4APYBW6EY   --assetid 16016195   \n```\n\n get a successful transaction with the transaction id : NEN4XBZH4TWXNODPKKMBSF3GNDJS3MES3Q54MPX63OLA3IUC5RFA\n\nThen we can send the new buyer the NFT while also sending the percent of the amount transferred to the Creator and the other seven artists :\n\n```bash\n# 12.5% OF 20% payment\ngoal clerk send --from WOOWCYJU4DV3LY4BFTRVIF3B3XRQF67YXBM64VC3NJN3OY35C4APYBW6EY --to 6OQQDT3FI2FY4TY6XFW7I7QFTSTQWH2TP3AF5U3W42TR6SMQPXEJX7TZAA  --amount 50000 --out unsignedSendA.tx\n# Payment from new buyer to previous buyer\ngoal clerk send --from WOOWCYJU4DV3LY4BFTRVIF3B3XRQF67YXBM64VC3NJN3OY35C4APYBW6EY --to XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --amount 1600000 --out unsignedSend.tx\n# App Call Transaction\ngoal app call --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --app-id 16016196 --out unsignedFreeportCall.tx\n# Asset send transaction\ngoal asset send --amount 1 --assetid 16016195       --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --to WOOWCYJU4DV3LY4BFTRVIF3B3XRQF67YXBM64VC3NJN3OY35C4APYBW6EY --clawback  XA5WEWCKTSR246S7I566J7NLGSBH24QUUAWYOSMBBZOI2DQDFHUB2GO2RU  --out unsignedAssetSend.tx\n\ngoal clerk send --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --to BN5DMMUOAJCR4SZUGPK3ICQFZ3JXSS24GWDY2B6P56K2SH4EADO6XN56GQ --amount 50000 --out unsignedSend0.tx\ngoal clerk send --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --to DG5UXOMPCEPT2SKQ4UJMRNEYDCOABYM3EFR4UW6E3OXF2ME2LF5APS5KLA --amount 50000 --out unsignedSend1.tx\ngoal clerk send --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --to DQIEID66TVX55BYECL7UUPIB2OE5ZQGNMFDLE7HRQDNGLTG3UXRBBXOWF4 --amount 50000 --out unsignedSend2.tx\ngoal clerk send --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --to EJKLHQS5GRXAKEY2U62YIFBSZPMVTDPL6EQD7XKNN7A33Z7XSYPUCMOODQ --amount 50000 --out unsignedSend3.tx\ngoal clerk send --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --to F5N2DN7KIX5EL646GMGV4AQVZHGQJBEIFJR3FEIDVAZP7RGUTBU7LGRRO4 --amount 50000 --out unsignedSend4.tx\ngoal clerk send --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --to JYURMSAFWF3BFC6ZJ2WXNQFHBKZONXSVLB6GIH3EH4ZA7Y4PPITDZYVDXU --amount 50000 --out unsignedSend5.tx\ngoal clerk send --from XHFRWIODL7MFJNCWURZY6USPIWUZTQ2X6EWCJ7SWSRKJPUN4LYHO5XK2BY --to VEKJYW4IIOKGVBI67S5VDQB7ZOHPGJPLRXMI2GG53BAYTB6MZA27S4ALQA --amount 50000 --out unsignedSend6.tx\n\n\n\n\ncat unsignedSendA.tx  unsignedSend.tx unsignedFreeportCall.tx  unsignedAssetSend.tx    unsignedSend0.tx unsignedSend1.tx unsignedSend2.tx unsignedSend3.tx unsignedSend4.tx unsignedSend5.tx unsignedSend6.tx \u003e combinedNftTransactions.tx\n\n\ngoal clerk group -i combinedNftTransactions.tx -o groupedNftTransactions.tx \n\ngoal clerk split -i groupedNftTransactions.tx -o splitNft.tx\n\ngoal clerk sign -i splitNft-0.tx -o signoutNft-0.tx\n\ngoal clerk sign -i splitNft-3.tx --program ../contracts/epoch.teal -o signoutNft-3.tx\n\ngoal clerk sign -i splitNft-1.tx -o signoutNft-1.tx\n\ngoal clerk sign -i splitNft-2.tx -o signoutNft-2.tx\n\ngoal clerk sign -i splitNft-4.tx -o signoutNft-4.tx\n\ngoal clerk sign -i splitNft-5.tx -o signoutNft-5.tx\n\ngoal clerk sign -i splitNft-6.tx -o signoutNft-6.tx\n\ngoal clerk sign -i splitNft-7.tx -o signoutNft-7.tx\n\ngoal clerk sign -i splitNft-8.tx -o signoutNft-8.tx\n\ngoal clerk sign -i splitNft-9.tx -o signoutNft-9.tx\n\ngoal clerk sign -i splitNft-10.tx -o signoutNft-10.tx\n\ncat signoutNft-0.tx signoutNft-1.tx signoutNft-2.tx signoutNft-3.tx signoutNft-4.tx signoutNft-5.tx signoutNft-6.tx signoutNft-7.tx signoutNft-8.tx signoutNft-9.tx signoutNft-10.tx  \u003e signoutNft.tx\n\ngoal clerk rawsend -f signoutNft.tx\n\n```\n\nIn the example above 1 unit of our NFT is resold for 2 algo, meaning our Creator gets  0.12 algo(30% of 20% of 2 algo), we send 0.04(10% 0f 20% of 2 algo) algo to our remaining artists, we send 1.6 algo(80% of 2 algo) to the previous buyer.\n\n\nMeaning our transactions were successful and our contracts work as expected.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funcopied%2Fepoch_smart_contract","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funcopied%2Fepoch_smart_contract","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funcopied%2Fepoch_smart_contract/lists"}