├── .gitignore ├── secrets.json ├── _config.yml ├── docs ├── images │ ├── AutoLm.png │ ├── BlocksSideView.PNG │ ├── InheritanceGraph.jpg │ ├── MetaMaskConnect.PNG │ ├── ImmutableChangeBank.PNG │ ├── ImmutableConfigure.PNG │ ├── ImmutableEntityEdit.PNG │ ├── ImmutableEntityMove.PNG │ ├── ImmutableNewProduct.PNG │ ├── ImmutableProducts.PNG │ ├── ImmutableRegister.PNG │ ├── ImmutableTopBanner.PNG │ ├── ImpactVSLikelihood.png │ ├── NoEthereumNetwork.PNG │ ├── RopstenTestNetwork.PNG │ ├── EntityDependencyGraph.jpg │ ├── ImmutableActivations.PNG │ ├── ImmutableConfigureAll.PNG │ ├── ImmutableTokenOffers.PNG │ ├── TokenDependencyGraph.jpg │ ├── ImmutableEntityReferral.PNG │ ├── ImmutableManageEscrows.PNG │ ├── ImmutableProductRelease.PNG │ ├── ImmutablePurchaseTokens.PNG │ ├── ImmutableTokenBlockOffer.PNG │ ├── ImmutableTokenOfferEdit.PNG │ ├── LicenseDependencyGraph.jpg │ ├── ProductDependencyGraph.jpg │ ├── ImmutableActivationDetails.PNG │ ├── ImmutableActivationForSale.PNG │ ├── ImmutableEntityAcceptMove.PNG │ ├── ImmutableTokenOfferBrowse.PNG │ ├── Immutable_BlueOnWhite_Logo.png │ ├── ImmutableBrowseApplications.PNG │ ├── ImmutablePurchaseActivation.PNG │ ├── ImmutableRegisterSecondStep.PNG │ ├── ImmutableRegisteredConfigure.PNG │ ├── ImmutableRegisteredUnapproved.PNG │ ├── ImmutableTokenOfferSelected.PNG │ ├── disclosure-logo-outline-black.png │ ├── ImmutableBrowseSelectedAndVerified.PNG │ ├── ImmutableBrowseSelectedCommercial.PNG │ ├── ImmutableOfferActivationForResale.PNG │ ├── ImmutableActivationChangeIdentifier.PNG │ ├── ImmutableBrowseSelectedAndVerifying.PNG │ ├── ImmutableRegisteredProductLicenseOffer.PNG │ └── ImmutableRegisteredProductLicenseEditOffers.PNG ├── CustomToken.md ├── IERC165Upgradeable.md ├── IERC721ReceiverUpgradeable.md ├── IERC20MetadataUpgradeable.md ├── Migrations.md ├── IERC721MetadataUpgradeable.md ├── StringsUpgradeable.md ├── ERC721BurnableUpgradeable.md ├── IERC721EnumerableUpgradeable.md ├── ERC165Upgradeable.md ├── ContextUpgradeable.md ├── ERC721URIStorageUpgradeable.md ├── IERC20Upgradeable.md ├── OwnableUpgradeable.md ├── SmartContracts.md ├── StringCommon.md ├── Initializable.md ├── IERC721Upgradeable.md ├── ERC721EnumerableUpgradeable.md ├── ProductActivate.md ├── AddressUpgradeable.md ├── ActivateToken.md └── CreatorToken.md ├── migrations ├── 1_initial_migration.js ├── 2_deploy_string_common.js ├── 7_deploy_custom_token.js ├── 3_deploy_entity.js ├── 4_deploy_product.js ├── 9_upgrade_ProductActivate_contract.js ├── 5_deploy_creator.js ├── 10_deploy_collection_proxy.js ├── 10_deploy_ecosystem_contracts_js.bak ├── 11_upgrade_Product_contracts.js ├── 8_upgrade_creator_contract.js └── 6_deploy_activate.js ├── client ├── src │ ├── utils │ │ ├── getWalletConnect.js │ │ └── getWeb3.js │ └── middleware │ │ ├── Utilities.js │ │ └── BackendServer.js └── python-dev │ ├── app.py │ └── record.py ├── contracts ├── Migrations.sol ├── CustomToken.sol ├── CollectionProxy.sol └── StringCommon.sol ├── package.json ├── test └── TestImmutableEcosystemEvents.js ├── openzeppelin-cli-export.json ├── core-terms-USA.md └── truffle-config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules* 2 | build 3 | 4 | .openzeppelin\.session 5 | -------------------------------------------------------------------------------- /secrets.json: -------------------------------------------------------------------------------- 1 | { 2 | "mnemonicPhrase": "", 3 | "projectID": "" 4 | } 5 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman 2 | google_analytics: UA-158371035-1 3 | -------------------------------------------------------------------------------- /docs/images/AutoLm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/AutoLm.png -------------------------------------------------------------------------------- /docs/images/BlocksSideView.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/BlocksSideView.PNG -------------------------------------------------------------------------------- /docs/images/InheritanceGraph.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/InheritanceGraph.jpg -------------------------------------------------------------------------------- /docs/images/MetaMaskConnect.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/MetaMaskConnect.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableChangeBank.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableChangeBank.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableConfigure.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableConfigure.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableEntityEdit.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableEntityEdit.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableEntityMove.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableEntityMove.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableNewProduct.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableNewProduct.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableProducts.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableProducts.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableRegister.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableRegister.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableTopBanner.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableTopBanner.PNG -------------------------------------------------------------------------------- /docs/images/ImpactVSLikelihood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImpactVSLikelihood.png -------------------------------------------------------------------------------- /docs/images/NoEthereumNetwork.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/NoEthereumNetwork.PNG -------------------------------------------------------------------------------- /docs/images/RopstenTestNetwork.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/RopstenTestNetwork.PNG -------------------------------------------------------------------------------- /docs/images/EntityDependencyGraph.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/EntityDependencyGraph.jpg -------------------------------------------------------------------------------- /docs/images/ImmutableActivations.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableActivations.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableConfigureAll.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableConfigureAll.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableTokenOffers.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableTokenOffers.PNG -------------------------------------------------------------------------------- /docs/images/TokenDependencyGraph.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/TokenDependencyGraph.jpg -------------------------------------------------------------------------------- /docs/images/ImmutableEntityReferral.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableEntityReferral.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableManageEscrows.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableManageEscrows.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableProductRelease.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableProductRelease.PNG -------------------------------------------------------------------------------- /docs/images/ImmutablePurchaseTokens.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutablePurchaseTokens.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableTokenBlockOffer.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableTokenBlockOffer.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableTokenOfferEdit.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableTokenOfferEdit.PNG -------------------------------------------------------------------------------- /docs/images/LicenseDependencyGraph.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/LicenseDependencyGraph.jpg -------------------------------------------------------------------------------- /docs/images/ProductDependencyGraph.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ProductDependencyGraph.jpg -------------------------------------------------------------------------------- /docs/images/ImmutableActivationDetails.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableActivationDetails.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableActivationForSale.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableActivationForSale.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableEntityAcceptMove.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableEntityAcceptMove.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableTokenOfferBrowse.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableTokenOfferBrowse.PNG -------------------------------------------------------------------------------- /docs/images/Immutable_BlueOnWhite_Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/Immutable_BlueOnWhite_Logo.png -------------------------------------------------------------------------------- /docs/images/ImmutableBrowseApplications.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableBrowseApplications.PNG -------------------------------------------------------------------------------- /docs/images/ImmutablePurchaseActivation.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutablePurchaseActivation.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableRegisterSecondStep.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableRegisterSecondStep.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableRegisteredConfigure.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableRegisteredConfigure.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableRegisteredUnapproved.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableRegisteredUnapproved.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableTokenOfferSelected.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableTokenOfferSelected.PNG -------------------------------------------------------------------------------- /docs/images/disclosure-logo-outline-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/disclosure-logo-outline-black.png -------------------------------------------------------------------------------- /docs/images/ImmutableBrowseSelectedAndVerified.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableBrowseSelectedAndVerified.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableBrowseSelectedCommercial.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableBrowseSelectedCommercial.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableOfferActivationForResale.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableOfferActivationForResale.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableActivationChangeIdentifier.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableActivationChangeIdentifier.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableBrowseSelectedAndVerifying.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableBrowseSelectedAndVerifying.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableRegisteredProductLicenseOffer.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableRegisteredProductLicenseOffer.PNG -------------------------------------------------------------------------------- /docs/images/ImmutableRegisteredProductLicenseEditOffers.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmutableSoft/ImmutableEcosystem/HEAD/docs/images/ImmutableRegisteredProductLicenseEditOffers.PNG -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | var Migrations = artifacts.require("Migrations"); 2 | 3 | module.exports = function(deployer) { 4 | // Deploy the Migrations contract as our only task 5 | deployer.deploy(Migrations); 6 | }; 7 | -------------------------------------------------------------------------------- /migrations/2_deploy_string_common.js: -------------------------------------------------------------------------------- 1 | // migrations/NN_deploy_upgradeable_box.js 2 | 3 | const { deployProxy } = require('@openzeppelin/truffle-upgrades'); 4 | 5 | const Common = artifacts.require('StringCommon'); 6 | 7 | module.exports = async function (deployer, network) { 8 | const commonInstance = await deployProxy(Common, [], { deployer }); 9 | console.log('Deployed common ', commonInstance.address); 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /migrations/7_deploy_custom_token.js: -------------------------------------------------------------------------------- 1 | // migrations/NN_deploy_upgradeable_box.js 2 | 3 | const { deployProxy } = require('@openzeppelin/truffle-upgrades'); 4 | 5 | const Custom = artifacts.require('CustomToken'); 6 | 7 | module.exports = async function (deployer, network) { 8 | if (network != 'mainnet') 9 | { 10 | // deployer.deploy(Custom) 11 | const customInstance = await deployProxy(Custom, [], { deployer }); 12 | console.log(' Deployed custom token ', customInstance.address); 13 | } 14 | }; 15 | 16 | -------------------------------------------------------------------------------- /migrations/3_deploy_entity.js: -------------------------------------------------------------------------------- 1 | // migrations/NN_deploy_upgradeable_box.js 2 | 3 | const { deployProxy } = require('@openzeppelin/truffle-upgrades'); 4 | 5 | const Common = artifacts.require('StringCommon'); 6 | const Entity = artifacts.require('ImmutableEntity'); 7 | 8 | module.exports = async function (deployer, network) { 9 | const commonInstance = await Common.deployed(); 10 | 11 | // await deployer.deploy(Entity, commonInstance.address); 12 | const entityInstance = await deployProxy(Entity, [commonInstance.address], { deployer }); 13 | 14 | console.log(' Deployed entity ', entityInstance.address); 15 | }; 16 | 17 | -------------------------------------------------------------------------------- /client/src/utils/getWalletConnect.js: -------------------------------------------------------------------------------- 1 | // Middleware library for WalletConnect version of universal web3 2 | // interface. 3 | // Copyright 2020-2023 ImmutableSoft Inc. All rights reserved. 4 | 5 | import Web3 from "web3"; 6 | import WalletConnectProvider from "@walletconnect/web3-provider"; 7 | 8 | const getWalletConnect = async () => 9 | { 10 | const provider = new WalletConnectProvider({ 11 | rpc: { 137: "https://polygon-rpc.com/" }, 12 | }); 13 | 14 | // Enable session (triggers QR Code modal) 15 | await provider.enable(); 16 | 17 | const web3 = new Web3(provider); 18 | return web3; 19 | } 20 | 21 | export default getWalletConnect; 22 | -------------------------------------------------------------------------------- /migrations/4_deploy_product.js: -------------------------------------------------------------------------------- 1 | // migrations/NN_deploy_upgradeable_box.js 2 | 3 | const { deployProxy } = require('@openzeppelin/truffle-upgrades'); 4 | 5 | const Common = artifacts.require('StringCommon'); 6 | const Entity = artifacts.require('ImmutableEntity'); 7 | const Product = artifacts.require('ImmutableProduct'); 8 | 9 | module.exports = async function (deployer, network) { 10 | const commonInstance = await Common.deployed(); 11 | 12 | const entityInstance = await Entity.deployed(); 13 | 14 | // await deployer.deploy(Product, entityInstance.address, commonInstance.address); 15 | const productInstance = await deployProxy(Product, [entityInstance.address, commonInstance.address], { deployer }); 16 | 17 | console.log(' Deployed product ', productInstance.address); 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.7.6; 2 | 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | contract Migrations { 6 | address public owner; 7 | 8 | // A function with the signature `last_completed_migration()`, returning a uint, is required. 9 | uint public last_completed_migration; 10 | 11 | modifier restricted() { 12 | if (msg.sender == owner) _; 13 | } 14 | 15 | constructor/*Migrations*/() { 16 | owner = msg.sender; 17 | } 18 | 19 | // A function with the signature `setCompleted(uint)` is required. 20 | function setCompleted(uint completed) external { 21 | last_completed_migration = completed; 22 | } 23 | 24 | function upgrade(address new_address) external { 25 | Migrations upgraded = Migrations(new_address); 26 | upgraded.setCompleted(last_completed_migration); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /migrations/9_upgrade_ProductActivate_contract.js: -------------------------------------------------------------------------------- 1 | // migrations/MM_upgrade_product_contract.js 2 | const { upgradeProxy } = require('@openzeppelin/truffle-upgrades'); 3 | //const OZ_SDK_EXPORT = require("../openzeppelin-cli-export.json"); 4 | 5 | const Common = artifacts.require('StringCommon'); 6 | const Entity = artifacts.require('ImmutableEntity'); 7 | const Product = artifacts.require('ImmutableProduct'); 8 | const Activate = artifacts.require('ActivateToken'); 9 | const ProductActivate = artifacts.require('ProductActivate'); 10 | const CreatorToken = artifacts.require('CreatorToken'); 11 | 12 | module.exports = async function (deployer) { 13 | 14 | const existingProductActivate = await ProductActivate.deployed(); 15 | const instanceProductActivate = await upgradeProxy(existingProductActivate.address, ProductActivate, { deployer }); 16 | console.log("Upgraded product activate ", instanceProductActivate.address); 17 | }; 18 | -------------------------------------------------------------------------------- /migrations/5_deploy_creator.js: -------------------------------------------------------------------------------- 1 | // migrations/NN_deploy_upgradeable_box.js 2 | 3 | const { deployProxy } = require('@openzeppelin/truffle-upgrades'); 4 | 5 | const Common = artifacts.require('StringCommon'); 6 | const Entity = artifacts.require('ImmutableEntity'); 7 | const Product = artifacts.require('ImmutableProduct'); 8 | const Creator = artifacts.require('CreatorToken'); 9 | 10 | module.exports = async function (deployer, network) { 11 | const commonInstance = await Common.deployed(); 12 | 13 | const entityInstance = await Entity.deployed(); 14 | 15 | const productInstance = await Product.deployed(); 16 | 17 | // await deployer.deploy(Creator, commonInstance.address, entityInstance.address, 18 | // productInstance.address); 19 | const creatorInstance = await deployProxy(Creator, [commonInstance.address, entityInstance.address, 20 | productInstance.address], { deployer }); 21 | console.log(' Deployed creator token ', creatorInstance.address); 22 | 23 | }; 24 | 25 | -------------------------------------------------------------------------------- /contracts/CustomToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.7.6; 2 | 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | // OpenZeppelin upgradable contracts 6 | import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; 7 | import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; 8 | import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; 9 | 10 | /* 11 | // OpenZepellin standard contracts 12 | //import "@openzeppelin/contracts/proxy/utils/Initializable.sol"; 13 | import "@openzeppelin/contracts/access/Ownable.sol"; 14 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 15 | */ 16 | 17 | contract CustomToken is Initializable, OwnableUpgradeable, ERC20Upgradeable 18 | //contract CustomToken is Ownable, ERC20 19 | { 20 | 21 | function initialize() public initializer 22 | { 23 | __Ownable_init();//.initialize(msg.sender); 24 | __ERC20_init("CustomToken", "CuT"); 25 | /* 26 | constructor() Ownable() 27 | ERC20("CustomToken", "CuT") 28 | { 29 | */ 30 | _mint(msg.sender, 1000000000000000000); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /migrations/10_deploy_collection_proxy.js: -------------------------------------------------------------------------------- 1 | const { deployProxy } = require('@openzeppelin/truffle-upgrades'); 2 | 3 | var CollectionProxy = artifacts.require("CollectionProxy"); 4 | const CreatorToken = artifacts.require('CreatorToken'); 5 | const Common = artifacts.require('StringCommon'); 6 | const Entity = artifacts.require('ImmutableEntity'); 7 | const Product = artifacts.require('ImmutableProduct'); 8 | 9 | module.exports = async function (deployer) { 10 | const commonInstance = await Common.deployed(); 11 | const existingCreator = await CreatorToken.deployed(); 12 | const entityInstance = await Entity.deployed(); 13 | const productInstance = await Product.deployed(); 14 | 15 | const proxyInstance = await deployProxy(CollectionProxy, 16 | [commonInstance.address, existingCreator.address, 17 | entityInstance.address, productInstance.address, 18 | /* REQUIRED: Change the parameters below. */ 19 | /* CollectionName, SymbolName, EntityID, ProductID. */ 20 | "CollectionProxy", "PXY", 1, 0], { deployer }); 21 | 22 | console.log(' Deployed collection proxy contract ', proxyInstance.address); 23 | }; 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ImmutableEcosystem", 3 | "version": "2.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "lint": "npm run lint:js && npm run lint:sol", 8 | "lint:fix": "npm run lint:js:fix", 9 | "lint:js": "eslint .", 10 | "lint:js:fix": "eslint . --fix", 11 | "lint:sol": "solhint --max-warnings 0 \"contracts/**/*.sol\"", 12 | "test": "truffle test" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/ImmutableSoft/ImmutableEcosystem.git" 17 | }, 18 | "keywords": [], 19 | "author": "Sean Lawless", 20 | "license": "GPL3", 21 | "bugs": { 22 | "url": "https://github.com/ImmutableSoft/ImmutableEcosystem/issues" 23 | }, 24 | "homepage": "https://github.com/ImmutableSoft", 25 | "devDependencies": { 26 | "@openzeppelin/contracts": "4.6.0", 27 | "@openzeppelin/contracts-upgradeable": "4.6.0", 28 | "@openzeppelin/test-helpers": "^0.5.16", 29 | "@openzeppelin/truffle-upgrades": "^1.17.1", 30 | "truffle-plugin-verify": "^0.5.33" 31 | }, 32 | "dependencies": { 33 | "@truffle/hdwallet-provider": "^1.7.0", 34 | "big-integer": "^1.6.51", 35 | "mem": "^8.1.1", 36 | "truffle-assertions": "^0.9.2", 37 | "truffle-contract-size": "^2.0.1" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /migrations/10_deploy_ecosystem_contracts_js.bak: -------------------------------------------------------------------------------- 1 | // migrations/NN_deploy_upgradeable_box.js 2 | 3 | const { deployProxy } = require('@openzeppelin/truffle-upgrades'); 4 | 5 | const Common = artifacts.require('StringCommon'); 6 | const Entity = artifacts.require('ImmutableEntity'); 7 | const Product = artifacts.require('ImmutableProduct'); 8 | const Activate = artifacts.require('ActivateToken'); 9 | const Custom = artifacts.require('CustomToken'); 10 | 11 | module.exports = async function (deployer, network) { 12 | const commonInstance = await deployProxy(Common, [], { deployer }); 13 | console.log('Deployed common ', commonInstance.address); 14 | 15 | const entityInstance = await deployProxy(Entity, [commonInstance.address], { deployer }); 16 | console.log('Deployed entity ', entityInstance.address); 17 | 18 | const productInstance = await deployProxy(Product, [entityInstance.address, commonInstance.address], { deployer }); 19 | console.log('Deployed product ', productInstance.address); 20 | 21 | const activateInstance = await deployProxy(Activate, [entityInstance.address, productInstance.address], { deployer }); 22 | console.log('Deployed activate token ', activateInstance.address); 23 | 24 | if (network != 'mainnet') 25 | { 26 | const customInstance = await deployProxy(Custom, [], { deployer }); 27 | console.log('Deployed custom token ', customInstance.address); 28 | } 29 | }; 30 | 31 | -------------------------------------------------------------------------------- /migrations/11_upgrade_Product_contracts.js: -------------------------------------------------------------------------------- 1 | // migrations/MM_upgrade_product_contract.js 2 | const { upgradeProxy } = require('@openzeppelin/truffle-upgrades'); 3 | //const OZ_SDK_EXPORT = require("../openzeppelin-cli-export.json"); 4 | // Immutable Ecosystem 2.2 (Immutable DAO) 5 | const Common = artifacts.require('StringCommon'); 6 | const Entity = artifacts.require('ImmutableEntity'); 7 | const Product = artifacts.require('ImmutableProduct'); 8 | const Activate = artifacts.require('ActivateToken'); 9 | const ProductActivate = artifacts.require('ProductActivate'); 10 | const CreatorToken = artifacts.require('CreatorToken'); 11 | 12 | module.exports = async function (deployer) { 13 | 14 | // const existingEntity = await Entity.deployed(); 15 | // const instanceEntity = await upgradeProxy(existingEntity.address, Entity, { deployer }); 16 | // console.log("Upgraded entity ", instanceEntity.address); 17 | 18 | const existingProduct = await Product.deployed(); 19 | const instanceProduct = await upgradeProxy(existingProduct.address, Product, { deployer }); 20 | console.log("Upgraded product ", instanceProduct.address); 21 | 22 | // const existingProductActivate = await ProductActivate.deployed(); 23 | // const instanceProductActivate = await upgradeProxy(existingProductActivate.address, ProductActivate, { deployer }); 24 | // console.log("Upgraded product activate ", instanceProductActivate.address); 25 | }; 26 | -------------------------------------------------------------------------------- /migrations/8_upgrade_creator_contract.js: -------------------------------------------------------------------------------- 1 | // migrations/MM_upgrade_product_contract.js 2 | const { upgradeProxy } = require('@openzeppelin/truffle-upgrades'); 3 | //const OZ_SDK_EXPORT = require("../openzeppelin-cli-export.json"); 4 | 5 | const Common = artifacts.require('StringCommon'); 6 | const Entity = artifacts.require('ImmutableEntity'); 7 | const Product = artifacts.require('ImmutableProduct'); 8 | const Activate = artifacts.require('ActivateToken'); 9 | const ProductActivate = artifacts.require('ProductActivate'); 10 | const CreatorToken = artifacts.require('CreatorToken'); 11 | 12 | module.exports = async function (deployer) { 13 | 14 | // const existingCommon = await Common.deployed(); 15 | // const instanceCommon = await upgradeProxy(existingCommon.address, Common, { deployer }); 16 | // console.log("Upgraded common ", instanceCommon.address); 17 | 18 | // const existingEntity = await Entity.deployed(); 19 | // const instanceEntity = await upgradeProxy(existingEntity.address, Entity, { deployer }); 20 | // console.log("Upgraded entity ", instanceEntity.address); 21 | 22 | // const existingProduct = await Product.deployed(); 23 | // const instanceProduct = await upgradeProxy(existingProduct.address, Product, { deployer }); 24 | // console.log("Upgraded product ", instanceProduct.address); 25 | 26 | // const existingActivate = await Activate.deployed(); 27 | // const instanceActivate = await upgradeProxy(existingActivate.address, Activate, { deployer }); 28 | // console.log("Upgraded activate token ", instanceActivate.address); 29 | 30 | const existingCreator = await CreatorToken.deployed(); 31 | const instanceCreator = await upgradeProxy(existingCreator.address, CreatorToken, { deployer }); 32 | console.log("Upgraded creator token ", instanceCreator.address); 33 | }; 34 | -------------------------------------------------------------------------------- /docs/CustomToken.md: -------------------------------------------------------------------------------- 1 | # CustomToken.sol 2 | 3 | View Source: [\contracts\CustomToken.sol](..\contracts\CustomToken.sol) 4 | 5 | **↗ Extends: [Initializable](Initializable.md), [OwnableUpgradeable](OwnableUpgradeable.md), [ERC20Upgradeable](ERC20Upgradeable.md)** 6 | 7 | **CustomToken** 8 | 9 | ## Functions 10 | 11 | - [initialize()](#initialize) 12 | 13 | ### initialize 14 | 15 | ```js 16 | function initialize() public nonpayable initializer 17 | ``` 18 | 19 | **Arguments** 20 | 21 | | Name | Type | Description | 22 | | ------------- |------------- | -----| 23 | 24 | ## Contracts 25 | 26 | * [ActivateToken](ActivateToken.md) 27 | * [AddressUpgradeable](AddressUpgradeable.md) 28 | * [ContextUpgradeable](ContextUpgradeable.md) 29 | * [CreatorToken](CreatorToken.md) 30 | * [CustomToken](CustomToken.md) 31 | * [ERC165Upgradeable](ERC165Upgradeable.md) 32 | * [ERC20Upgradeable](ERC20Upgradeable.md) 33 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 34 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 35 | * [ERC721Upgradeable](ERC721Upgradeable.md) 36 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 37 | * [IERC165Upgradeable](IERC165Upgradeable.md) 38 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 39 | * [IERC20Upgradeable](IERC20Upgradeable.md) 40 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 41 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 42 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 43 | * [IERC721Upgradeable](IERC721Upgradeable.md) 44 | * [ImmutableEntity](ImmutableEntity.md) 45 | * [ImmutableProduct](ImmutableProduct.md) 46 | * [Initializable](Initializable.md) 47 | * [Migrations](Migrations.md) 48 | * [OwnableUpgradeable](OwnableUpgradeable.md) 49 | * [ProductActivate](ProductActivate.md) 50 | * [StringCommon](StringCommon.md) 51 | * [StringsUpgradeable](StringsUpgradeable.md) 52 | -------------------------------------------------------------------------------- /test/TestImmutableEcosystemEvents.js: -------------------------------------------------------------------------------- 1 | const ImmutableEntity = artifacts.require("ImmutableEntity.sol"); 2 | const ImmutableProduct = artifacts.require("ImmutableProduct.sol"); 3 | const truffleAssert = require('truffle-assertions'); 4 | 5 | contract("ImmutableEcosystemEvents", accounts => { 6 | /* 7 | let immutableEntityInstance; 8 | let productActivateInstance; 9 | 10 | beforeEach('setup contract for each test case', async () => { 11 | immutableEntityInstance = await ImmutableEntity.deployed(); 12 | immutableProductInstance = await ImmutableProduct.deployed(); 13 | }) 14 | 15 | it("Check the new organization event", async () => { 16 | const immutableEntityInstance = await ImmutableEntity.deployed(); 17 | 18 | // Create a new test organization 19 | let newEntity = await immutableEntityInstance.entityCreate("Test Org Event", 20 | "http://exampleEvent.com", { from: accounts[1] }); 21 | 22 | truffleAssert.eventEmitted(newEntity, 'entityEvent', (ev) => { 23 | return ev.entityIndex == 1 && ev.name === "Test Org Event"; 24 | }); 25 | 26 | }); 27 | 28 | it("Check the new product event", async () => { 29 | const immutableEntityInstance = await ImmutableEntity.deployed(); 30 | const immutableProductInstance = await ImmutableProduct.deployed(); 31 | 32 | // Read back the organization status 33 | const status = await immutableEntityInstance.entityIndexStatus(1); 34 | if (status == 0) 35 | { 36 | // Administrator (accounts[0]) must update status to a creator (1) 37 | await immutableEntityInstance.entityStatusUpdate( 38 | 1, 1, { from: accounts[0] }); 39 | } 40 | 41 | // Create a new test organization 42 | let newEntity = await immutableProductInstance.productCreate("Test Product Event", 43 | "http://exampleEvent.com", "http://exampleEvent.com/favicon.ico", 0, { from: accounts[1] }); 44 | 45 | truffleAssert.eventEmitted(newEntity, 'productEvent', (ev) => { 46 | return ev.entityIndex == 1 && ev.name === "Test Product Event"; 47 | }); 48 | }); 49 | */ 50 | }); 51 | -------------------------------------------------------------------------------- /migrations/6_deploy_activate.js: -------------------------------------------------------------------------------- 1 | // migrations/NN_deploy_upgradeable_box.js 2 | 3 | const { deployProxy } = require('@openzeppelin/truffle-upgrades'); 4 | 5 | const Common = artifacts.require('StringCommon'); 6 | const Entity = artifacts.require('ImmutableEntity'); 7 | const Product = artifacts.require('ImmutableProduct'); 8 | const Creator = artifacts.require('CreatorToken'); 9 | const Activate = artifacts.require('ActivateToken'); 10 | const ProductActivate = artifacts.require('ProductActivate'); 11 | 12 | module.exports = async function (deployer, network, accounts) { 13 | const commonInstance = await Common.deployed(); 14 | 15 | const entityInstance = await Entity.deployed(); 16 | 17 | const productInstance = await Product.deployed(); 18 | 19 | const creatorInstance = await Creator.deployed(); 20 | 21 | // const activateInstance = await deployer.deploy(Activate, commonInstance.address, entityInstance.address); 22 | const activateInstance = await deployProxy(Activate, 23 | [commonInstance.address, entityInstance.address], { deployer }); 24 | 25 | console.log(' Deployed activate token ', activateInstance.address); 26 | 27 | // await deployer.deploy(ProductActivate, commonInstance.address, 28 | // entityInstance.address, productInstance.address, 29 | // activateInstance.address, creatorInstance.address); 30 | const productActivateInstance = await deployProxy(ProductActivate, [commonInstance.address, 31 | entityInstance.address, productInstance.address, 32 | activateInstance.address, creatorInstance.address], { deployer }); 33 | 34 | console.log(' Deployed product activate', productActivateInstance.address); 35 | 36 | /* 37 | // const activateTokenInstance = await Activate.deployed(); 38 | await activateInstance.restrictToken(productActivateInstance.address, 39 | creatorInstance.address); 40 | 41 | console.log(' Restricted activate token '); 42 | */ 43 | 44 | // const creatorInstance = await deployProxy(Creator, [entityInstance.address, commonInstance.address], { deployer }); 45 | // console.log('Deployed creator token ', creatorInstance.address); 46 | }; 47 | 48 | -------------------------------------------------------------------------------- /openzeppelin-cli-export.json: -------------------------------------------------------------------------------- 1 | { 2 | "networks": { 3 | "ropsten": { 4 | "proxies": { 5 | "ImmutableEcosystem/StringCommon": [ 6 | { 7 | "address": "0x7c7136B44067e3004D947672e5B253309BA312a9", 8 | "version": "2.0.0", 9 | "implementation": "0xF6eB751531249E3BB6bc597369F77Fc2cAB4144A", 10 | "admin": "0xF44d87A1ae06CEd01e88c8Eb6F0BEA65bEFCc9C7", 11 | "kind": "Upgradeable" 12 | } 13 | ], 14 | "ImmutableEcosystem/ImmutableEntity": [ 15 | { 16 | "address": "0x6C25eD314e0714B13CF9ac42B6A54c14C634EDB7", 17 | "version": "2.0.0", 18 | "implementation": "0x0517E1B1402230633131bB3FB30f8Cd58a712351", 19 | "admin": "0xF44d87A1ae06CEd01e88c8Eb6F0BEA65bEFCc9C7", 20 | "kind": "Upgradeable" 21 | } 22 | ], 23 | "ImmutableEcosystem/ImmutableProduct": [ 24 | { 25 | "address": "0x4DA001F154683A67F5B817229c34Ce50aa6F3281", 26 | "version": "2.0.0", 27 | "implementation": "0xfd7a1e6085E52eaac9934442a078AFc19f52edDC", 28 | "admin": "0xF44d87A1ae06CEd01e88c8Eb6F0BEA65bEFCc9C7", 29 | "kind": "Upgradeable" 30 | } 31 | ], 32 | "ImmutableEcosystem/ActivateToken": [ 33 | { 34 | "address": "0x5A516379F798b1D5b1875fb3efDCdbCfe199De42", 35 | "version": "2.0.0", 36 | "implementation": "0x906C7985Af6799b0AF643b232D690F52532932e2", 37 | "admin": "0xF44d87A1ae06CEd01e88c8Eb6F0BEA65bEFCc9C7", 38 | "kind": "Upgradeable" 39 | } 40 | ] 41 | }, 42 | "dependencies": { 43 | "@openzeppelin/contracts-ethereum-package": { 44 | "package": "0x2a9e7B63514438906A83a1e320dBBD814D417002", 45 | "version": "2.5.0" 46 | } 47 | } 48 | } 49 | }, 50 | "compiler": { 51 | "compilerSettings": { 52 | "optimizer": { 53 | "enabled": false, 54 | "runs": "200" 55 | } 56 | }, 57 | "typechain": { 58 | "enabled": false 59 | }, 60 | "manager": "truffle", 61 | "artifactsDir": "build\\contracts", 62 | "contractsDir": "contracts" 63 | } 64 | } -------------------------------------------------------------------------------- /docs/IERC165Upgradeable.md: -------------------------------------------------------------------------------- 1 | # IERC165Upgradeable.sol 2 | 3 | View Source: [@openzeppelin\contracts-upgradeable\utils\introspection\IERC165Upgradeable.sol](..\@openzeppelin\contracts-upgradeable\utils\introspection\IERC165Upgradeable.sol) 4 | 5 | **↘ Derived Contracts: [ERC165Upgradeable](ERC165Upgradeable.md), [IERC721Upgradeable](IERC721Upgradeable.md)** 6 | 7 | **IERC165Upgradeable** 8 | 9 | Interface of the ERC165 standard, as defined in the 10 | https://eips.ethereum.org/EIPS/eip-165[EIP]. 11 | Implementers can declare support of contract interfaces, which can then be 12 | queried by others ({ERC165Checker}). 13 | For an implementation, see {ERC165}. 14 | 15 | ## Functions 16 | 17 | - [supportsInterface(bytes4 interfaceId)](#supportsinterface) 18 | 19 | ### supportsInterface 20 | 21 | Returns true if this contract implements the interface defined by 22 | `interfaceId`. See the corresponding 23 | https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] 24 | to learn more about how these ids are created. 25 | This function call must use less than 30 000 gas. 26 | 27 | ```js 28 | function supportsInterface(bytes4 interfaceId) external view 29 | returns(bool) 30 | ``` 31 | 32 | **Arguments** 33 | 34 | | Name | Type | Description | 35 | | ------------- |------------- | -----| 36 | | interfaceId | bytes4 | | 37 | 38 | ## Contracts 39 | 40 | * [ActivateToken](ActivateToken.md) 41 | * [AddressUpgradeable](AddressUpgradeable.md) 42 | * [ContextUpgradeable](ContextUpgradeable.md) 43 | * [CreatorToken](CreatorToken.md) 44 | * [CustomToken](CustomToken.md) 45 | * [ERC165Upgradeable](ERC165Upgradeable.md) 46 | * [ERC20Upgradeable](ERC20Upgradeable.md) 47 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 48 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 49 | * [ERC721Upgradeable](ERC721Upgradeable.md) 50 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 51 | * [IERC165Upgradeable](IERC165Upgradeable.md) 52 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 53 | * [IERC20Upgradeable](IERC20Upgradeable.md) 54 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 55 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 56 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 57 | * [IERC721Upgradeable](IERC721Upgradeable.md) 58 | * [ImmutableEntity](ImmutableEntity.md) 59 | * [ImmutableProduct](ImmutableProduct.md) 60 | * [Initializable](Initializable.md) 61 | * [Migrations](Migrations.md) 62 | * [OwnableUpgradeable](OwnableUpgradeable.md) 63 | * [ProductActivate](ProductActivate.md) 64 | * [StringCommon](StringCommon.md) 65 | * [StringsUpgradeable](StringsUpgradeable.md) 66 | -------------------------------------------------------------------------------- /client/src/middleware/Utilities.js: -------------------------------------------------------------------------------- 1 | // Utilities library for ImmutableSoft UI 2 | // Copyright 2020-2023 ImmutableSoft Inc. All rights reserved. 3 | var bigInt = require("big-integer"); 4 | 5 | export function findProductIndex(entity, product, products) 6 | { 7 | var i; 8 | 9 | // alert(entity + " : " + product); 10 | for (i = 0; i < products.length; ++i) 11 | { 12 | // alert("Check entity and product ids for product " i); 13 | // If this entity and product match, return the index 14 | if ((products[i].entity == entity) && 15 | (products[i].product == product)) 16 | return i; 17 | } 18 | return -1; 19 | } 20 | 21 | export function findReleaseHash(uri, theReleases) 22 | { 23 | var i; 24 | 25 | for (i = 0; i < theReleases.length; ++i) 26 | { 27 | // If this entity and product match, return the index 28 | if (theReleases[i].split('::')[6] === uri) 29 | return theReleases[i].split('::')[7]; 30 | } 31 | return 0; 32 | } 33 | 34 | export function secondsToDays(seconds) 35 | { 36 | seconds = Number(seconds); 37 | var d = Math.floor(seconds / (3600 * 24)); 38 | 39 | var dDisplay = d > 0 ? d + (d === 1 ? " day" : " days") : " 0 days"; 40 | return dDisplay; 41 | } 42 | 43 | export function isValidFilename(filename) 44 | { 45 | var regex = /^[^\\/:\*\?"<>\|]+$/; 46 | 47 | if (regex.test(filename) == false) // check for forbidden characters 48 | return false; 49 | else 50 | return true; 51 | } 52 | 53 | export function versionStringToUint256(versionString) 54 | { 55 | var versionArray = versionString.split("."); 56 | var version = bigInt(0); 57 | 58 | for (var i = 0; i < 4; ++i) 59 | { 60 | if (i < versionArray.length) 61 | version = version.add(versionArray[i]); 62 | if (i < 3) 63 | version = version.shiftLeft(16); 64 | } 65 | return version; 66 | } 67 | 68 | // Returns hex string of creator tokenId 69 | export function findCreatorTokenId(entity, product, release) 70 | { 71 | var tokenId = bigInt(0); 72 | 73 | //224 entity offset 74 | //192 product offset 75 | //160 release offset 76 | 77 | tokenId = tokenId.add(entity); 78 | tokenId = tokenId.shiftLeft(32); 79 | tokenId = tokenId.add(product); 80 | tokenId = tokenId.shiftLeft(32); 81 | tokenId = tokenId.add(release); 82 | tokenId = tokenId.shiftLeft(160); 83 | 84 | return '0x' + tokenId.toString(16); 85 | } 86 | 87 | export function convertFormToDataURI(formData) 88 | { 89 | var result = {}; 90 | 91 | formData.forEach(function(value, key) 92 | { 93 | result[key] = value; 94 | }); 95 | 96 | return "data:application/json," + JSON.stringify(result); 97 | } 98 | -------------------------------------------------------------------------------- /docs/IERC721ReceiverUpgradeable.md: -------------------------------------------------------------------------------- 1 | # ERC721 token receiver interface (IERC721ReceiverUpgradeable.sol) 2 | 3 | View Source: [@openzeppelin\contracts-upgradeable\token\ERC721\IERC721ReceiverUpgradeable.sol](..\@openzeppelin\contracts-upgradeable\token\ERC721\IERC721ReceiverUpgradeable.sol) 4 | 5 | **IERC721ReceiverUpgradeable** 6 | 7 | Interface for any contract that wants to support safeTransfers 8 | from ERC721 asset contracts. 9 | 10 | ## Functions 11 | 12 | - [onERC721Received(address operator, address from, uint256 tokenId, bytes data)](#onerc721received) 13 | 14 | ### onERC721Received 15 | 16 | Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} 17 | by `operator` from `from`, this function is called. 18 | It must return its Solidity selector to confirm the token transfer. 19 | If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. 20 | The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. 21 | 22 | ```js 23 | function onERC721Received(address operator, address from, uint256 tokenId, bytes data) external nonpayable 24 | returns(bytes4) 25 | ``` 26 | 27 | **Arguments** 28 | 29 | | Name | Type | Description | 30 | | ------------- |------------- | -----| 31 | | operator | address | | 32 | | from | address | | 33 | | tokenId | uint256 | | 34 | | data | bytes | | 35 | 36 | ## Contracts 37 | 38 | * [ActivateToken](ActivateToken.md) 39 | * [AddressUpgradeable](AddressUpgradeable.md) 40 | * [ContextUpgradeable](ContextUpgradeable.md) 41 | * [CreatorToken](CreatorToken.md) 42 | * [CustomToken](CustomToken.md) 43 | * [ERC165Upgradeable](ERC165Upgradeable.md) 44 | * [ERC20Upgradeable](ERC20Upgradeable.md) 45 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 46 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 47 | * [ERC721Upgradeable](ERC721Upgradeable.md) 48 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 49 | * [IERC165Upgradeable](IERC165Upgradeable.md) 50 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 51 | * [IERC20Upgradeable](IERC20Upgradeable.md) 52 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 53 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 54 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 55 | * [IERC721Upgradeable](IERC721Upgradeable.md) 56 | * [ImmutableEntity](ImmutableEntity.md) 57 | * [ImmutableProduct](ImmutableProduct.md) 58 | * [Initializable](Initializable.md) 59 | * [Migrations](Migrations.md) 60 | * [OwnableUpgradeable](OwnableUpgradeable.md) 61 | * [ProductActivate](ProductActivate.md) 62 | * [StringCommon](StringCommon.md) 63 | * [StringsUpgradeable](StringsUpgradeable.md) 64 | -------------------------------------------------------------------------------- /docs/IERC20MetadataUpgradeable.md: -------------------------------------------------------------------------------- 1 | # IERC20MetadataUpgradeable.sol 2 | 3 | View Source: [@openzeppelin\contracts-upgradeable\token\ERC20\extensions\IERC20MetadataUpgradeable.sol](..\@openzeppelin\contracts-upgradeable\token\ERC20\extensions\IERC20MetadataUpgradeable.sol) 4 | 5 | **↗ Extends: [IERC20Upgradeable](IERC20Upgradeable.md)** 6 | **↘ Derived Contracts: [ERC20Upgradeable](ERC20Upgradeable.md)** 7 | 8 | **IERC20MetadataUpgradeable** 9 | 10 | Interface for the optional metadata functions from the ERC20 standard. 11 | _Available since v4.1._ 12 | 13 | ## Functions 14 | 15 | - [name()](#name) 16 | - [symbol()](#symbol) 17 | - [decimals()](#decimals) 18 | 19 | ### name 20 | 21 | Returns the name of the token. 22 | 23 | ```js 24 | function name() external view 25 | returns(string) 26 | ``` 27 | 28 | **Arguments** 29 | 30 | | Name | Type | Description | 31 | | ------------- |------------- | -----| 32 | 33 | ### symbol 34 | 35 | Returns the symbol of the token. 36 | 37 | ```js 38 | function symbol() external view 39 | returns(string) 40 | ``` 41 | 42 | **Arguments** 43 | 44 | | Name | Type | Description | 45 | | ------------- |------------- | -----| 46 | 47 | ### decimals 48 | 49 | Returns the decimals places of the token. 50 | 51 | ```js 52 | function decimals() external view 53 | returns(uint8) 54 | ``` 55 | 56 | **Arguments** 57 | 58 | | Name | Type | Description | 59 | | ------------- |------------- | -----| 60 | 61 | ## Contracts 62 | 63 | * [ActivateToken](ActivateToken.md) 64 | * [AddressUpgradeable](AddressUpgradeable.md) 65 | * [ContextUpgradeable](ContextUpgradeable.md) 66 | * [CreatorToken](CreatorToken.md) 67 | * [CustomToken](CustomToken.md) 68 | * [ERC165Upgradeable](ERC165Upgradeable.md) 69 | * [ERC20Upgradeable](ERC20Upgradeable.md) 70 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 71 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 72 | * [ERC721Upgradeable](ERC721Upgradeable.md) 73 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 74 | * [IERC165Upgradeable](IERC165Upgradeable.md) 75 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 76 | * [IERC20Upgradeable](IERC20Upgradeable.md) 77 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 78 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 79 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 80 | * [IERC721Upgradeable](IERC721Upgradeable.md) 81 | * [ImmutableEntity](ImmutableEntity.md) 82 | * [ImmutableProduct](ImmutableProduct.md) 83 | * [Initializable](Initializable.md) 84 | * [Migrations](Migrations.md) 85 | * [OwnableUpgradeable](OwnableUpgradeable.md) 86 | * [ProductActivate](ProductActivate.md) 87 | * [StringCommon](StringCommon.md) 88 | * [StringsUpgradeable](StringsUpgradeable.md) 89 | -------------------------------------------------------------------------------- /docs/Migrations.md: -------------------------------------------------------------------------------- 1 | # Migrations.sol 2 | 3 | View Source: [\contracts\Migrations.sol](..\contracts\Migrations.sol) 4 | 5 | **Migrations** 6 | 7 | ## Contract Members 8 | **Constants & Variables** 9 | 10 | ```js 11 | address public owner; 12 | uint256 public last_completed_migration; 13 | 14 | ``` 15 | 16 | ## Modifiers 17 | 18 | - [restricted](#restricted) 19 | 20 | ### restricted 21 | 22 | ```js 23 | modifier restricted() internal 24 | ``` 25 | 26 | **Arguments** 27 | 28 | | Name | Type | Description | 29 | | ------------- |------------- | -----| 30 | 31 | ## Functions 32 | 33 | - [constructor()](#) 34 | - [setCompleted(uint256 completed)](#setcompleted) 35 | - [upgrade(address new_address)](#upgrade) 36 | 37 | ### 38 | 39 | ```js 40 | function () public nonpayable 41 | ``` 42 | 43 | **Arguments** 44 | 45 | | Name | Type | Description | 46 | | ------------- |------------- | -----| 47 | 48 | ### setCompleted 49 | 50 | ```js 51 | function setCompleted(uint256 completed) external nonpayable 52 | ``` 53 | 54 | **Arguments** 55 | 56 | | Name | Type | Description | 57 | | ------------- |------------- | -----| 58 | | completed | uint256 | | 59 | 60 | ### upgrade 61 | 62 | ```js 63 | function upgrade(address new_address) external nonpayable 64 | ``` 65 | 66 | **Arguments** 67 | 68 | | Name | Type | Description | 69 | | ------------- |------------- | -----| 70 | | new_address | address | | 71 | 72 | ## Contracts 73 | 74 | * [ActivateToken](ActivateToken.md) 75 | * [AddressUpgradeable](AddressUpgradeable.md) 76 | * [ContextUpgradeable](ContextUpgradeable.md) 77 | * [CreatorToken](CreatorToken.md) 78 | * [CustomToken](CustomToken.md) 79 | * [ERC165Upgradeable](ERC165Upgradeable.md) 80 | * [ERC20Upgradeable](ERC20Upgradeable.md) 81 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 82 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 83 | * [ERC721Upgradeable](ERC721Upgradeable.md) 84 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 85 | * [IERC165Upgradeable](IERC165Upgradeable.md) 86 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 87 | * [IERC20Upgradeable](IERC20Upgradeable.md) 88 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 89 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 90 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 91 | * [IERC721Upgradeable](IERC721Upgradeable.md) 92 | * [ImmutableEntity](ImmutableEntity.md) 93 | * [ImmutableProduct](ImmutableProduct.md) 94 | * [Initializable](Initializable.md) 95 | * [Migrations](Migrations.md) 96 | * [OwnableUpgradeable](OwnableUpgradeable.md) 97 | * [ProductActivate](ProductActivate.md) 98 | * [StringCommon](StringCommon.md) 99 | * [StringsUpgradeable](StringsUpgradeable.md) 100 | -------------------------------------------------------------------------------- /docs/IERC721MetadataUpgradeable.md: -------------------------------------------------------------------------------- 1 | # ERC-721 Non-Fungible Token Standard, optional metadata extension (IERC721MetadataUpgradeable.sol) 2 | 3 | View Source: [@openzeppelin\contracts-upgradeable\token\ERC721\extensions\IERC721MetadataUpgradeable.sol](..\@openzeppelin\contracts-upgradeable\token\ERC721\extensions\IERC721MetadataUpgradeable.sol) 4 | 5 | **↗ Extends: [IERC721Upgradeable](IERC721Upgradeable.md)** 6 | **↘ Derived Contracts: [ERC721Upgradeable](ERC721Upgradeable.md)** 7 | 8 | **IERC721MetadataUpgradeable** 9 | 10 | See https://eips.ethereum.org/EIPS/eip-721 11 | 12 | ## Functions 13 | 14 | - [name()](#name) 15 | - [symbol()](#symbol) 16 | - [tokenURI(uint256 tokenId)](#tokenuri) 17 | 18 | ### name 19 | 20 | Returns the token collection name. 21 | 22 | ```js 23 | function name() external view 24 | returns(string) 25 | ``` 26 | 27 | **Arguments** 28 | 29 | | Name | Type | Description | 30 | | ------------- |------------- | -----| 31 | 32 | ### symbol 33 | 34 | Returns the token collection symbol. 35 | 36 | ```js 37 | function symbol() external view 38 | returns(string) 39 | ``` 40 | 41 | **Arguments** 42 | 43 | | Name | Type | Description | 44 | | ------------- |------------- | -----| 45 | 46 | ### tokenURI 47 | 48 | Returns the Uniform Resource Identifier (URI) for `tokenId` token. 49 | 50 | ```js 51 | function tokenURI(uint256 tokenId) external view 52 | returns(string) 53 | ``` 54 | 55 | **Arguments** 56 | 57 | | Name | Type | Description | 58 | | ------------- |------------- | -----| 59 | | tokenId | uint256 | | 60 | 61 | ## Contracts 62 | 63 | * [ActivateToken](ActivateToken.md) 64 | * [AddressUpgradeable](AddressUpgradeable.md) 65 | * [ContextUpgradeable](ContextUpgradeable.md) 66 | * [CreatorToken](CreatorToken.md) 67 | * [CustomToken](CustomToken.md) 68 | * [ERC165Upgradeable](ERC165Upgradeable.md) 69 | * [ERC20Upgradeable](ERC20Upgradeable.md) 70 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 71 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 72 | * [ERC721Upgradeable](ERC721Upgradeable.md) 73 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 74 | * [IERC165Upgradeable](IERC165Upgradeable.md) 75 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 76 | * [IERC20Upgradeable](IERC20Upgradeable.md) 77 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 78 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 79 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 80 | * [IERC721Upgradeable](IERC721Upgradeable.md) 81 | * [ImmutableEntity](ImmutableEntity.md) 82 | * [ImmutableProduct](ImmutableProduct.md) 83 | * [Initializable](Initializable.md) 84 | * [Migrations](Migrations.md) 85 | * [OwnableUpgradeable](OwnableUpgradeable.md) 86 | * [ProductActivate](ProductActivate.md) 87 | * [StringCommon](StringCommon.md) 88 | * [StringsUpgradeable](StringsUpgradeable.md) 89 | -------------------------------------------------------------------------------- /docs/StringsUpgradeable.md: -------------------------------------------------------------------------------- 1 | # StringsUpgradeable.sol 2 | 3 | View Source: [@openzeppelin\contracts-upgradeable\utils\StringsUpgradeable.sol](..\@openzeppelin\contracts-upgradeable\utils\StringsUpgradeable.sol) 4 | 5 | **StringsUpgradeable** 6 | 7 | String operations. 8 | 9 | ## Contract Members 10 | **Constants & Variables** 11 | 12 | ```js 13 | bytes16 private constant _HEX_SYMBOLS; 14 | 15 | ``` 16 | 17 | ## Functions 18 | 19 | - [toString(uint256 value)](#tostring) 20 | - [toHexString(uint256 value)](#tohexstring) 21 | - [toHexString(uint256 value, uint256 length)](#tohexstring) 22 | 23 | ### toString 24 | 25 | Converts a `uint256` to its ASCII `string` decimal representation. 26 | 27 | ```js 28 | function toString(uint256 value) internal pure 29 | returns(string) 30 | ``` 31 | 32 | **Arguments** 33 | 34 | | Name | Type | Description | 35 | | ------------- |------------- | -----| 36 | | value | uint256 | | 37 | 38 | ### toHexString 39 | 40 | Converts a `uint256` to its ASCII `string` hexadecimal representation. 41 | 42 | ```js 43 | function toHexString(uint256 value) internal pure 44 | returns(string) 45 | ``` 46 | 47 | **Arguments** 48 | 49 | | Name | Type | Description | 50 | | ------------- |------------- | -----| 51 | | value | uint256 | | 52 | 53 | ### toHexString 54 | 55 | Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. 56 | 57 | ```js 58 | function toHexString(uint256 value, uint256 length) internal pure 59 | returns(string) 60 | ``` 61 | 62 | **Arguments** 63 | 64 | | Name | Type | Description | 65 | | ------------- |------------- | -----| 66 | | value | uint256 | | 67 | | length | uint256 | | 68 | 69 | ## Contracts 70 | 71 | * [ActivateToken](ActivateToken.md) 72 | * [AddressUpgradeable](AddressUpgradeable.md) 73 | * [ContextUpgradeable](ContextUpgradeable.md) 74 | * [CreatorToken](CreatorToken.md) 75 | * [CustomToken](CustomToken.md) 76 | * [ERC165Upgradeable](ERC165Upgradeable.md) 77 | * [ERC20Upgradeable](ERC20Upgradeable.md) 78 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 79 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 80 | * [ERC721Upgradeable](ERC721Upgradeable.md) 81 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 82 | * [IERC165Upgradeable](IERC165Upgradeable.md) 83 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 84 | * [IERC20Upgradeable](IERC20Upgradeable.md) 85 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 86 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 87 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 88 | * [IERC721Upgradeable](IERC721Upgradeable.md) 89 | * [ImmutableEntity](ImmutableEntity.md) 90 | * [ImmutableProduct](ImmutableProduct.md) 91 | * [Initializable](Initializable.md) 92 | * [Migrations](Migrations.md) 93 | * [OwnableUpgradeable](OwnableUpgradeable.md) 94 | * [ProductActivate](ProductActivate.md) 95 | * [StringCommon](StringCommon.md) 96 | * [StringsUpgradeable](StringsUpgradeable.md) 97 | -------------------------------------------------------------------------------- /client/src/middleware/BackendServer.js: -------------------------------------------------------------------------------- 1 | // Development and Product 2 | export const MemberFileBaseURL = ((window.location.hostname === "localhost") || 3 | (window.location.hostname.split('.').length == 4)) ? 4 | "http://localhost:3001/" : 5 | "https://members.immutablesoft.org/"; 6 | const MemberFileUploadURL = ((window.location.hostname === "localhost") || 7 | (window.location.hostname.split('.').length == 4)) ? 8 | "http://localhost:3001/upload" : 9 | "https://members.immutablesoft.org/upload"; 10 | const MemberFileRemoveURL = ((window.location.hostname === "localhost") || 11 | (window.location.hostname.split('.').length == 4)) ? 12 | "http://localhost:3001/remove" : 13 | "https://members.immutablesoft.org/remove"; 14 | 15 | /* 16 | curl -i -X OPTIONS -H "Origin: http://127.0.0.1:3000" -H 'Access-Control-Request-Method: POST' -H 'Access-Control-Request-Headers: Content-Type, Authorization' "http://127.0.0.1:3001" 17 | */ 18 | export function UploadFile(fileUpload, entityIndex, productIndex, networkId) 19 | { 20 | 21 | var data = new FormData(); 22 | data.append('file', fileUpload); 23 | data.append('network', networkId); 24 | data.append('user', entityIndex + '-' + productIndex); 25 | 26 | // Uploading the file using the fetch API to the server 27 | return fetch(MemberFileUploadURL, { 28 | method: 'POST', 29 | body: data 30 | }).then((res) => res.json()).then((data) => 31 | { 32 | if (data.success === true) 33 | { 34 | // Return the uploaded file's new URI 35 | return data.fileUrl; 36 | } 37 | else 38 | { 39 | // Return the error 40 | return "Error: " + data.message; 41 | } 42 | }) 43 | .catch((err) => { return "Error: " + err }); 44 | } 45 | 46 | export function RemoveFile(fileToRemove, entityIndex, productIndex, networkId) 47 | { 48 | // entityIndex and productIndex 49 | var data = new FormData(); 50 | data.append('filename', fileToRemove); 51 | data.append('network', networkId); 52 | data.append('user', entityIndex + '-' + productIndex); 53 | 54 | // Removing the file using the fetch API to the server 55 | return fetch(MemberFileRemoveURL, { 56 | method: 'POST', 57 | body: data 58 | }).then((res) => res.json()).then((data) => 59 | { 60 | if (data.success === true) 61 | { 62 | // Return the removed file's old URI 63 | return data.fileUrl; 64 | } 65 | else 66 | { 67 | // Return the error 68 | return "Error: " + data.message; 69 | } 70 | }) 71 | .catch((err) => { return "Error: " + err }); 72 | } 73 | 74 | -------------------------------------------------------------------------------- /docs/ERC721BurnableUpgradeable.md: -------------------------------------------------------------------------------- 1 | # ERC721 Burnable Token (ERC721BurnableUpgradeable.sol) 2 | 3 | View Source: [@openzeppelin\contracts-upgradeable\token\ERC721\extensions\ERC721BurnableUpgradeable.sol](..\@openzeppelin\contracts-upgradeable\token\ERC721\extensions\ERC721BurnableUpgradeable.sol) 4 | 5 | **↗ Extends: [Initializable](Initializable.md), [ContextUpgradeable](ContextUpgradeable.md), [ERC721Upgradeable](ERC721Upgradeable.md)** 6 | **↘ Derived Contracts: [ActivateToken](ActivateToken.md), [CreatorToken](CreatorToken.md)** 7 | 8 | **ERC721BurnableUpgradeable** 9 | 10 | ERC721 Token that can be irreversibly burned (destroyed). 11 | 12 | ## Contract Members 13 | **Constants & Variables** 14 | 15 | ```js 16 | uint256[50] private __gap; 17 | 18 | ``` 19 | 20 | ## Functions 21 | 22 | - [__ERC721Burnable_init()](#__erc721burnable_init) 23 | - [__ERC721Burnable_init_unchained()](#__erc721burnable_init_unchained) 24 | - [burn(uint256 tokenId)](#burn) 25 | 26 | ### __ERC721Burnable_init 27 | 28 | ```js 29 | function __ERC721Burnable_init() internal nonpayable onlyInitializing 30 | ``` 31 | 32 | **Arguments** 33 | 34 | | Name | Type | Description | 35 | | ------------- |------------- | -----| 36 | 37 | ### __ERC721Burnable_init_unchained 38 | 39 | ```js 40 | function __ERC721Burnable_init_unchained() internal nonpayable onlyInitializing 41 | ``` 42 | 43 | **Arguments** 44 | 45 | | Name | Type | Description | 46 | | ------------- |------------- | -----| 47 | 48 | ### burn 49 | 50 | Burns `tokenId`. See {ERC721-_burn}. 51 | Requirements: 52 | - The caller must own `tokenId` or be an approved operator. 53 | 54 | ```js 55 | function burn(uint256 tokenId) public nonpayable 56 | ``` 57 | 58 | **Arguments** 59 | 60 | | Name | Type | Description | 61 | | ------------- |------------- | -----| 62 | | tokenId | uint256 | | 63 | 64 | ## Contracts 65 | 66 | * [ActivateToken](ActivateToken.md) 67 | * [AddressUpgradeable](AddressUpgradeable.md) 68 | * [ContextUpgradeable](ContextUpgradeable.md) 69 | * [CreatorToken](CreatorToken.md) 70 | * [CustomToken](CustomToken.md) 71 | * [ERC165Upgradeable](ERC165Upgradeable.md) 72 | * [ERC20Upgradeable](ERC20Upgradeable.md) 73 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 74 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 75 | * [ERC721Upgradeable](ERC721Upgradeable.md) 76 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 77 | * [IERC165Upgradeable](IERC165Upgradeable.md) 78 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 79 | * [IERC20Upgradeable](IERC20Upgradeable.md) 80 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 81 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 82 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 83 | * [IERC721Upgradeable](IERC721Upgradeable.md) 84 | * [ImmutableEntity](ImmutableEntity.md) 85 | * [ImmutableProduct](ImmutableProduct.md) 86 | * [Initializable](Initializable.md) 87 | * [Migrations](Migrations.md) 88 | * [OwnableUpgradeable](OwnableUpgradeable.md) 89 | * [ProductActivate](ProductActivate.md) 90 | * [StringCommon](StringCommon.md) 91 | * [StringsUpgradeable](StringsUpgradeable.md) 92 | -------------------------------------------------------------------------------- /docs/IERC721EnumerableUpgradeable.md: -------------------------------------------------------------------------------- 1 | # ERC-721 Non-Fungible Token Standard, optional enumeration extension (IERC721EnumerableUpgradeable.sol) 2 | 3 | View Source: [@openzeppelin\contracts-upgradeable\token\ERC721\extensions\IERC721EnumerableUpgradeable.sol](..\@openzeppelin\contracts-upgradeable\token\ERC721\extensions\IERC721EnumerableUpgradeable.sol) 4 | 5 | **↗ Extends: [IERC721Upgradeable](IERC721Upgradeable.md)** 6 | **↘ Derived Contracts: [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md)** 7 | 8 | **IERC721EnumerableUpgradeable** 9 | 10 | See https://eips.ethereum.org/EIPS/eip-721 11 | 12 | ## Functions 13 | 14 | - [totalSupply()](#totalsupply) 15 | - [tokenOfOwnerByIndex(address owner, uint256 index)](#tokenofownerbyindex) 16 | - [tokenByIndex(uint256 index)](#tokenbyindex) 17 | 18 | ### totalSupply 19 | 20 | Returns the total amount of tokens stored by the contract. 21 | 22 | ```js 23 | function totalSupply() external view 24 | returns(uint256) 25 | ``` 26 | 27 | **Arguments** 28 | 29 | | Name | Type | Description | 30 | | ------------- |------------- | -----| 31 | 32 | ### tokenOfOwnerByIndex 33 | 34 | Returns a token ID owned by `owner` at a given `index` of its token list. 35 | Use along with {balanceOf} to enumerate all of ``owner``'s tokens. 36 | 37 | ```js 38 | function tokenOfOwnerByIndex(address owner, uint256 index) external view 39 | returns(uint256) 40 | ``` 41 | 42 | **Arguments** 43 | 44 | | Name | Type | Description | 45 | | ------------- |------------- | -----| 46 | | owner | address | | 47 | | index | uint256 | | 48 | 49 | ### tokenByIndex 50 | 51 | Returns a token ID at a given `index` of all the tokens stored by the contract. 52 | Use along with {totalSupply} to enumerate all tokens. 53 | 54 | ```js 55 | function tokenByIndex(uint256 index) external view 56 | returns(uint256) 57 | ``` 58 | 59 | **Arguments** 60 | 61 | | Name | Type | Description | 62 | | ------------- |------------- | -----| 63 | | index | uint256 | | 64 | 65 | ## Contracts 66 | 67 | * [ActivateToken](ActivateToken.md) 68 | * [AddressUpgradeable](AddressUpgradeable.md) 69 | * [ContextUpgradeable](ContextUpgradeable.md) 70 | * [CreatorToken](CreatorToken.md) 71 | * [CustomToken](CustomToken.md) 72 | * [ERC165Upgradeable](ERC165Upgradeable.md) 73 | * [ERC20Upgradeable](ERC20Upgradeable.md) 74 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 75 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 76 | * [ERC721Upgradeable](ERC721Upgradeable.md) 77 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 78 | * [IERC165Upgradeable](IERC165Upgradeable.md) 79 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 80 | * [IERC20Upgradeable](IERC20Upgradeable.md) 81 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 82 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 83 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 84 | * [IERC721Upgradeable](IERC721Upgradeable.md) 85 | * [ImmutableEntity](ImmutableEntity.md) 86 | * [ImmutableProduct](ImmutableProduct.md) 87 | * [Initializable](Initializable.md) 88 | * [Migrations](Migrations.md) 89 | * [OwnableUpgradeable](OwnableUpgradeable.md) 90 | * [ProductActivate](ProductActivate.md) 91 | * [StringCommon](StringCommon.md) 92 | * [StringsUpgradeable](StringsUpgradeable.md) 93 | -------------------------------------------------------------------------------- /core-terms-USA.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Security is core to our values, and we value the input of hackers acting in good faith to help us maintain a high standard for the security and privacy for our users. This includes encouraging responsible vulnerability research and disclosure. This policy sets out our definition of good faith in the context of finding and reporting vulnerabilities, as well as what you can expect from us in return. 4 | 5 | # Expectations 6 | 7 | When working with us according to this policy, you can expect us to: 8 | 9 | - Extend Safe Harbor for your vulnerability research that is related to this policy; 10 | - Work with you to understand and validate your report, including a timely initial response to the submission; 11 | - Work to remediate discovered vulnerabilities in a timely manner; and 12 | - Recognize your contribution to improving our security if you are the first to report a unique vulnerability, and your report triggers a code or configuration change. 13 | 14 | # Ground Rules 15 | 16 | To encourage vulnerability research and to avoid any confusion between good-faith hacking and malicious attack, we ask that you: 17 | 18 | - Play by the rules. This includes following this policy, as well as any other relevant agreements. If there is any inconsistency between this policy and any other relevant terms, the terms of this policy will prevail; 19 | - Report any vulnerability you’ve discovered promptly; 20 | - Avoid violating the privacy of others, disrupting our systems, destroying data, and/or harming user experience; 21 | - Use only the Official Channels to discuss vulnerability information with us; 22 | - Keep the details of any discovered vulnerabilities confidential until they are fixed, according to the Disclosure Policy; 23 | - Perform testing only on in-scope systems, and respect systems and activities which are out-of-scope; 24 | - If a vulnerability provides unintended access to data: Limit the amount of data you access to the minimum required for effectively demonstrating a Proof of Concept; and cease testing and submit a report immediately if you encounter any user data during testing, such as Personally Identifiable Information (PII), Personal Healthcare Information (PHI), credit card data, or proprietary information; 25 | - You should only interact with test accounts you own or with explicit permission from the account holder; and 26 | - Do not engage in extortion. 27 | 28 | # Safe Harbor 29 | 30 | When conducting vulnerability research according to this policy, we consider this research to be: 31 | 32 | - Authorized in accordance with the Computer Fraud and Abuse Act (CFAA) (and/or similar state laws), and we will not initiate or support legal action against you for accidental, good faith violations of this policy; 33 | - Exempt from the Digital Millennium Copyright Act (DMCA), and we will not bring a claim against you for circumvention of technology controls; 34 | - Exempt from restrictions in our Terms & Conditions that would interfere with conducting security research, and we waive those restrictions on a limited basis for work done under this policy; and 35 | - Lawful, helpful to the overall security of the Internet, and conducted in good faith. 36 | 37 | You are expected, as always, to comply with all applicable laws. 38 | 39 | If at any time you have concerns or are uncertain whether your security research is consistent with this policy, please submit a report through one of our Official Channels before going any further. 40 | -------------------------------------------------------------------------------- /docs/ERC165Upgradeable.md: -------------------------------------------------------------------------------- 1 | # ERC165Upgradeable.sol 2 | 3 | View Source: [@openzeppelin\contracts-upgradeable\utils\introspection\ERC165Upgradeable.sol](..\@openzeppelin\contracts-upgradeable\utils\introspection\ERC165Upgradeable.sol) 4 | 5 | **↗ Extends: [Initializable](Initializable.md), [IERC165Upgradeable](IERC165Upgradeable.md)** 6 | **↘ Derived Contracts: [ERC721Upgradeable](ERC721Upgradeable.md)** 7 | 8 | **ERC165Upgradeable** 9 | 10 | Implementation of the {IERC165} interface. 11 | Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check 12 | for the additional interface id that will be supported. For example: 13 | ```solidity 14 | function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { 15 | return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); 16 | } 17 | ``` 18 | Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. 19 | 20 | ## Contract Members 21 | **Constants & Variables** 22 | 23 | ```js 24 | uint256[50] private __gap; 25 | 26 | ``` 27 | 28 | ## Functions 29 | 30 | - [__ERC165_init()](#__erc165_init) 31 | - [__ERC165_init_unchained()](#__erc165_init_unchained) 32 | - [supportsInterface(bytes4 interfaceId)](#supportsinterface) 33 | 34 | ### __ERC165_init 35 | 36 | ```js 37 | function __ERC165_init() internal nonpayable onlyInitializing 38 | ``` 39 | 40 | **Arguments** 41 | 42 | | Name | Type | Description | 43 | | ------------- |------------- | -----| 44 | 45 | ### __ERC165_init_unchained 46 | 47 | ```js 48 | function __ERC165_init_unchained() internal nonpayable onlyInitializing 49 | ``` 50 | 51 | **Arguments** 52 | 53 | | Name | Type | Description | 54 | | ------------- |------------- | -----| 55 | 56 | ### supportsInterface 57 | 58 | See {IERC165-supportsInterface}. 59 | 60 | ```js 61 | function supportsInterface(bytes4 interfaceId) public view 62 | returns(bool) 63 | ``` 64 | 65 | **Arguments** 66 | 67 | | Name | Type | Description | 68 | | ------------- |------------- | -----| 69 | | interfaceId | bytes4 | | 70 | 71 | ## Contracts 72 | 73 | * [ActivateToken](ActivateToken.md) 74 | * [AddressUpgradeable](AddressUpgradeable.md) 75 | * [ContextUpgradeable](ContextUpgradeable.md) 76 | * [CreatorToken](CreatorToken.md) 77 | * [CustomToken](CustomToken.md) 78 | * [ERC165Upgradeable](ERC165Upgradeable.md) 79 | * [ERC20Upgradeable](ERC20Upgradeable.md) 80 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 81 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 82 | * [ERC721Upgradeable](ERC721Upgradeable.md) 83 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 84 | * [IERC165Upgradeable](IERC165Upgradeable.md) 85 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 86 | * [IERC20Upgradeable](IERC20Upgradeable.md) 87 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 88 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 89 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 90 | * [IERC721Upgradeable](IERC721Upgradeable.md) 91 | * [ImmutableEntity](ImmutableEntity.md) 92 | * [ImmutableProduct](ImmutableProduct.md) 93 | * [Initializable](Initializable.md) 94 | * [Migrations](Migrations.md) 95 | * [OwnableUpgradeable](OwnableUpgradeable.md) 96 | * [ProductActivate](ProductActivate.md) 97 | * [StringCommon](StringCommon.md) 98 | * [StringsUpgradeable](StringsUpgradeable.md) 99 | -------------------------------------------------------------------------------- /docs/ContextUpgradeable.md: -------------------------------------------------------------------------------- 1 | # ContextUpgradeable.sol 2 | 3 | View Source: [@openzeppelin\contracts-upgradeable\utils\ContextUpgradeable.sol](..\@openzeppelin\contracts-upgradeable\utils\ContextUpgradeable.sol) 4 | 5 | **↗ Extends: [Initializable](Initializable.md)** 6 | **↘ Derived Contracts: [ERC20Upgradeable](ERC20Upgradeable.md), [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md), [ERC721Upgradeable](ERC721Upgradeable.md), [OwnableUpgradeable](OwnableUpgradeable.md)** 7 | 8 | **ContextUpgradeable** 9 | 10 | Provides information about the current execution context, including the 11 | sender of the transaction and its data. While these are generally available 12 | via msg.sender and msg.data, they should not be accessed in such a direct 13 | manner, since when dealing with meta-transactions the account sending and 14 | paying for execution may not be the actual sender (as far as an application 15 | is concerned). 16 | This contract is only required for intermediate, library-like contracts. 17 | 18 | ## Contract Members 19 | **Constants & Variables** 20 | 21 | ```js 22 | uint256[50] private __gap; 23 | 24 | ``` 25 | 26 | ## Functions 27 | 28 | - [__Context_init()](#__context_init) 29 | - [__Context_init_unchained()](#__context_init_unchained) 30 | - [_msgSender()](#_msgsender) 31 | - [_msgData()](#_msgdata) 32 | 33 | ### __Context_init 34 | 35 | ```js 36 | function __Context_init() internal nonpayable onlyInitializing 37 | ``` 38 | 39 | **Arguments** 40 | 41 | | Name | Type | Description | 42 | | ------------- |------------- | -----| 43 | 44 | ### __Context_init_unchained 45 | 46 | ```js 47 | function __Context_init_unchained() internal nonpayable onlyInitializing 48 | ``` 49 | 50 | **Arguments** 51 | 52 | | Name | Type | Description | 53 | | ------------- |------------- | -----| 54 | 55 | ### _msgSender 56 | 57 | ```js 58 | function _msgSender() internal view 59 | returns(address) 60 | ``` 61 | 62 | **Arguments** 63 | 64 | | Name | Type | Description | 65 | | ------------- |------------- | -----| 66 | 67 | ### _msgData 68 | 69 | ```js 70 | function _msgData() internal view 71 | returns(bytes) 72 | ``` 73 | 74 | **Arguments** 75 | 76 | | Name | Type | Description | 77 | | ------------- |------------- | -----| 78 | 79 | ## Contracts 80 | 81 | * [ActivateToken](ActivateToken.md) 82 | * [AddressUpgradeable](AddressUpgradeable.md) 83 | * [ContextUpgradeable](ContextUpgradeable.md) 84 | * [CreatorToken](CreatorToken.md) 85 | * [CustomToken](CustomToken.md) 86 | * [ERC165Upgradeable](ERC165Upgradeable.md) 87 | * [ERC20Upgradeable](ERC20Upgradeable.md) 88 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 89 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 90 | * [ERC721Upgradeable](ERC721Upgradeable.md) 91 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 92 | * [IERC165Upgradeable](IERC165Upgradeable.md) 93 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 94 | * [IERC20Upgradeable](IERC20Upgradeable.md) 95 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 96 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 97 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 98 | * [IERC721Upgradeable](IERC721Upgradeable.md) 99 | * [ImmutableEntity](ImmutableEntity.md) 100 | * [ImmutableProduct](ImmutableProduct.md) 101 | * [Initializable](Initializable.md) 102 | * [Migrations](Migrations.md) 103 | * [OwnableUpgradeable](OwnableUpgradeable.md) 104 | * [ProductActivate](ProductActivate.md) 105 | * [StringCommon](StringCommon.md) 106 | * [StringsUpgradeable](StringsUpgradeable.md) 107 | -------------------------------------------------------------------------------- /docs/ERC721URIStorageUpgradeable.md: -------------------------------------------------------------------------------- 1 | # ERC721URIStorageUpgradeable.sol 2 | 3 | View Source: [@openzeppelin\contracts-upgradeable\token\ERC721\extensions\ERC721URIStorageUpgradeable.sol](..\@openzeppelin\contracts-upgradeable\token\ERC721\extensions\ERC721URIStorageUpgradeable.sol) 4 | 5 | **↗ Extends: [Initializable](Initializable.md), [ERC721Upgradeable](ERC721Upgradeable.md)** 6 | **↘ Derived Contracts: [CreatorToken](CreatorToken.md)** 7 | 8 | **ERC721URIStorageUpgradeable** 9 | 10 | ERC721 token with storage based token URI management. 11 | 12 | ## Contract Members 13 | **Constants & Variables** 14 | 15 | ```js 16 | mapping(uint256 => string) private _tokenURIs; 17 | uint256[49] private __gap; 18 | 19 | ``` 20 | 21 | ## Functions 22 | 23 | - [__ERC721URIStorage_init()](#__erc721uristorage_init) 24 | - [__ERC721URIStorage_init_unchained()](#__erc721uristorage_init_unchained) 25 | - [tokenURI(uint256 tokenId)](#tokenuri) 26 | - [_setTokenURI(uint256 tokenId, string _tokenURI)](#_settokenuri) 27 | - [_burn(uint256 tokenId)](#_burn) 28 | 29 | ### __ERC721URIStorage_init 30 | 31 | ```js 32 | function __ERC721URIStorage_init() internal nonpayable onlyInitializing 33 | ``` 34 | 35 | **Arguments** 36 | 37 | | Name | Type | Description | 38 | | ------------- |------------- | -----| 39 | 40 | ### __ERC721URIStorage_init_unchained 41 | 42 | ```js 43 | function __ERC721URIStorage_init_unchained() internal nonpayable onlyInitializing 44 | ``` 45 | 46 | **Arguments** 47 | 48 | | Name | Type | Description | 49 | | ------------- |------------- | -----| 50 | 51 | ### tokenURI 52 | 53 | See {IERC721Metadata-tokenURI}. 54 | 55 | ```js 56 | function tokenURI(uint256 tokenId) public view 57 | returns(string) 58 | ``` 59 | 60 | **Arguments** 61 | 62 | | Name | Type | Description | 63 | | ------------- |------------- | -----| 64 | | tokenId | uint256 | | 65 | 66 | ### _setTokenURI 67 | 68 | Sets `_tokenURI` as the tokenURI of `tokenId`. 69 | Requirements: 70 | - `tokenId` must exist. 71 | 72 | ```js 73 | function _setTokenURI(uint256 tokenId, string _tokenURI) internal nonpayable 74 | ``` 75 | 76 | **Arguments** 77 | 78 | | Name | Type | Description | 79 | | ------------- |------------- | -----| 80 | | tokenId | uint256 | | 81 | | _tokenURI | string | | 82 | 83 | ### _burn 84 | 85 | Destroys `tokenId`. 86 | The approval is cleared when the token is burned. 87 | Requirements: 88 | - `tokenId` must exist. 89 | Emits a {Transfer} event. 90 | 91 | ```js 92 | function _burn(uint256 tokenId) internal nonpayable 93 | ``` 94 | 95 | **Arguments** 96 | 97 | | Name | Type | Description | 98 | | ------------- |------------- | -----| 99 | | tokenId | uint256 | | 100 | 101 | ## Contracts 102 | 103 | * [ActivateToken](ActivateToken.md) 104 | * [AddressUpgradeable](AddressUpgradeable.md) 105 | * [ContextUpgradeable](ContextUpgradeable.md) 106 | * [CreatorToken](CreatorToken.md) 107 | * [CustomToken](CustomToken.md) 108 | * [ERC165Upgradeable](ERC165Upgradeable.md) 109 | * [ERC20Upgradeable](ERC20Upgradeable.md) 110 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 111 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 112 | * [ERC721Upgradeable](ERC721Upgradeable.md) 113 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 114 | * [IERC165Upgradeable](IERC165Upgradeable.md) 115 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 116 | * [IERC20Upgradeable](IERC20Upgradeable.md) 117 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 118 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 119 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 120 | * [IERC721Upgradeable](IERC721Upgradeable.md) 121 | * [ImmutableEntity](ImmutableEntity.md) 122 | * [ImmutableProduct](ImmutableProduct.md) 123 | * [Initializable](Initializable.md) 124 | * [Migrations](Migrations.md) 125 | * [OwnableUpgradeable](OwnableUpgradeable.md) 126 | * [ProductActivate](ProductActivate.md) 127 | * [StringCommon](StringCommon.md) 128 | * [StringsUpgradeable](StringsUpgradeable.md) 129 | -------------------------------------------------------------------------------- /client/src/utils/getWeb3.js: -------------------------------------------------------------------------------- 1 | // Middleware library for generatic version of universal web3 2 | // interface (ie. MetaMask and Infura). 3 | // Copyright 2020-2023 ImmutableSoft Inc. All rights reserved. 4 | import Web3 from "web3"; 5 | 6 | var getWeb3 = async () => { 7 | //const getWeb3 = () => 8 | // new Promise((resolve, reject) => { 9 | // Wait for loading completion to avoid race conditions with web3 injection timing. 10 | // window.addEventListener("load", async () => { 11 | // Modern dapp browsers... 12 | if (window.ethereum != null) { 13 | // alert("Modern"); 14 | const web3 = new Web3(window.ethereum); 15 | try { 16 | // Request account access if needed 17 | // await window.ethereum.enable(); 18 | const subdomainName = window.location.hostname.split(".")[0]; 19 | var chainId; 20 | 21 | if ((subdomainName === "127") || (subdomainName === "192") || 22 | (subdomainName.toLowerCase() === "mediachain") || 23 | (subdomainName.toLowerCase() === "titlechain")) 24 | { 25 | chainId = 80001; // Polygon Mumbai Testnet 26 | } else { 27 | chainId = 137;// Mainnet 28 | } 29 | window.ethereum.accounts = await window.ethereum.request({ 30 | method: "eth_requestAccounts", 31 | }); 32 | 33 | if (window.ethereum.networkVersion !== chainId) { 34 | try { 35 | await window.ethereum.request({ 36 | method: 'wallet_switchEthereumChain', 37 | params: [{ chainId: web3.utils.toHex(chainId) }] 38 | }); 39 | } catch (err) { 40 | // This error code indicates that the chain has not been added to MetaMask 41 | if (err.code === 4902) { 42 | 43 | if ((subdomainName === "127") || (subdomainName === "192") || 44 | (subdomainName.toLowerCase() === "mediachain") || 45 | (subdomainName.toLowerCase() === "titlechain")) 46 | { 47 | await window.ethereum.request({ 48 | method: 'wallet_addEthereumChain', 49 | params: [ 50 | { 51 | chainName: 'Polygon Mumbai Testnet', 52 | chainId: web3.utils.toHex(chainId), 53 | nativeCurrency: { name: 'MATIC', decimals: 18, symbol: 'MATIC' }, 54 | rpcUrls: ['https://rpc-mumbai.maticvigil.com'] 55 | } 56 | ] 57 | }); 58 | } 59 | else 60 | { 61 | await window.ethereum.request({ 62 | method: 'wallet_addEthereumChain', 63 | params: [ 64 | { 65 | chainName: 'Polygon Mainnet', 66 | chainId: web3.utils.toHex(chainId), 67 | nativeCurrency: { name: 'MATIC', decimals: 18, symbol: 'MATIC' }, 68 | rpcUrls: ['https://polygon-mainnet.chainstacklabs.com'] 69 | } 70 | ] 71 | }); 72 | } 73 | } 74 | } 75 | } 76 | 77 | // Acccounts now exposed 78 | return web3;//resolve(web3); 79 | } catch (error) { 80 | throw error;//reject(error); 81 | } 82 | } 83 | // Legacy dapp browsers... 84 | else if (window.web3 != null) { 85 | // alert("Legacy"); 86 | // Use Mist/MetaMask's provider. 87 | const web3 = window.web3; 88 | console.log("Injected web3 detected."); 89 | return web3;//resolve(web3); 90 | } 91 | // Fallback to Infura on Polygon 92 | else 93 | { 94 | // alert("Infura"); 95 | const provider = new Web3.providers.HttpProvider( 96 | // "http://127.0.0.1:7545" 97 | "https://polygon-mainnet.infura.io/v3/6233914717a744d19a2931dfbdd3dddc" 98 | ); 99 | const web3 = new Web3(provider); 100 | console.log("No web3 instance injected."); 101 | return web3;//resolve(web3); 102 | // reject(error); 103 | } 104 | // }); 105 | // }); 106 | } 107 | export default getWeb3; 108 | -------------------------------------------------------------------------------- /client/python-dev/app.py: -------------------------------------------------------------------------------- 1 | import json 2 | from web3 import Web3, HTTPProvider 3 | 4 | # UNCOMMENt ONLY ONE COLLECTION OF ENDPOINT AND CONTRACT ADDRESSES 5 | 6 | # Truffle development 7 | # Deployed contract address (see `migrate` command output: `contract address`) 8 | #endpoint_address = 'http://127.0.0.1:8545/' 9 | #entity_contract_address = '0xdd88f7448305079728c32ecaAFCA6a87166d52B6' 10 | #product_contract_address = '0x61f31C64EcDA67357ed8ca64EB80780c2033de5a' 11 | #creator_contract_address = '0x02a5d5C9c22eeDfAbE54c42Cd81F907Ffb27567C' 12 | #activate_contract_address = '0x5464dA569E4E93b0bd2BB7d4D46936B1E17E2642' 13 | #productActivate_contract_address = '0x333b8590Ff428D2bE80C27F8dB4973EDA61c7b75' 14 | 15 | # Polygon Mumbai 16 | # Deployed contract addresses (see `deploy_polygon_mumbai.txt') 17 | #endpoint_address = 'https://matic-mumbai.chainstacklabs.com/' 18 | #entity_contract_address = '0x4e3113E6DD6A7646aa8520905eC30A341D907B1d' 19 | #product_contract_address = '0x21027DD05168A559330649721D3600196aB0aeC2' 20 | #creator_contract_address = '0x5D319aC4488db1eD484be461FdD34F9ebfB6C6E9' 21 | #activate_contract_address = '0xe4984149608663b175667aF4A22bdbEEd17f9a26' 22 | #productActivate_contract_address = '0xdd88f7448305079728c32ecaAFCA6a87166d52B6' 23 | 24 | # Polygon Mainnet 25 | # Deployed contract addresses (see `deploy_polygon_mainnet.txt') 26 | endpoint_address = 'https://polygon-rpc.com/' 27 | entity_contract_address = '0xdd88f7448305079728c32ecaAFCA6a87166d52B6' 28 | product_contract_address = '0x61f31C64EcDA67357ed8ca64EB80780c2033de5a' 29 | creator_contract_address = '0x02a5d5C9c22eeDfAbE54c42Cd81F907Ffb27567C' 30 | activate_contract_address = '0x5464dA569E4E93b0bd2BB7d4D46936B1E17E2642' 31 | productActivate_contract_address = '0x333b8590Ff428D2bE80C27F8dB4973EDA61c7b75' 32 | 33 | # Client instance to interact with the blockchain 34 | web3 = Web3(HTTPProvider(endpoint_address)) 35 | 36 | # Set the default account (so we don't need to set the "from" for every transaction call) 37 | # TODO: enable this for write 38 | #web3.eth.defaultAccount = web3.eth.accounts[0] 39 | 40 | # Path to the compiled contract JSON file 41 | entity_contract_path = '../src/contracts/ImmutableEntity.json' 42 | product_contract_path = '../src/contracts/ImmutableProduct.json' 43 | creator_contract_path = '../src/contracts/CreatorToken.json' 44 | productActivate_contract_path = '../src/contracts/ProductActivate.json' 45 | activate_contract_path = '../src/contracts/ActivateToken.json' 46 | 47 | with open(entity_contract_path) as file: 48 | contract_json = json.load(file) # load contract info as JSON 49 | contract_abi = contract_json['abi'] # fetch contract's abi - necessary to call its functions 50 | 51 | # Initialize ImmutableEntity deployed contract interface 52 | entityContract = web3.eth.contract(address=entity_contract_address, abi=contract_abi) 53 | 54 | with open(product_contract_path) as file: 55 | contract_json = json.load(file) # load contract info as JSON 56 | contract_abi = contract_json['abi'] # fetch contract's abi - necessary to call its functions 57 | 58 | # Initialize ImmutableProduct deployed contract interface 59 | productContract = web3.eth.contract(address=product_contract_address, abi=contract_abi) 60 | 61 | with open(creator_contract_path) as file: 62 | contract_json = json.load(file) # load contract info as JSON 63 | contract_abi = contract_json['abi'] # fetch contract's abi - necessary to call its functions 64 | 65 | # Initialize CreatorToken deployed contract interface 66 | creatorContract = web3.eth.contract(address=creator_contract_address, abi=contract_abi) 67 | 68 | with open(activate_contract_path) as file: 69 | contract_json = json.load(file) # load contract info as JSON 70 | contract_abi = contract_json['abi'] # fetch contract's abi - necessary to call its functions 71 | 72 | # Initialize ActivateToken deployed contract interface 73 | activateContract = web3.eth.contract(address=activate_contract_address, abi=contract_abi) 74 | 75 | with open(productActivate_contract_path) as file: 76 | contract_json = json.load(file) # load contract info as JSON 77 | contract_abi = contract_json['abi'] # fetch contract's abi - necessary to call its functions 78 | 79 | # Initialize ProductActivate deployed contract interface 80 | productActivateContract = web3.eth.contract(address=productActivate_contract_address, abi=contract_abi) 81 | 82 | # Read entity contract and display first (1) entity information 83 | message = entityContract.functions.entityDetailsByIndex(1).call() 84 | print(message) 85 | 86 | # Read product contract and display first (1) entity product (0) information 87 | message = productContract.functions.productDetails(1, 0).call() 88 | print(message) 89 | 90 | # Read releases for this product from creator contract 91 | message = creatorContract.functions.creatorAllReleaseDetails(1, 0).call() 92 | print(message) 93 | 94 | # Read specific release information from release file hash (reverse lookup) 95 | message = creatorContract.functions.creatorReleaseHashDetails(message[2][0]).call() 96 | print(message) 97 | -------------------------------------------------------------------------------- /docs/IERC20Upgradeable.md: -------------------------------------------------------------------------------- 1 | # IERC20Upgradeable.sol 2 | 3 | View Source: [@openzeppelin\contracts-upgradeable\token\ERC20\IERC20Upgradeable.sol](..\@openzeppelin\contracts-upgradeable\token\ERC20\IERC20Upgradeable.sol) 4 | 5 | **↘ Derived Contracts: [ERC20Upgradeable](ERC20Upgradeable.md), [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md)** 6 | 7 | **IERC20Upgradeable** 8 | 9 | Interface of the ERC20 standard as defined in the EIP. 10 | 11 | **Events** 12 | 13 | ```js 14 | event Transfer(address indexed from, address indexed to, uint256 value); 15 | event Approval(address indexed owner, address indexed spender, uint256 value); 16 | ``` 17 | 18 | ## Functions 19 | 20 | - [totalSupply()](#totalsupply) 21 | - [balanceOf(address account)](#balanceof) 22 | - [transfer(address to, uint256 amount)](#transfer) 23 | - [allowance(address owner, address spender)](#allowance) 24 | - [approve(address spender, uint256 amount)](#approve) 25 | - [transferFrom(address from, address to, uint256 amount)](#transferfrom) 26 | 27 | ### totalSupply 28 | 29 | Returns the amount of tokens in existence. 30 | 31 | ```js 32 | function totalSupply() external view 33 | returns(uint256) 34 | ``` 35 | 36 | **Arguments** 37 | 38 | | Name | Type | Description | 39 | | ------------- |------------- | -----| 40 | 41 | ### balanceOf 42 | 43 | Returns the amount of tokens owned by `account`. 44 | 45 | ```js 46 | function balanceOf(address account) external view 47 | returns(uint256) 48 | ``` 49 | 50 | **Arguments** 51 | 52 | | Name | Type | Description | 53 | | ------------- |------------- | -----| 54 | | account | address | | 55 | 56 | ### transfer 57 | 58 | Moves `amount` tokens from the caller's account to `to`. 59 | Returns a boolean value indicating whether the operation succeeded. 60 | Emits a {Transfer} event. 61 | 62 | ```js 63 | function transfer(address to, uint256 amount) external nonpayable 64 | returns(bool) 65 | ``` 66 | 67 | **Arguments** 68 | 69 | | Name | Type | Description | 70 | | ------------- |------------- | -----| 71 | | to | address | | 72 | | amount | uint256 | | 73 | 74 | ### allowance 75 | 76 | Returns the remaining number of tokens that `spender` will be 77 | allowed to spend on behalf of `owner` through {transferFrom}. This is 78 | zero by default. 79 | This value changes when {approve} or {transferFrom} are called. 80 | 81 | ```js 82 | function allowance(address owner, address spender) external view 83 | returns(uint256) 84 | ``` 85 | 86 | **Arguments** 87 | 88 | | Name | Type | Description | 89 | | ------------- |------------- | -----| 90 | | owner | address | | 91 | | spender | address | | 92 | 93 | ### approve 94 | 95 | Sets `amount` as the allowance of `spender` over the caller's tokens. 96 | Returns a boolean value indicating whether the operation succeeded. 97 | IMPORTANT: Beware that changing an allowance with this method brings the risk 98 | that someone may use both the old and the new allowance by unfortunate 99 | transaction ordering. One possible solution to mitigate this race 100 | condition is to first reduce the spender's allowance to 0 and set the 101 | desired value afterwards: 102 | https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 103 | Emits an {Approval} event. 104 | 105 | ```js 106 | function approve(address spender, uint256 amount) external nonpayable 107 | returns(bool) 108 | ``` 109 | 110 | **Arguments** 111 | 112 | | Name | Type | Description | 113 | | ------------- |------------- | -----| 114 | | spender | address | | 115 | | amount | uint256 | | 116 | 117 | ### transferFrom 118 | 119 | Moves `amount` tokens from `from` to `to` using the 120 | allowance mechanism. `amount` is then deducted from the caller's 121 | allowance. 122 | Returns a boolean value indicating whether the operation succeeded. 123 | Emits a {Transfer} event. 124 | 125 | ```js 126 | function transferFrom(address from, address to, uint256 amount) external nonpayable 127 | returns(bool) 128 | ``` 129 | 130 | **Arguments** 131 | 132 | | Name | Type | Description | 133 | | ------------- |------------- | -----| 134 | | from | address | | 135 | | to | address | | 136 | | amount | uint256 | | 137 | 138 | ## Contracts 139 | 140 | * [ActivateToken](ActivateToken.md) 141 | * [AddressUpgradeable](AddressUpgradeable.md) 142 | * [ContextUpgradeable](ContextUpgradeable.md) 143 | * [CreatorToken](CreatorToken.md) 144 | * [CustomToken](CustomToken.md) 145 | * [ERC165Upgradeable](ERC165Upgradeable.md) 146 | * [ERC20Upgradeable](ERC20Upgradeable.md) 147 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 148 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 149 | * [ERC721Upgradeable](ERC721Upgradeable.md) 150 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 151 | * [IERC165Upgradeable](IERC165Upgradeable.md) 152 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 153 | * [IERC20Upgradeable](IERC20Upgradeable.md) 154 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 155 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 156 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 157 | * [IERC721Upgradeable](IERC721Upgradeable.md) 158 | * [ImmutableEntity](ImmutableEntity.md) 159 | * [ImmutableProduct](ImmutableProduct.md) 160 | * [Initializable](Initializable.md) 161 | * [Migrations](Migrations.md) 162 | * [OwnableUpgradeable](OwnableUpgradeable.md) 163 | * [ProductActivate](ProductActivate.md) 164 | * [StringCommon](StringCommon.md) 165 | * [StringsUpgradeable](StringsUpgradeable.md) 166 | -------------------------------------------------------------------------------- /docs/OwnableUpgradeable.md: -------------------------------------------------------------------------------- 1 | # OwnableUpgradeable.sol 2 | 3 | View Source: [@openzeppelin\contracts-upgradeable\access\OwnableUpgradeable.sol](..\@openzeppelin\contracts-upgradeable\access\OwnableUpgradeable.sol) 4 | 5 | **↗ Extends: [Initializable](Initializable.md), [ContextUpgradeable](ContextUpgradeable.md)** 6 | **↘ Derived Contracts: [ActivateToken](ActivateToken.md), [CreatorToken](CreatorToken.md), [CustomToken](CustomToken.md), [ImmutableEntity](ImmutableEntity.md), [ImmutableProduct](ImmutableProduct.md), [ProductActivate](ProductActivate.md), [StringCommon](StringCommon.md)** 7 | 8 | **OwnableUpgradeable** 9 | 10 | Contract module which provides a basic access control mechanism, where 11 | there is an account (an owner) that can be granted exclusive access to 12 | specific functions. 13 | By default, the owner account will be the one that deploys the contract. This 14 | can later be changed with {transferOwnership}. 15 | This module is used through inheritance. It will make available the modifier 16 | `onlyOwner`, which can be applied to your functions to restrict their use to 17 | the owner. 18 | 19 | ## Contract Members 20 | **Constants & Variables** 21 | 22 | ```js 23 | address private _owner; 24 | uint256[49] private __gap; 25 | 26 | ``` 27 | 28 | **Events** 29 | 30 | ```js 31 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 32 | ``` 33 | 34 | ## Modifiers 35 | 36 | - [onlyOwner](#onlyowner) 37 | 38 | ### onlyOwner 39 | 40 | Throws if called by any account other than the owner. 41 | 42 | ```js 43 | modifier onlyOwner() internal 44 | ``` 45 | 46 | **Arguments** 47 | 48 | | Name | Type | Description | 49 | | ------------- |------------- | -----| 50 | 51 | ## Functions 52 | 53 | - [__Ownable_init()](#__ownable_init) 54 | - [__Ownable_init_unchained()](#__ownable_init_unchained) 55 | - [owner()](#owner) 56 | - [renounceOwnership()](#renounceownership) 57 | - [transferOwnership(address newOwner)](#transferownership) 58 | - [_transferOwnership(address newOwner)](#_transferownership) 59 | 60 | ### __Ownable_init 61 | 62 | Initializes the contract setting the deployer as the initial owner. 63 | 64 | ```js 65 | function __Ownable_init() internal nonpayable onlyInitializing 66 | ``` 67 | 68 | **Arguments** 69 | 70 | | Name | Type | Description | 71 | | ------------- |------------- | -----| 72 | 73 | ### __Ownable_init_unchained 74 | 75 | ```js 76 | function __Ownable_init_unchained() internal nonpayable onlyInitializing 77 | ``` 78 | 79 | **Arguments** 80 | 81 | | Name | Type | Description | 82 | | ------------- |------------- | -----| 83 | 84 | ### owner 85 | 86 | Returns the address of the current owner. 87 | 88 | ```js 89 | function owner() public view 90 | returns(address) 91 | ``` 92 | 93 | **Arguments** 94 | 95 | | Name | Type | Description | 96 | | ------------- |------------- | -----| 97 | 98 | ### renounceOwnership 99 | 100 | Leaves the contract without owner. It will not be possible to call 101 | `onlyOwner` functions anymore. Can only be called by the current owner. 102 | NOTE: Renouncing ownership will leave the contract without an owner, 103 | thereby removing any functionality that is only available to the owner. 104 | 105 | ```js 106 | function renounceOwnership() public nonpayable onlyOwner 107 | ``` 108 | 109 | **Arguments** 110 | 111 | | Name | Type | Description | 112 | | ------------- |------------- | -----| 113 | 114 | ### transferOwnership 115 | 116 | Transfers ownership of the contract to a new account (`newOwner`). 117 | Can only be called by the current owner. 118 | 119 | ```js 120 | function transferOwnership(address newOwner) public nonpayable onlyOwner 121 | ``` 122 | 123 | **Arguments** 124 | 125 | | Name | Type | Description | 126 | | ------------- |------------- | -----| 127 | | newOwner | address | | 128 | 129 | ### _transferOwnership 130 | 131 | Transfers ownership of the contract to a new account (`newOwner`). 132 | Internal function without access restriction. 133 | 134 | ```js 135 | function _transferOwnership(address newOwner) internal nonpayable 136 | ``` 137 | 138 | **Arguments** 139 | 140 | | Name | Type | Description | 141 | | ------------- |------------- | -----| 142 | | newOwner | address | | 143 | 144 | ## Contracts 145 | 146 | * [ActivateToken](ActivateToken.md) 147 | * [AddressUpgradeable](AddressUpgradeable.md) 148 | * [ContextUpgradeable](ContextUpgradeable.md) 149 | * [CreatorToken](CreatorToken.md) 150 | * [CustomToken](CustomToken.md) 151 | * [ERC165Upgradeable](ERC165Upgradeable.md) 152 | * [ERC20Upgradeable](ERC20Upgradeable.md) 153 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 154 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 155 | * [ERC721Upgradeable](ERC721Upgradeable.md) 156 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 157 | * [IERC165Upgradeable](IERC165Upgradeable.md) 158 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 159 | * [IERC20Upgradeable](IERC20Upgradeable.md) 160 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 161 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 162 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 163 | * [IERC721Upgradeable](IERC721Upgradeable.md) 164 | * [ImmutableEntity](ImmutableEntity.md) 165 | * [ImmutableProduct](ImmutableProduct.md) 166 | * [Initializable](Initializable.md) 167 | * [Migrations](Migrations.md) 168 | * [OwnableUpgradeable](OwnableUpgradeable.md) 169 | * [ProductActivate](ProductActivate.md) 170 | * [StringCommon](StringCommon.md) 171 | * [StringsUpgradeable](StringsUpgradeable.md) 172 | -------------------------------------------------------------------------------- /docs/SmartContracts.md: -------------------------------------------------------------------------------- 1 | # ImmutableEcosystem 2 | 3 | The [Immutable Ecosystem](https://immutablesoft.org) is a hardware and language agnostic Ethereum based application store. This decentralized ecosystem has two main components, the Solidity smart contracts and the Distributed Application (Dapp). This repository is for the Smart Contracts only. The generated API documentation for the smart contracts is located in the 'docs' directory. The unit tests of the smart contracts are located in the 'tests' directory. 4 | 5 | ## disclosure Bug Bounty 6 | 7 | A bug bounty is in effect for the smart contracts within the Immutable Ecosystem. Adopting vulnerability disclosure best practices we have followed the disclose.io [framework](./core-terms-USA.md) to safeguard security researchers. 8 | 9 | To receive the maximum payout the report should include a fix to the problem if possible. Specific payouts to the bug bounty depend on the impact of the bug as well as the general likelihood of the bug. In general, the theft of ETH, tokens or Entity accounts are considered of the highest impact. When calculating the severity and thus payout for reported issues we will utilize the common impact vs. likelihood chart below. 10 | 11 | ![image impact](./images/ImpactVSLikelihood.png) 12 | 13 | Exemptions: Bugs in the Solidity compiler, third party contracts (ERC20, ENS, etc.), or Ethereum, Optimistic Ethereum and/or EVM or optimistic rollups in general are explicitly not permissible within this bug bounty unless the bug is directly caused by ImmutableSoft's use of these third party components. Also, bugs in the Dapp (once available) are not part of this bug bounty (but please report them if you find them ;-) 14 | 15 | The procedure for reporting a bug is to create a Github issue and identify the general problem. To maximize your paybout you then have 15 days to further expand on and discuss the problem and/or develop a solution. Please do not forget this first step so you can ensure your effort will be rewarded. Bugs discovered during the bounty are awarded in a first come, first served basis. No duplicate bugs will be rewarded, however additional explanations and/or solutions by others may result in the sharing of a particular bounty. 16 | 17 | If you do not have time to write up a formal issue report, or wish to remain anonymous, you can submit your report through email. Send your submission directly to Security at ImmutableSoft dot org. Any submission that is acted upon by ImmutableSoft is eligable for a payout. If you wish to decline payment or receive your reward with tokens, please mention this in email. 18 | 19 | ## Overview 20 | 21 | The Immutable Ecosystem is split into six Smart Contracts. The [ActivateToken](https://immutablesoft.github.io/ImmutableEcosystem/docs/ActivateToken.html) is a ERC721 token that activates digital products offered for sale in the Ecosystem. The [ImmutableEntity](https://immutablesoft.github.io/ImmutableEcosystem/docs/ImmutableEntity.html) handles registering and managing orangizations (entities) within the Ecosystem. The [ImmutableProduct](https://immutablesoft.github.io/ImmutableEcosystem/docs/ImmutableProduct.html) is responsible for managing products and their offers of activation by approved entities with the Ecosystem. The [CreatorToken](https://immutablesoft.github.io/ImmutableEcosystem/docs/ImmutableEntity.html) is an ERC721 token that handles the creation and lookup of file releases and Ricardian relations. And finally the [ProductActivate](https://immutablesoft.github.io/ImmutableEcosystem/docs/ProductActivate.html) contract executes product offers by escrowing payment to the product creator before minting new product specific tokens directly to the purchaser. 22 | 23 | This project utilizes 'truffle' to build and test the solidity smart contracts. Typical usage after cloning the project includes the following commands issued in the base of the cloned directory. See https://www.trufflesuite.com/ for more information on truffle. 24 | 25 | ### npm install 26 | ### truffle compile --all 27 | ### truffle deploy --all 28 | ### truffle test 29 | 30 | After contract deployment the following ActivateToken contract initialization procedures are taken by the contract owner to make the Ecosystem operational. The first step configures and restricts token transfers to or from the Ecosystem contracts only. See the second javascript test in the file test/TestImmutableEcosystem.js for examples of how to do this. 31 | 32 | ### restrictToken(address activateAddress, address creatorAddress) 33 | 34 | Any use of the Ecosystem before this step are taken is limited. Afterward the Ecosystem is ready for use. 35 | 36 | ## ImmutableEntity 37 | 38 | Individuals and organization can register themselves as entities of either Creator, Distributor, or End User type. Each Entity is assigned a unique index within the Ecosystem upon creation. This index, as well as the Ethereum wallet address used to create the Entity, are thus forth used to uniquely identify the Entity. This smart contract has an interface for the resale of tokens as well as the configuration of an ETH bank account that will be paid out too. 39 | 40 | The full public API documentation for this smart contract is available here [ImmutableEntity](https://immutablesoft.github.io/ImmutableEcosystem/docs/ImmutableEntity.html). 41 | 42 | ## ImmutableProduct 43 | 44 | The ImmutableProduct smart contract has interfaces to allow registered entities to create new products and product releases, funding those releases with an escrow holding tokens. Nonprofit creators have this escrow minted for them while commercial creators must transfer tokens to the product release escrow. This contract also handles end user download and authentication verification interfaces as well product release challenges. End users can use this contract to ensure authentic installation of products and to report any discovered file hash mismatch and be rewarded with one half of the outstanding escrow. 45 | 46 | The full public API documentation for this smart contract is available here [ImmutableProduct](https://immutablesoft.github.io/ImmutableEcosystem/docs/ImmutableProduct.html). 47 | -------------------------------------------------------------------------------- /docs/StringCommon.md: -------------------------------------------------------------------------------- 1 | # Immutable String - common constants and string routines (StringCommon.sol) 2 | 3 | View Source: [\contracts\StringCommon.sol](..\contracts\StringCommon.sol) 4 | 5 | **↗ Extends: [Initializable](Initializable.md), [OwnableUpgradeable](OwnableUpgradeable.md)** 6 | 7 | **StringCommon** 8 | 9 | StringCommon is string related general/pure functions 10 | 11 | ## Contract Members 12 | **Constants & Variables** 13 | 14 | ```js 15 | uint256 public constant Unknown; 16 | uint256 public constant Creator; 17 | uint256 public constant Distributor; 18 | uint256 public constant EndUser; 19 | uint256 public constant Nonprofit; 20 | uint256 public constant Automatic; 21 | uint256 public constant CustomToken; 22 | uint256 public constant CoutryCodeOffset; 23 | uint256 public constant CoutryCodeMask; 24 | uint256 public constant Tools; 25 | uint256 public constant System; 26 | uint256 public constant Platform; 27 | uint256 public constant Education; 28 | uint256 public constant Entertainment; 29 | uint256 public constant Communications; 30 | uint256 public constant Professional; 31 | uint256 public constant Manufacturing; 32 | uint256 public constant Business; 33 | uint256 public constant Hazard; 34 | uint256 public constant Adult; 35 | uint256 public constant Restricted; 36 | uint256 public constant USCryptoExport; 37 | uint256 public constant EUCryptoExport; 38 | uint256 public constant Mandarin; 39 | uint256 public constant Spanish; 40 | uint256 public constant English; 41 | uint256 public constant Hindi; 42 | uint256 public constant Bengali; 43 | uint256 public constant Portuguese; 44 | uint256 public constant Russian; 45 | uint256 public constant Japanese; 46 | uint256 public constant Punjabi; 47 | uint256 public constant Marathi; 48 | uint256 public constant Teluga; 49 | uint256 public constant Wu; 50 | uint256 public constant Turkish; 51 | uint256 public constant Korean; 52 | uint256 public constant French; 53 | uint256 public constant German; 54 | uint256 public constant Vietnamese; 55 | uint256 public constant Windows_x86; 56 | uint256 public constant Windows_amd64; 57 | uint256 public constant Windows_aarch64; 58 | uint256 public constant Linux_x86; 59 | uint256 public constant Linux_amd64; 60 | uint256 public constant Linux_aarch64; 61 | uint256 public constant Android_aarch64; 62 | uint256 public constant iPhone_arm64; 63 | uint256 public constant BIOS_x86; 64 | uint256 public constant BIOS_amd64; 65 | uint256 public constant BIOS_aarch32; 66 | uint256 public constant BIOS_aarch64; 67 | uint256 public constant BIOS_arm64; 68 | uint256 public constant Mac_amd64; 69 | uint256 public constant Mac_arm64; 70 | uint256 public constant SourceCode; 71 | uint256 public constant Agnostic; 72 | uint256 public constant NotApplicable; 73 | uint256 public constant Other; 74 | uint256 public constant ExpirationFlag; 75 | uint256 public constant LimitationFlag; 76 | uint256 public constant NoResaleFlag; 77 | uint256 public constant FeatureFlag; 78 | uint256 public constant LimitedOffersFlag; 79 | uint256 public constant BulkOffersFlag; 80 | uint256 public constant RicardianReqFlag; 81 | uint256 public constant EntityIdOffset; 82 | uint256 public constant EntityIdMask; 83 | uint256 public constant ProductIdOffset; 84 | uint256 public constant ProductIdMask; 85 | uint256 public constant ReleaseIdOffset; 86 | uint256 public constant ReleaseIdMask; 87 | uint256 public constant UniqueIdOffset; 88 | uint256 public constant UniqueIdMask; 89 | uint256 public constant FlagsOffset; 90 | uint256 public constant FlagsMask; 91 | uint256 public constant ExpirationOffset; 92 | uint256 public constant ExpirationMask; 93 | uint256 public constant ValueOffset; 94 | uint256 public constant ValueMask; 95 | string public constant EntityIsZero; 96 | string public constant OfferNotFound; 97 | string public constant EntityNotValidated; 98 | string public constant ProductNotFound; 99 | string public constant TokenEntityNoMatch; 100 | string public constant TokenProductNoMatch; 101 | string public constant TokenNotUnique; 102 | 103 | ``` 104 | 105 | ## Functions 106 | 107 | - [initialize()](#initialize) 108 | - [stringsEqual(string _a, string _b)](#stringsequal) 109 | 110 | ### initialize 111 | 112 | Initialize the StringCommon smart contract 113 | Called during first deployment only (not on upgrade) as 114 | this is an OpenZepellin upgradable contract 115 | 116 | ```js 117 | function initialize() public nonpayable initializer 118 | ``` 119 | 120 | **Arguments** 121 | 122 | | Name | Type | Description | 123 | | ------------- |------------- | -----| 124 | 125 | ### stringsEqual 126 | 127 | Compare strings and return true if equal. 128 | Case sensitive. 129 | 130 | ```js 131 | function stringsEqual(string _a, string _b) public pure 132 | returns(bool) 133 | ``` 134 | 135 | **Returns** 136 | 137 | true if strings are equal, otherwise false 138 | 139 | **Arguments** 140 | 141 | | Name | Type | Description | 142 | | ------------- |------------- | -----| 143 | | _a | string | The string to be compared | 144 | | _b | string | The string to compare | 145 | 146 | ## Contracts 147 | 148 | * [ActivateToken](ActivateToken.md) 149 | * [AddressUpgradeable](AddressUpgradeable.md) 150 | * [ContextUpgradeable](ContextUpgradeable.md) 151 | * [CreatorToken](CreatorToken.md) 152 | * [CustomToken](CustomToken.md) 153 | * [ERC165Upgradeable](ERC165Upgradeable.md) 154 | * [ERC20Upgradeable](ERC20Upgradeable.md) 155 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 156 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 157 | * [ERC721Upgradeable](ERC721Upgradeable.md) 158 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 159 | * [IERC165Upgradeable](IERC165Upgradeable.md) 160 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 161 | * [IERC20Upgradeable](IERC20Upgradeable.md) 162 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 163 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 164 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 165 | * [IERC721Upgradeable](IERC721Upgradeable.md) 166 | * [ImmutableEntity](ImmutableEntity.md) 167 | * [ImmutableProduct](ImmutableProduct.md) 168 | * [Initializable](Initializable.md) 169 | * [Migrations](Migrations.md) 170 | * [OwnableUpgradeable](OwnableUpgradeable.md) 171 | * [ProductActivate](ProductActivate.md) 172 | * [StringCommon](StringCommon.md) 173 | * [StringsUpgradeable](StringsUpgradeable.md) 174 | -------------------------------------------------------------------------------- /client/python-dev/record.py: -------------------------------------------------------------------------------- 1 | import json 2 | from web3 import Web3, HTTPProvider 3 | from web3.gas_strategies.time_based import medium_gas_price_strategy 4 | 5 | ##################################################################### 6 | # WALLET CONFIGURATION (global) 7 | # Change below to load from a keystore or env variable 8 | # Ganache testing only. (Account 0 of ganache-cli --deterministic) 9 | # This address MUST first be regsitered with Immutable Ecosystem 10 | ##################################################################### 11 | private_key = '0x6cbed15c793ce57650b9877cf6fa156fbef513c4e6134f022a85b1ffdd59b2a1' 12 | from_address = '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0' 13 | 14 | ##################################################################### 15 | # BLOCKCHAIN CONFIGURATION (global) 16 | ##################################################################### 17 | # UNCOMMENt ONLY ONE COLLECTION OF ENDPOINT AND CONTRACT ADDRESSES 18 | 19 | ##################################################################### 20 | # Truffle development 21 | ##################################################################### 22 | endpoint_address = 'http://127.0.0.1:8545/' 23 | chain_id = 1337 24 | # Deployed contract addresses (see `migrate` command output: `contract address`) 25 | entity_contract_address = '0xdd88f7448305079728c32ecaAFCA6a87166d52B6' 26 | product_contract_address = '0x61f31C64EcDA67357ed8ca64EB80780c2033de5a' 27 | creator_contract_address = '0xA57B8a5584442B467b4689F1144D269d096A3daF' 28 | activate_contract_address = '0x5464dA569E4E93b0bd2BB7d4D46936B1E17E2642' 29 | productActivate_contract_address = '0x333b8590Ff428D2bE80C27F8dB4973EDA61c7b75' 30 | 31 | ##################################################################### 32 | # Polygon Mumbai 33 | ##################################################################### 34 | # Deployed contract addresses (see `deploy_polygon_mumbai.txt') 35 | #endpoint_address = 'https://matic-mumbai.chainstacklabs.com/' 36 | #chain_id = 80001 37 | #entity_contract_address = '0x4e3113E6DD6A7646aa8520905eC30A341D907B1d' 38 | #product_contract_address = '0x21027DD05168A559330649721D3600196aB0aeC2' 39 | #creator_contract_address = '0x5D319aC4488db1eD484be461FdD34F9ebfB6C6E9' 40 | #activate_contract_address = '0xe4984149608663b175667aF4A22bdbEEd17f9a26' 41 | #productActivate_contract_address = '0xdd88f7448305079728c32ecaAFCA6a87166d52B6' 42 | 43 | ##################################################################### 44 | # Polygon Mainnet 45 | # Deployed contract addresses (see `deploy_polygon_mainnet.txt') 46 | ##################################################################### 47 | #endpoint_address = 'https://polygon-rpc.com/' 48 | #chain_id = 137 49 | #entity_contract_address = '0xdd88f7448305079728c32ecaAFCA6a87166d52B6' 50 | #product_contract_address = '0x61f31C64EcDA67357ed8ca64EB80780c2033de5a' 51 | #creator_contract_address = '0x02a5d5C9c22eeDfAbE54c42Cd81F907Ffb27567C' 52 | #activate_contract_address = '0x5464dA569E4E93b0bd2BB7d4D46936B1E17E2642' 53 | #productActivate_contract_address = '0x333b8590Ff428D2bE80C27F8dB4973EDA61c7b75' 54 | 55 | ##################################################################### 56 | # RecordProductReleases: parameters must be arrays of equal length 57 | # index - the product index (as defined in Immutable Ecosystem) 58 | # sha - the file PoE: the unique one-way SHA256 checksum 59 | # uri - the file URI: public or private URI 60 | # version - the file version (0x0001000200030004 = v1.2.3.4) 61 | # root - the Ricardian root of file, or zero 62 | ##################################################################### 63 | def RecordProductReleases(index, sha, uri, version, root): 64 | 65 | # Client instance to interact with the blockchain 66 | web3 = Web3(HTTPProvider(endpoint_address)) 67 | 68 | ##################################################################### 69 | # SETUP WEB3 ENDPOINT AND CONTRACTS 70 | ##################################################################### 71 | 72 | # Path to the compiled contract JSON file 73 | creator_contract_path = '../src/contracts/CreatorToken.json' 74 | 75 | with open(creator_contract_path) as file: 76 | contract_json = json.load(file) # load contract info as JSON 77 | contract_abi = contract_json['abi'] # fetch contract's abi - necessary to call its functions 78 | 79 | # Initialize CreatorToken deployed contract interface 80 | creatorContract = web3.eth.contract(address=creator_contract_address, abi=contract_abi) 81 | 82 | # Initialize the gas price strategy 83 | web3.eth.setGasPriceStrategy(medium_gas_price_strategy) 84 | 85 | ##################################################################### 86 | # ENCODE CONTRACT TRANSACTION, SIGN AND SUBMIT TO ENDPOINT 87 | ##################################################################### 88 | 89 | # Build new release transaction for this product from creator contract 90 | newRelease = creatorContract.functions.creatorReleases(index, version, sha, uri, root).buildTransaction({ 91 | 'chainId': chain_id, 92 | 'nonce': web3.eth.getTransactionCount(from_address), 93 | 'from': from_address, 94 | }) 95 | 96 | # Sign the transaction with private key configured above 97 | signed_txn = web3.eth.account.sign_transaction(newRelease, private_key) 98 | print(signed_txn.rawTransaction) 99 | 100 | # Send the transaction and wait for receipt of it being mined 101 | # Note: This can take awhile, and may fail due to low gas on 102 | # Mainnet (Polygon/Ethereum). 103 | tx_hash = web3.eth.sendRawTransaction(signed_txn.rawTransaction) 104 | receipt = web3.eth.waitForTransactionReceipt(tx_hash) 105 | return receipt 106 | 107 | ##################################################################### 108 | # Record a single file PoE for product 0 to the IE smart contracts 109 | ##################################################################### 110 | # RecordProductReleases(index, sha, uri, version, root) 111 | tx = RecordProductReleases([0], [0x0ABA0D8FB16D662BB67A75EAEA2DFDE44525CC28EA46A243EB63C44D902BA1D3], 112 | ['https://licenseware.io/audit_reports/clientA/Report_02.pdf'], 113 | [0x0001000200030004], [0]) 114 | # Check if successful 115 | # See output on https://web3py.readthedocs.io/en/stable/examples.html#looking-up-transactions 116 | if tx["status"] == 1: 117 | print("success") 118 | else: 119 | print("failed") 120 | 121 | print(dict(tx)) # record this receipt in web2? 122 | 123 | # From receipt hash, look up the full transaction data (ie. Etherscan) 124 | #web3 = Web3(HTTPProvider(endpoint_address)) 125 | #print(web3.eth.get_transaction(tx["transactionHash"])) 126 | -------------------------------------------------------------------------------- /docs/Initializable.md: -------------------------------------------------------------------------------- 1 | # Initializable.sol 2 | 3 | View Source: [@openzeppelin\contracts-upgradeable\proxy\utils\Initializable.sol](..\@openzeppelin\contracts-upgradeable\proxy\utils\Initializable.sol) 4 | 5 | **↘ Derived Contracts: [ActivateToken](ActivateToken.md), [ContextUpgradeable](ContextUpgradeable.md), [CreatorToken](CreatorToken.md), [CustomToken](CustomToken.md), [ERC165Upgradeable](ERC165Upgradeable.md), [ERC20Upgradeable](ERC20Upgradeable.md), [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md), [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md), [ERC721Upgradeable](ERC721Upgradeable.md), [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md), [ImmutableEntity](ImmutableEntity.md), [ImmutableProduct](ImmutableProduct.md), [OwnableUpgradeable](OwnableUpgradeable.md), [ProductActivate](ProductActivate.md), [StringCommon](StringCommon.md)** 6 | 7 | **Initializable** 8 | 9 | This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed 10 | behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an 11 | external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer 12 | function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. 13 | The initialization functions use a version number. Once a version number is used, it is consumed and cannot be 14 | reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in 15 | case an upgrade adds a module that needs to be initialized. 16 | For example: 17 | [.hljs-theme-light.nopadding] 18 | ``` 19 | contract MyToken is ERC20Upgradeable { 20 | function initialize() initializer public { 21 | __ERC20_init("MyToken", "MTK"); 22 | } 23 | } 24 | contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { 25 | function initializeV2() reinitializer(2) public { 26 | __ERC20Permit_init("MyToken"); 27 | } 28 | } 29 | ``` 30 | TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as 31 | possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. 32 | CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure 33 | that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. 34 | [CAUTION] 35 | ==== 36 | Avoid leaving a contract uninitialized. 37 | An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation 38 | contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke 39 | the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: 40 | [.hljs-theme-light.nopadding] 41 | ``` 42 | /// 43 | 44 | ## Contract Members 45 | **Constants & Variables** 46 | 47 | ```js 48 | uint8 private _initialized; 49 | bool private _initializing; 50 | 51 | ``` 52 | 53 | **Events** 54 | 55 | ```js 56 | event Initialized(uint8 version); 57 | ``` 58 | 59 | ## Modifiers 60 | 61 | - [initializer](#initializer) 62 | - [reinitializer](#reinitializer) 63 | - [onlyInitializing](#onlyinitializing) 64 | 65 | ### initializer 66 | 67 | A modifier that defines a protected initializer function that can be invoked at most once. In its scope, 68 | `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. 69 | 70 | ```js 71 | modifier initializer() internal 72 | ``` 73 | 74 | **Arguments** 75 | 76 | | Name | Type | Description | 77 | | ------------- |------------- | -----| 78 | 79 | ### reinitializer 80 | 81 | A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the 82 | contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be 83 | used to initialize parent contracts. 84 | `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original 85 | initialization step. This is essential to configure modules that are added through upgrades and that require 86 | initialization. 87 | Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in 88 | a contract, executing them in the right order is up to the developer or operator. 89 | 90 | ```js 91 | modifier reinitializer(uint8 version) internal 92 | ``` 93 | 94 | **Arguments** 95 | 96 | | Name | Type | Description | 97 | | ------------- |------------- | -----| 98 | | version | uint8 | | 99 | 100 | ### onlyInitializing 101 | 102 | Modifier to protect an initialization function so that it can only be invoked by functions with the 103 | {initializer} and {reinitializer} modifiers, directly or indirectly. 104 | 105 | ```js 106 | modifier onlyInitializing() internal 107 | ``` 108 | 109 | **Arguments** 110 | 111 | | Name | Type | Description | 112 | | ------------- |------------- | -----| 113 | 114 | ## Functions 115 | 116 | - [_disableInitializers()](#_disableinitializers) 117 | - [_setInitializedVersion(uint8 version)](#_setinitializedversion) 118 | 119 | ### _disableInitializers 120 | 121 | Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. 122 | Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized 123 | to any version. It is recommended to use this to lock implementation contracts that are designed to be called 124 | through proxies. 125 | 126 | ```js 127 | function _disableInitializers() internal nonpayable 128 | ``` 129 | 130 | **Arguments** 131 | 132 | | Name | Type | Description | 133 | | ------------- |------------- | -----| 134 | 135 | ### _setInitializedVersion 136 | 137 | ```js 138 | function _setInitializedVersion(uint8 version) private nonpayable 139 | returns(bool) 140 | ``` 141 | 142 | **Arguments** 143 | 144 | | Name | Type | Description | 145 | | ------------- |------------- | -----| 146 | | version | uint8 | | 147 | 148 | ## Contracts 149 | 150 | * [ActivateToken](ActivateToken.md) 151 | * [AddressUpgradeable](AddressUpgradeable.md) 152 | * [ContextUpgradeable](ContextUpgradeable.md) 153 | * [CreatorToken](CreatorToken.md) 154 | * [CustomToken](CustomToken.md) 155 | * [ERC165Upgradeable](ERC165Upgradeable.md) 156 | * [ERC20Upgradeable](ERC20Upgradeable.md) 157 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 158 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 159 | * [ERC721Upgradeable](ERC721Upgradeable.md) 160 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 161 | * [IERC165Upgradeable](IERC165Upgradeable.md) 162 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 163 | * [IERC20Upgradeable](IERC20Upgradeable.md) 164 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 165 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 166 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 167 | * [IERC721Upgradeable](IERC721Upgradeable.md) 168 | * [ImmutableEntity](ImmutableEntity.md) 169 | * [ImmutableProduct](ImmutableProduct.md) 170 | * [Initializable](Initializable.md) 171 | * [Migrations](Migrations.md) 172 | * [OwnableUpgradeable](OwnableUpgradeable.md) 173 | * [ProductActivate](ProductActivate.md) 174 | * [StringCommon](StringCommon.md) 175 | * [StringsUpgradeable](StringsUpgradeable.md) 176 | -------------------------------------------------------------------------------- /truffle-config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const HDWalletProvider = require("@truffle/hdwallet-provider"); 3 | const { projectID, mnemonicPhrase } = require('./secrets.json'); 4 | 5 | var optimism_mnemonic = 'test test test test test test test test test test test junk' 6 | module.exports = { 7 | 8 | // See 9 | // to customize your Truffle configuration! 10 | contracts_build_directory: path.join(__dirname, "client/src/contracts"), 11 | 12 | networks: { 13 | development: { 14 | host: "127.0.0.1", // Localhost (default: none) 15 | port: 8545, // Standard Ethereum port (default: none) 16 | network_id: "*", // Any network (default: none) 17 | gasPrice: 30000000000 // 50gwei Estimate real world ETH costs 18 | }, 19 | optimistic: { 20 | provider: () => new HDWalletProvider(optimism_mnemonic, "http://127.0.0.1:8545/"), 21 | network_id: "420", 22 | gasPrice: 120000000000 // 120gwei Estimate real world L2 costs 23 | }, 24 | optimistic_kovan: { 25 | provider: () => new HDWalletProvider( 26 | mnemonicPhrase, "https://kovan.optimism.io" 27 | ), 28 | network_id: '69' 29 | }, 30 | optimistic_mainnet: { 31 | provider: () => new HDWalletProvider( 32 | optimism_mnemonic/*mnemonicPhrase*/, "https://mainnet.optimism.io" 33 | ), 34 | network_id: '10' 35 | }, 36 | ropsten: { 37 | provider: () => new HDWalletProvider( 38 | mnemonicPhrase, 'https://ropsten.infura.io/v3/' + projectID 39 | ), 40 | network_id: '3', 41 | }, 42 | kovan: { 43 | provider: () => new HDWalletProvider( 44 | mnemonicPhrase, 'https://kovan.infura.io/v3/' + projectID 45 | ), 46 | network_id: '42', 47 | }, 48 | mainnet: { 49 | provider: () => new HDWalletProvider( 50 | mnemonicPhrase, 'https://mainnet.infura.io/v3/' + projectID 51 | ), 52 | networkId: 1, 53 | }, 54 | //polygon Infura mainnet 55 | polygon_infura_mainnet: { 56 | provider: () => new HDWalletProvider( 57 | mnemonicPhrase, 'https://polygon-mainnet.infura.io/v3/' + projectID 58 | ), 59 | network_id: 137, 60 | confirmations: 2, 61 | timeoutBlocks: 200, 62 | skipDryRun: true, 63 | chainId: 137 64 | }, 65 | polygon_alchemy_mainnet: { 66 | provider: () => new HDWalletProvider( 67 | mnemonicPhrase, 'https://polygon-mainnet.g.alchemy.com/v2/' + projectID 68 | ), 69 | network_id: 137, 70 | confirmations: 2, 71 | timeoutBlocks: 200, 72 | skipDryRun: true, 73 | chainId: 137 74 | }, 75 | polygon_mainnet: { 76 | provider: () => new HDWalletProvider( 77 | mnemonicPhrase, 'https://polygon-rpc.com/' 78 | ), 79 | network_id: 137, 80 | confirmations: 2, 81 | timeoutBlocks: 200, 82 | skipDryRun: true, 83 | chainId: 137, 84 | gasPrice: 32000000000 // 32gwei Estimate real world ETH costs 85 | }, 86 | //polygon Testnet 87 | polygon_testnet: { 88 | provider: () => new HDWalletProvider( 89 | mnemonicPhrase, "https://matic-mumbai.chainstacklabs.com" 90 | ), 91 | network_id: 80001, 92 | confirmations: 2, 93 | timeoutBlocks: 200, 94 | skipDryRun: true, 95 | chainId: 80001 96 | }, 97 | //polygon Infura testnet 98 | polygon_infura_testnet: { 99 | provider: () => new HDWalletProvider( 100 | mnemonicPhrase, "https://polygon-mumbai.infura.io/v3/" + projectID 101 | ), 102 | network_id: 80001, 103 | confirmations: 2, 104 | timeoutBlocks: 200, 105 | skipDryRun: true, 106 | chainId: 80001 107 | } 108 | }, 109 | 110 | compilers: { 111 | solc: { 112 | version: "0.8.14", // change this to download new compiler, cool! 113 | settings: { 114 | optimizer: { 115 | enabled: true, 116 | runs: 1000, 117 | details: { 118 | // Removes duplicate code blocks 119 | deduplicate: true, 120 | 121 | // Common subexpression elimination, this is the most complicated step but 122 | // can also provide the largest gain. 123 | cse: true, 124 | 125 | // Optimize representation of literal numbers and strings in code. 126 | constantOptimizer: true, 127 | 128 | // The new Yul optimizer. Mostly operates on the code of ABI coder v2 129 | // and inline assembly. 130 | // It is activated together with the global optimizer setting 131 | // and can be deactivated here. 132 | // Before Solidity 0.6.0 it had to be activated through this switch. 133 | "yul": true, 134 | 135 | // Tuning options for the Yul optimizer. 136 | "yulDetails": { 137 | // Improve allocation of stack slots for variables, can free up stack slots early. 138 | // Activated by default if the Yul optimizer is activated. 139 | "stackAllocation": true 140 | // Select optimization steps to be applied. 141 | // Optional, the optimizer will use the default sequence if omitted. 142 | // "optimizerSteps": "dhfoDgvulfnTUtnIf..." 143 | } 144 | } 145 | }, 146 | // Version of the EVM to compile for. 147 | // Affects type checking and code generation. Can be homestead, 148 | // tangerineWhistle, spuriousDragon, byzantium, constantinople, petersburg, istanbul or berlin 149 | evmVersion: "london", 150 | 151 | // Optional: Change compilation pipeline to go through the Yul intermediate representation. 152 | // This is a highly EXPERIMENTAL feature, not to be used for production. This is false by default. 153 | // "viaIR": true, 154 | 155 | debug: { 156 | // How to treat revert (and require) reason strings. Settings are 157 | // "default", "strip", "debug" and "verboseDebug". 158 | // "default" does not inject compiler-generated revert strings and keeps user-supplied ones. 159 | // "strip" removes all revert strings (if possible, i.e. if literals are used) keeping side-effects 160 | // "debug" injects strings for compiler-generated internal reverts, implemented for ABI encoders V1 and V2 for now. 161 | // "verboseDebug" even appends further information to user-supplied revert strings (not yet implemented) 162 | revertStrings: "default", 163 | // Optional: How much extra debug information to include in comments in the produced EVM 164 | // assembly and Yul code. Available components are: 165 | // - `location`: Annotations of the form `@src ::` indicating the 166 | // location of the corresponding element in the original Solidity file, where: 167 | // - `` is the file index matching the `@use-src` annotation, 168 | // - `` is the index of the first byte at that location, 169 | // - `` is the index of the first byte after that location. 170 | // - `snippet`: A single-line code snippet from the location indicated by `@src`. 171 | // The snippet is quoted and follows the corresponding `@src` annotation. 172 | // - `*`: Wildcard value that can be used to request everything. 173 | debugInfo: ["location", "snippet"] 174 | }, 175 | } 176 | } 177 | }, 178 | 179 | plugins: [ 180 | 'truffle-contract-size', 181 | 'truffle-plugin-verify' 182 | ], 183 | api_keys: { 184 | etherscan: '4X9YYVYZE94IP4U52RYB37AK3B8ZQN146B', 185 | polygonscan: '4X9YYVYZE94IP4U52RYB37AK3B8ZQN146B' 186 | } 187 | }; 188 | -------------------------------------------------------------------------------- /docs/IERC721Upgradeable.md: -------------------------------------------------------------------------------- 1 | # IERC721Upgradeable.sol 2 | 3 | View Source: [@openzeppelin\contracts-upgradeable\token\ERC721\IERC721Upgradeable.sol](..\@openzeppelin\contracts-upgradeable\token\ERC721\IERC721Upgradeable.sol) 4 | 5 | **↗ Extends: [IERC165Upgradeable](IERC165Upgradeable.md)** 6 | **↘ Derived Contracts: [ERC721Upgradeable](ERC721Upgradeable.md), [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md), [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md)** 7 | 8 | **IERC721Upgradeable** 9 | 10 | Required interface of an ERC721 compliant contract. 11 | 12 | **Events** 13 | 14 | ```js 15 | event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); 16 | event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); 17 | event ApprovalForAll(address indexed owner, address indexed operator, bool approved); 18 | ``` 19 | 20 | ## Functions 21 | 22 | - [balanceOf(address owner)](#balanceof) 23 | - [ownerOf(uint256 tokenId)](#ownerof) 24 | - [safeTransferFrom(address from, address to, uint256 tokenId, bytes data)](#safetransferfrom) 25 | - [safeTransferFrom(address from, address to, uint256 tokenId)](#safetransferfrom) 26 | - [transferFrom(address from, address to, uint256 tokenId)](#transferfrom) 27 | - [approve(address to, uint256 tokenId)](#approve) 28 | - [setApprovalForAll(address operator, bool _approved)](#setapprovalforall) 29 | - [getApproved(uint256 tokenId)](#getapproved) 30 | - [isApprovedForAll(address owner, address operator)](#isapprovedforall) 31 | 32 | ### balanceOf 33 | 34 | Returns the number of tokens in ``owner``'s account. 35 | 36 | ```js 37 | function balanceOf(address owner) external view 38 | returns(balance uint256) 39 | ``` 40 | 41 | **Arguments** 42 | 43 | | Name | Type | Description | 44 | | ------------- |------------- | -----| 45 | | owner | address | | 46 | 47 | ### ownerOf 48 | 49 | Returns the owner of the `tokenId` token. 50 | Requirements: 51 | - `tokenId` must exist. 52 | 53 | ```js 54 | function ownerOf(uint256 tokenId) external view 55 | returns(owner address) 56 | ``` 57 | 58 | **Arguments** 59 | 60 | | Name | Type | Description | 61 | | ------------- |------------- | -----| 62 | | tokenId | uint256 | | 63 | 64 | ### safeTransferFrom 65 | 66 | Safely transfers `tokenId` token from `from` to `to`. 67 | Requirements: 68 | - `from` cannot be the zero address. 69 | - `to` cannot be the zero address. 70 | - `tokenId` token must exist and be owned by `from`. 71 | - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. 72 | - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. 73 | Emits a {Transfer} event. 74 | 75 | ```js 76 | function safeTransferFrom(address from, address to, uint256 tokenId, bytes data) external nonpayable 77 | ``` 78 | 79 | **Arguments** 80 | 81 | | Name | Type | Description | 82 | | ------------- |------------- | -----| 83 | | from | address | | 84 | | to | address | | 85 | | tokenId | uint256 | | 86 | | data | bytes | | 87 | 88 | ### safeTransferFrom 89 | 90 | Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients 91 | are aware of the ERC721 protocol to prevent tokens from being forever locked. 92 | Requirements: 93 | - `from` cannot be the zero address. 94 | - `to` cannot be the zero address. 95 | - `tokenId` token must exist and be owned by `from`. 96 | - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. 97 | - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. 98 | Emits a {Transfer} event. 99 | 100 | ```js 101 | function safeTransferFrom(address from, address to, uint256 tokenId) external nonpayable 102 | ``` 103 | 104 | **Arguments** 105 | 106 | | Name | Type | Description | 107 | | ------------- |------------- | -----| 108 | | from | address | | 109 | | to | address | | 110 | | tokenId | uint256 | | 111 | 112 | ### transferFrom 113 | 114 | Transfers `tokenId` token from `from` to `to`. 115 | WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. 116 | Requirements: 117 | - `from` cannot be the zero address. 118 | - `to` cannot be the zero address. 119 | - `tokenId` token must be owned by `from`. 120 | - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. 121 | Emits a {Transfer} event. 122 | 123 | ```js 124 | function transferFrom(address from, address to, uint256 tokenId) external nonpayable 125 | ``` 126 | 127 | **Arguments** 128 | 129 | | Name | Type | Description | 130 | | ------------- |------------- | -----| 131 | | from | address | | 132 | | to | address | | 133 | | tokenId | uint256 | | 134 | 135 | ### approve 136 | 137 | Gives permission to `to` to transfer `tokenId` token to another account. 138 | The approval is cleared when the token is transferred. 139 | Only a single account can be approved at a time, so approving the zero address clears previous approvals. 140 | Requirements: 141 | - The caller must own the token or be an approved operator. 142 | - `tokenId` must exist. 143 | Emits an {Approval} event. 144 | 145 | ```js 146 | function approve(address to, uint256 tokenId) external nonpayable 147 | ``` 148 | 149 | **Arguments** 150 | 151 | | Name | Type | Description | 152 | | ------------- |------------- | -----| 153 | | to | address | | 154 | | tokenId | uint256 | | 155 | 156 | ### setApprovalForAll 157 | 158 | Approve or remove `operator` as an operator for the caller. 159 | Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. 160 | Requirements: 161 | - The `operator` cannot be the caller. 162 | Emits an {ApprovalForAll} event. 163 | 164 | ```js 165 | function setApprovalForAll(address operator, bool _approved) external nonpayable 166 | ``` 167 | 168 | **Arguments** 169 | 170 | | Name | Type | Description | 171 | | ------------- |------------- | -----| 172 | | operator | address | | 173 | | _approved | bool | | 174 | 175 | ### getApproved 176 | 177 | Returns the account approved for `tokenId` token. 178 | Requirements: 179 | - `tokenId` must exist. 180 | 181 | ```js 182 | function getApproved(uint256 tokenId) external view 183 | returns(operator address) 184 | ``` 185 | 186 | **Arguments** 187 | 188 | | Name | Type | Description | 189 | | ------------- |------------- | -----| 190 | | tokenId | uint256 | | 191 | 192 | ### isApprovedForAll 193 | 194 | Returns if the `operator` is allowed to manage all of the assets of `owner`. 195 | See {setApprovalForAll} 196 | 197 | ```js 198 | function isApprovedForAll(address owner, address operator) external view 199 | returns(bool) 200 | ``` 201 | 202 | **Arguments** 203 | 204 | | Name | Type | Description | 205 | | ------------- |------------- | -----| 206 | | owner | address | | 207 | | operator | address | | 208 | 209 | ## Contracts 210 | 211 | * [ActivateToken](ActivateToken.md) 212 | * [AddressUpgradeable](AddressUpgradeable.md) 213 | * [ContextUpgradeable](ContextUpgradeable.md) 214 | * [CreatorToken](CreatorToken.md) 215 | * [CustomToken](CustomToken.md) 216 | * [ERC165Upgradeable](ERC165Upgradeable.md) 217 | * [ERC20Upgradeable](ERC20Upgradeable.md) 218 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 219 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 220 | * [ERC721Upgradeable](ERC721Upgradeable.md) 221 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 222 | * [IERC165Upgradeable](IERC165Upgradeable.md) 223 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 224 | * [IERC20Upgradeable](IERC20Upgradeable.md) 225 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 226 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 227 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 228 | * [IERC721Upgradeable](IERC721Upgradeable.md) 229 | * [ImmutableEntity](ImmutableEntity.md) 230 | * [ImmutableProduct](ImmutableProduct.md) 231 | * [Initializable](Initializable.md) 232 | * [Migrations](Migrations.md) 233 | * [OwnableUpgradeable](OwnableUpgradeable.md) 234 | * [ProductActivate](ProductActivate.md) 235 | * [StringCommon](StringCommon.md) 236 | * [StringsUpgradeable](StringsUpgradeable.md) 237 | -------------------------------------------------------------------------------- /docs/ERC721EnumerableUpgradeable.md: -------------------------------------------------------------------------------- 1 | # ERC721EnumerableUpgradeable.sol 2 | 3 | View Source: [@openzeppelin\contracts-upgradeable\token\ERC721\extensions\ERC721EnumerableUpgradeable.sol](..\@openzeppelin\contracts-upgradeable\token\ERC721\extensions\ERC721EnumerableUpgradeable.sol) 4 | 5 | **↗ Extends: [Initializable](Initializable.md), [ERC721Upgradeable](ERC721Upgradeable.md), [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md)** 6 | **↘ Derived Contracts: [ActivateToken](ActivateToken.md), [CreatorToken](CreatorToken.md)** 7 | 8 | **ERC721EnumerableUpgradeable** 9 | 10 | This implements an optional extension of {ERC721} defined in the EIP that adds 11 | enumerability of all the token ids in the contract as well as all token ids owned by each 12 | account. 13 | 14 | ## Contract Members 15 | **Constants & Variables** 16 | 17 | ```js 18 | mapping(address => mapping(uint256 => uint256)) private _ownedTokens; 19 | mapping(uint256 => uint256) private _ownedTokensIndex; 20 | uint256[] private _allTokens; 21 | mapping(uint256 => uint256) private _allTokensIndex; 22 | uint256[46] private __gap; 23 | 24 | ``` 25 | 26 | ## Functions 27 | 28 | - [__ERC721Enumerable_init()](#__erc721enumerable_init) 29 | - [__ERC721Enumerable_init_unchained()](#__erc721enumerable_init_unchained) 30 | - [supportsInterface(bytes4 interfaceId)](#supportsinterface) 31 | - [tokenOfOwnerByIndex(address owner, uint256 index)](#tokenofownerbyindex) 32 | - [totalSupply()](#totalsupply) 33 | - [tokenByIndex(uint256 index)](#tokenbyindex) 34 | - [_beforeTokenTransfer(address from, address to, uint256 tokenId)](#_beforetokentransfer) 35 | - [_addTokenToOwnerEnumeration(address to, uint256 tokenId)](#_addtokentoownerenumeration) 36 | - [_addTokenToAllTokensEnumeration(uint256 tokenId)](#_addtokentoalltokensenumeration) 37 | - [_removeTokenFromOwnerEnumeration(address from, uint256 tokenId)](#_removetokenfromownerenumeration) 38 | - [_removeTokenFromAllTokensEnumeration(uint256 tokenId)](#_removetokenfromalltokensenumeration) 39 | 40 | ### __ERC721Enumerable_init 41 | 42 | ```js 43 | function __ERC721Enumerable_init() internal nonpayable onlyInitializing 44 | ``` 45 | 46 | **Arguments** 47 | 48 | | Name | Type | Description | 49 | | ------------- |------------- | -----| 50 | 51 | ### __ERC721Enumerable_init_unchained 52 | 53 | ```js 54 | function __ERC721Enumerable_init_unchained() internal nonpayable onlyInitializing 55 | ``` 56 | 57 | **Arguments** 58 | 59 | | Name | Type | Description | 60 | | ------------- |------------- | -----| 61 | 62 | ### supportsInterface 63 | 64 | See {IERC165-supportsInterface}. 65 | 66 | ```js 67 | function supportsInterface(bytes4 interfaceId) public view 68 | returns(bool) 69 | ``` 70 | 71 | **Arguments** 72 | 73 | | Name | Type | Description | 74 | | ------------- |------------- | -----| 75 | | interfaceId | bytes4 | | 76 | 77 | ### tokenOfOwnerByIndex 78 | 79 | See {IERC721Enumerable-tokenOfOwnerByIndex}. 80 | 81 | ```js 82 | function tokenOfOwnerByIndex(address owner, uint256 index) public view 83 | returns(uint256) 84 | ``` 85 | 86 | **Arguments** 87 | 88 | | Name | Type | Description | 89 | | ------------- |------------- | -----| 90 | | owner | address | | 91 | | index | uint256 | | 92 | 93 | ### totalSupply 94 | 95 | See {IERC721Enumerable-totalSupply}. 96 | 97 | ```js 98 | function totalSupply() public view 99 | returns(uint256) 100 | ``` 101 | 102 | **Arguments** 103 | 104 | | Name | Type | Description | 105 | | ------------- |------------- | -----| 106 | 107 | ### tokenByIndex 108 | 109 | See {IERC721Enumerable-tokenByIndex}. 110 | 111 | ```js 112 | function tokenByIndex(uint256 index) public view 113 | returns(uint256) 114 | ``` 115 | 116 | **Arguments** 117 | 118 | | Name | Type | Description | 119 | | ------------- |------------- | -----| 120 | | index | uint256 | | 121 | 122 | ### _beforeTokenTransfer 123 | 124 | Hook that is called before any token transfer. This includes minting 125 | and burning. 126 | Calling conditions: 127 | - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be 128 | transferred to `to`. 129 | - When `from` is zero, `tokenId` will be minted for `to`. 130 | - When `to` is zero, ``from``'s `tokenId` will be burned. 131 | - `from` cannot be the zero address. 132 | - `to` cannot be the zero address. 133 | To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 134 | 135 | ```js 136 | function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal nonpayable 137 | ``` 138 | 139 | **Arguments** 140 | 141 | | Name | Type | Description | 142 | | ------------- |------------- | -----| 143 | | from | address | | 144 | | to | address | | 145 | | tokenId | uint256 | | 146 | 147 | ### _addTokenToOwnerEnumeration 148 | 149 | Private function to add a token to this extension's ownership-tracking data structures. 150 | 151 | ```js 152 | function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private nonpayable 153 | ``` 154 | 155 | **Arguments** 156 | 157 | | Name | Type | Description | 158 | | ------------- |------------- | -----| 159 | | to | address | address representing the new owner of the given token ID | 160 | | tokenId | uint256 | uint256 ID of the token to be added to the tokens list of the given address | 161 | 162 | ### _addTokenToAllTokensEnumeration 163 | 164 | Private function to add a token to this extension's token tracking data structures. 165 | 166 | ```js 167 | function _addTokenToAllTokensEnumeration(uint256 tokenId) private nonpayable 168 | ``` 169 | 170 | **Arguments** 171 | 172 | | Name | Type | Description | 173 | | ------------- |------------- | -----| 174 | | tokenId | uint256 | uint256 ID of the token to be added to the tokens list | 175 | 176 | ### _removeTokenFromOwnerEnumeration 177 | 178 | Private function to remove a token from this extension's ownership-tracking data structures. Note that 179 | while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for 180 | gas optimizations e.g. when performing a transfer operation (avoiding double writes). 181 | This has O(1) time complexity, but alters the order of the _ownedTokens array. 182 | 183 | ```js 184 | function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private nonpayable 185 | ``` 186 | 187 | **Arguments** 188 | 189 | | Name | Type | Description | 190 | | ------------- |------------- | -----| 191 | | from | address | address representing the previous owner of the given token ID | 192 | | tokenId | uint256 | uint256 ID of the token to be removed from the tokens list of the given address | 193 | 194 | ### _removeTokenFromAllTokensEnumeration 195 | 196 | Private function to remove a token from this extension's token tracking data structures. 197 | This has O(1) time complexity, but alters the order of the _allTokens array. 198 | 199 | ```js 200 | function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private nonpayable 201 | ``` 202 | 203 | **Arguments** 204 | 205 | | Name | Type | Description | 206 | | ------------- |------------- | -----| 207 | | tokenId | uint256 | uint256 ID of the token to be removed from the tokens list | 208 | 209 | ## Contracts 210 | 211 | * [ActivateToken](ActivateToken.md) 212 | * [AddressUpgradeable](AddressUpgradeable.md) 213 | * [ContextUpgradeable](ContextUpgradeable.md) 214 | * [CreatorToken](CreatorToken.md) 215 | * [CustomToken](CustomToken.md) 216 | * [ERC165Upgradeable](ERC165Upgradeable.md) 217 | * [ERC20Upgradeable](ERC20Upgradeable.md) 218 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 219 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 220 | * [ERC721Upgradeable](ERC721Upgradeable.md) 221 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 222 | * [IERC165Upgradeable](IERC165Upgradeable.md) 223 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 224 | * [IERC20Upgradeable](IERC20Upgradeable.md) 225 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 226 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 227 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 228 | * [IERC721Upgradeable](IERC721Upgradeable.md) 229 | * [ImmutableEntity](ImmutableEntity.md) 230 | * [ImmutableProduct](ImmutableProduct.md) 231 | * [Initializable](Initializable.md) 232 | * [Migrations](Migrations.md) 233 | * [OwnableUpgradeable](OwnableUpgradeable.md) 234 | * [ProductActivate](ProductActivate.md) 235 | * [StringCommon](StringCommon.md) 236 | * [StringsUpgradeable](StringsUpgradeable.md) 237 | -------------------------------------------------------------------------------- /docs/ProductActivate.md: -------------------------------------------------------------------------------- 1 | # ProductActivate.sol 2 | 3 | View Source: [\contracts\ProductActivate.sol](..\contracts\ProductActivate.sol) 4 | 5 | **↗ Extends: [Initializable](Initializable.md), [OwnableUpgradeable](OwnableUpgradeable.md)** 6 | 7 | **ProductActivate** 8 | 9 | ## Structs 10 | ### ActivationOffer 11 | 12 | ```js 13 | struct ActivationOffer { 14 | uint256 priceInTokens, 15 | uint256 value, 16 | address erc20token, 17 | string infoUrl, 18 | uint256 transferSurcharge, 19 | uint256 ricardianParent 20 | } 21 | ``` 22 | 23 | ## Contract Members 24 | **Constants & Variables** 25 | 26 | ```js 27 | mapping(uint256 => uint256) private TokenIdToOfferPrice; 28 | mapping(uint256 => uint256) private TransferSurcharge; 29 | contract ActivateToken private activateTokenInterface; 30 | contract CreatorToken private creatorTokenInterface; 31 | contract ImmutableEntity private entityInterface; 32 | contract ImmutableProduct private productInterface; 33 | contract StringCommon private commonInterface; 34 | 35 | ``` 36 | 37 | ## Functions 38 | 39 | - [initialize(address commonAddr, address entityContractAddr, address productContractAddr, address activateTokenAddr, address creatorTokenAddr)](#initialize) 40 | - [activateCreate(uint256 productIndex, uint256 licenseHash, uint256 licenseValue, uint256 transferSurcharge, uint256 ricardianParent)](#activatecreate) 41 | - [activatePurchase(uint256 entityIndex, uint256 productIndex, uint256 offerIndex, uint16 numPurchases, uint256[] licenseHashes, uint256[] ricardianClients)](#activatepurchase) 42 | - [activateMove(uint256 entityIndex, uint256 productIndex, uint256 oldLicenseHash, uint256 newLicenseHash)](#activatemove) 43 | - [activateOfferResale(uint256 entityIndex, uint256 productIndex, uint256 licenseHash, uint256 priceInEth)](#activateofferresale) 44 | - [activateTransfer(uint256 entityIndex, uint256 productIndex, uint256 licenseHash, uint256 newLicenseHash)](#activatetransfer) 45 | - [activateTokenIdToOfferPrice(uint256 tokenId)](#activatetokenidtoofferprice) 46 | 47 | ### initialize 48 | 49 | Initialize the ProductActivate smart contract 50 | Called during first deployment only (not on upgrade) as 51 | this is an OpenZepellin upgradable contract 52 | 53 | ```js 54 | function initialize(address commonAddr, address entityContractAddr, address productContractAddr, address activateTokenAddr, address creatorTokenAddr) public nonpayable initializer 55 | ``` 56 | 57 | **Arguments** 58 | 59 | | Name | Type | Description | 60 | | ------------- |------------- | -----| 61 | | commonAddr | address | The StringCommon contract address | 62 | | entityContractAddr | address | The ImmutableEntity token contract address | 63 | | productContractAddr | address | The ImmutableProduct token contract address | 64 | | activateTokenAddr | address | The ActivateToken token contract address | 65 | | creatorTokenAddr | address | The CreatorToken token contract address | 66 | 67 | ### activateCreate 68 | 69 | Create manual product activation license for end user. 70 | mes.sender must own the entity and product. 71 | Costs 1 IuT token if sender not registered as automatic 72 | 73 | ```js 74 | function activateCreate(uint256 productIndex, uint256 licenseHash, uint256 licenseValue, uint256 transferSurcharge, uint256 ricardianParent) external nonpayable 75 | ``` 76 | 77 | **Arguments** 78 | 79 | | Name | Type | Description | 80 | | ------------- |------------- | -----| 81 | | productIndex | uint256 | The specific ID of the product | 82 | | licenseHash | uint256 | the activation license hash from end user | 83 | | licenseValue | uint256 | the value of the license | 84 | | transferSurcharge | uint256 | the additional cost/surcharge to transfer | 85 | | ricardianParent | uint256 | The Ricardian contract parent (if any) | 86 | 87 | ### activatePurchase 88 | 89 | Purchase a digital product activation license. 90 | mes.sender is the purchaser. 91 | 92 | ```js 93 | function activatePurchase(uint256 entityIndex, uint256 productIndex, uint256 offerIndex, uint16 numPurchases, uint256[] licenseHashes, uint256[] ricardianClients) external payable 94 | ``` 95 | 96 | **Arguments** 97 | 98 | | Name | Type | Description | 99 | | ------------- |------------- | -----| 100 | | entityIndex | uint256 | The entity offering the product license | 101 | | productIndex | uint256 | The specific ID of the product | 102 | | offerIndex | uint256 | the product activation offer to purchase | 103 | | numPurchases | uint16 | the number of offers to purchase | 104 | | licenseHashes | uint256[] | Array of end user identifiers to activate | 105 | | ricardianClients | uint256[] | Array of end client agreement contracts | 106 | 107 | ### activateMove 108 | 109 | Move a digital product activation license. 110 | mes.sender must be the activation license owner. 111 | 112 | ```js 113 | function activateMove(uint256 entityIndex, uint256 productIndex, uint256 oldLicenseHash, uint256 newLicenseHash) external nonpayable 114 | ``` 115 | 116 | **Arguments** 117 | 118 | | Name | Type | Description | 119 | | ------------- |------------- | -----| 120 | | entityIndex | uint256 | The entity who owns the product | 121 | | productIndex | uint256 | The specific ID of the product | 122 | | oldLicenseHash | uint256 | the existing activation identifier | 123 | | newLicenseHash | uint256 | the new activation identifier | 124 | 125 | ### activateOfferResale 126 | 127 | Offer a digital product license for resale. 128 | mes.sender must own the activation license. 129 | 130 | ```js 131 | function activateOfferResale(uint256 entityIndex, uint256 productIndex, uint256 licenseHash, uint256 priceInEth) external nonpayable 132 | returns(uint256) 133 | ``` 134 | 135 | **Returns** 136 | 137 | the tokenId of the activation offered for resale 138 | 139 | **Arguments** 140 | 141 | | Name | Type | Description | 142 | | ------------- |------------- | -----| 143 | | entityIndex | uint256 | The entity who owns the product | 144 | | productIndex | uint256 | The specific ID of the product | 145 | | licenseHash | uint256 | the existing activation identifier | 146 | | priceInEth | uint256 | The ETH cost to purchase license | 147 | 148 | ### activateTransfer 149 | 150 | Transfer/Resell a digital product activation license. 151 | License must be 'for sale' and msg.sender is new owner. 152 | 153 | ```js 154 | function activateTransfer(uint256 entityIndex, uint256 productIndex, uint256 licenseHash, uint256 newLicenseHash) external payable 155 | ``` 156 | 157 | **Arguments** 158 | 159 | | Name | Type | Description | 160 | | ------------- |------------- | -----| 161 | | entityIndex | uint256 | The entity who owns the product | 162 | | productIndex | uint256 | The specific ID of the product | 163 | | licenseHash | uint256 | the existing activation identifier to purchase | 164 | | newLicenseHash | uint256 | the new activation identifier after purchase | 165 | 166 | ### activateTokenIdToOfferPrice 167 | 168 | Query activate token offer price 169 | 170 | ```js 171 | function activateTokenIdToOfferPrice(uint256 tokenId) external view 172 | returns(uint256) 173 | ``` 174 | 175 | **Returns** 176 | 177 | The price of the token if for sale 178 | 179 | **Arguments** 180 | 181 | | Name | Type | Description | 182 | | ------------- |------------- | -----| 183 | | tokenId | uint256 | The activate token identifier | 184 | 185 | ## Contracts 186 | 187 | * [ActivateToken](ActivateToken.md) 188 | * [AddressUpgradeable](AddressUpgradeable.md) 189 | * [ContextUpgradeable](ContextUpgradeable.md) 190 | * [CreatorToken](CreatorToken.md) 191 | * [CustomToken](CustomToken.md) 192 | * [ERC165Upgradeable](ERC165Upgradeable.md) 193 | * [ERC20Upgradeable](ERC20Upgradeable.md) 194 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 195 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 196 | * [ERC721Upgradeable](ERC721Upgradeable.md) 197 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 198 | * [IERC165Upgradeable](IERC165Upgradeable.md) 199 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 200 | * [IERC20Upgradeable](IERC20Upgradeable.md) 201 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 202 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 203 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 204 | * [IERC721Upgradeable](IERC721Upgradeable.md) 205 | * [ImmutableEntity](ImmutableEntity.md) 206 | * [ImmutableProduct](ImmutableProduct.md) 207 | * [Initializable](Initializable.md) 208 | * [Migrations](Migrations.md) 209 | * [OwnableUpgradeable](OwnableUpgradeable.md) 210 | * [ProductActivate](ProductActivate.md) 211 | * [StringCommon](StringCommon.md) 212 | * [StringsUpgradeable](StringsUpgradeable.md) 213 | -------------------------------------------------------------------------------- /docs/AddressUpgradeable.md: -------------------------------------------------------------------------------- 1 | # AddressUpgradeable.sol 2 | 3 | View Source: [@openzeppelin\contracts-upgradeable\utils\AddressUpgradeable.sol](..\@openzeppelin\contracts-upgradeable\utils\AddressUpgradeable.sol) 4 | 5 | **AddressUpgradeable** 6 | 7 | Collection of functions related to the address type 8 | 9 | ## Functions 10 | 11 | - [isContract(address account)](#iscontract) 12 | - [sendValue(address payable recipient, uint256 amount)](#sendvalue) 13 | - [functionCall(address target, bytes data)](#functioncall) 14 | - [functionCall(address target, bytes data, string errorMessage)](#functioncall) 15 | - [functionCallWithValue(address target, bytes data, uint256 value)](#functioncallwithvalue) 16 | - [functionCallWithValue(address target, bytes data, uint256 value, string errorMessage)](#functioncallwithvalue) 17 | - [functionStaticCall(address target, bytes data)](#functionstaticcall) 18 | - [functionStaticCall(address target, bytes data, string errorMessage)](#functionstaticcall) 19 | - [verifyCallResult(bool success, bytes returndata, string errorMessage)](#verifycallresult) 20 | 21 | ### isContract 22 | 23 | Returns true if `account` is a contract. 24 | [IMPORTANT] 25 | ==== 26 | It is unsafe to assume that an address for which this function returns 27 | false is an externally-owned account (EOA) and not a contract. 28 | Among others, `isContract` will return false for the following 29 | types of addresses: 30 | - an externally-owned account 31 | - a contract in construction 32 | - an address where a contract will be created 33 | - an address where a contract lived, but was destroyed 34 | ==== 35 | [IMPORTANT] 36 | ==== 37 | You shouldn't rely on `isContract` to protect against flash loan attacks! 38 | Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets 39 | like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract 40 | constructor. 41 | ==== 42 | 43 | ```js 44 | function isContract(address account) internal view 45 | returns(bool) 46 | ``` 47 | 48 | **Arguments** 49 | 50 | | Name | Type | Description | 51 | | ------------- |------------- | -----| 52 | | account | address | | 53 | 54 | ### sendValue 55 | 56 | Replacement for Solidity's `transfer`: sends `amount` wei to 57 | `recipient`, forwarding all available gas and reverting on errors. 58 | https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 59 | of certain opcodes, possibly making contracts go over the 2300 gas limit 60 | imposed by `transfer`, making them unable to receive funds via 61 | `transfer`. {sendValue} removes this limitation. 62 | https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 63 | IMPORTANT: because control is transferred to `recipient`, care must be 64 | taken to not create reentrancy vulnerabilities. Consider using 65 | {ReentrancyGuard} or the 66 | https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 67 | 68 | ```js 69 | function sendValue(address payable recipient, uint256 amount) internal nonpayable 70 | ``` 71 | 72 | **Arguments** 73 | 74 | | Name | Type | Description | 75 | | ------------- |------------- | -----| 76 | | recipient | address payable | | 77 | | amount | uint256 | | 78 | 79 | ### functionCall 80 | 81 | Performs a Solidity function call using a low level `call`. A 82 | plain `call` is an unsafe replacement for a function call: use this 83 | function instead. 84 | If `target` reverts with a revert reason, it is bubbled up by this 85 | function (like regular Solidity function calls). 86 | Returns the raw returned data. To convert to the expected return value, 87 | use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. 88 | Requirements: 89 | - `target` must be a contract. 90 | - calling `target` with `data` must not revert. 91 | _Available since v3.1._ 92 | 93 | ```js 94 | function functionCall(address target, bytes data) internal nonpayable 95 | returns(bytes) 96 | ``` 97 | 98 | **Arguments** 99 | 100 | | Name | Type | Description | 101 | | ------------- |------------- | -----| 102 | | target | address | | 103 | | data | bytes | | 104 | 105 | ### functionCall 106 | 107 | Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with 108 | `errorMessage` as a fallback revert reason when `target` reverts. 109 | _Available since v3.1._ 110 | 111 | ```js 112 | function functionCall(address target, bytes data, string errorMessage) internal nonpayable 113 | returns(bytes) 114 | ``` 115 | 116 | **Arguments** 117 | 118 | | Name | Type | Description | 119 | | ------------- |------------- | -----| 120 | | target | address | | 121 | | data | bytes | | 122 | | errorMessage | string | | 123 | 124 | ### functionCallWithValue 125 | 126 | Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 127 | but also transferring `value` wei to `target`. 128 | Requirements: 129 | - the calling contract must have an ETH balance of at least `value`. 130 | - the called Solidity function must be `payable`. 131 | _Available since v3.1._ 132 | 133 | ```js 134 | function functionCallWithValue(address target, bytes data, uint256 value) internal nonpayable 135 | returns(bytes) 136 | ``` 137 | 138 | **Arguments** 139 | 140 | | Name | Type | Description | 141 | | ------------- |------------- | -----| 142 | | target | address | | 143 | | data | bytes | | 144 | | value | uint256 | | 145 | 146 | ### functionCallWithValue 147 | 148 | Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but 149 | with `errorMessage` as a fallback revert reason when `target` reverts. 150 | _Available since v3.1._ 151 | 152 | ```js 153 | function functionCallWithValue(address target, bytes data, uint256 value, string errorMessage) internal nonpayable 154 | returns(bytes) 155 | ``` 156 | 157 | **Arguments** 158 | 159 | | Name | Type | Description | 160 | | ------------- |------------- | -----| 161 | | target | address | | 162 | | data | bytes | | 163 | | value | uint256 | | 164 | | errorMessage | string | | 165 | 166 | ### functionStaticCall 167 | 168 | Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 169 | but performing a static call. 170 | _Available since v3.3._ 171 | 172 | ```js 173 | function functionStaticCall(address target, bytes data) internal view 174 | returns(bytes) 175 | ``` 176 | 177 | **Arguments** 178 | 179 | | Name | Type | Description | 180 | | ------------- |------------- | -----| 181 | | target | address | | 182 | | data | bytes | | 183 | 184 | ### functionStaticCall 185 | 186 | Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 187 | but performing a static call. 188 | _Available since v3.3._ 189 | 190 | ```js 191 | function functionStaticCall(address target, bytes data, string errorMessage) internal view 192 | returns(bytes) 193 | ``` 194 | 195 | **Arguments** 196 | 197 | | Name | Type | Description | 198 | | ------------- |------------- | -----| 199 | | target | address | | 200 | | data | bytes | | 201 | | errorMessage | string | | 202 | 203 | ### verifyCallResult 204 | 205 | Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the 206 | revert reason using the provided one. 207 | _Available since v4.3._ 208 | 209 | ```js 210 | function verifyCallResult(bool success, bytes returndata, string errorMessage) internal pure 211 | returns(bytes) 212 | ``` 213 | 214 | **Arguments** 215 | 216 | | Name | Type | Description | 217 | | ------------- |------------- | -----| 218 | | success | bool | | 219 | | returndata | bytes | | 220 | | errorMessage | string | | 221 | 222 | ## Contracts 223 | 224 | * [ActivateToken](ActivateToken.md) 225 | * [AddressUpgradeable](AddressUpgradeable.md) 226 | * [ContextUpgradeable](ContextUpgradeable.md) 227 | * [CreatorToken](CreatorToken.md) 228 | * [CustomToken](CustomToken.md) 229 | * [ERC165Upgradeable](ERC165Upgradeable.md) 230 | * [ERC20Upgradeable](ERC20Upgradeable.md) 231 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 232 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 233 | * [ERC721Upgradeable](ERC721Upgradeable.md) 234 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 235 | * [IERC165Upgradeable](IERC165Upgradeable.md) 236 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 237 | * [IERC20Upgradeable](IERC20Upgradeable.md) 238 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 239 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 240 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 241 | * [IERC721Upgradeable](IERC721Upgradeable.md) 242 | * [ImmutableEntity](ImmutableEntity.md) 243 | * [ImmutableProduct](ImmutableProduct.md) 244 | * [Initializable](Initializable.md) 245 | * [Migrations](Migrations.md) 246 | * [OwnableUpgradeable](OwnableUpgradeable.md) 247 | * [ProductActivate](ProductActivate.md) 248 | * [StringCommon](StringCommon.md) 249 | * [StringsUpgradeable](StringsUpgradeable.md) 250 | -------------------------------------------------------------------------------- /docs/ActivateToken.md: -------------------------------------------------------------------------------- 1 | # ActivateToken.sol 2 | 3 | View Source: [\contracts\ActivateToken.sol](..\contracts\ActivateToken.sol) 4 | 5 | **↗ Extends: [Initializable](Initializable.md), [OwnableUpgradeable](OwnableUpgradeable.md), [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md), [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md)** 6 | 7 | **ActivateToken** 8 | 9 | ## Contract Members 10 | **Constants & Variables** 11 | 12 | ```js 13 | mapping(uint256 => uint256) private ActivateIdToTokenId; 14 | mapping(uint256 => uint256) private TokenIdToActivateId; 15 | mapping(uint64 => uint64) private NumberOfActivations; 16 | mapping(uint256 => uint256) private TokenIdToRicardianParent; 17 | contract ProductActivate private activateInterface; 18 | contract CreatorToken private creatorInterface; 19 | contract ImmutableEntity private entityInterface; 20 | contract StringCommon private commonInterface; 21 | 22 | ``` 23 | 24 | ## Functions 25 | 26 | - [initialize(address commonContractAddr, address entityContractAddr)](#initialize) 27 | - [restrictToken(address activateAddress, address creatorAddress)](#restricttoken) 28 | - [burn(uint256 tokenId)](#burn) 29 | - [mint(address sender, uint256 entityIndex, uint256 productIndex, uint256 licenseHash, uint256 licenseValue, uint256 ricardianParent)](#mint) 30 | - [activateOwner(address newOwner)](#activateowner) 31 | - [activateTokenMoveHash(uint256 tokenId, uint256 newHash, uint256 oldHash)](#activatetokenmovehash) 32 | - [activateIdToTokenId(uint256 licenseHash)](#activateidtotokenid) 33 | - [tokenIdToActivateId(uint256 tokenId)](#tokenidtoactivateid) 34 | - [activateStatus(uint256 entityIndex, uint256 productIndex, uint256 licenseHash)](#activatestatus) 35 | - [activateAllDetailsForAddress(address entityAddress)](#activatealldetailsforaddress) 36 | - [activateAllDetails(uint256 entityIndex)](#activatealldetails) 37 | - [activateAllForSaleTokenDetails()](#activateallforsaletokendetails) 38 | - [_beforeTokenTransfer(address from, address to, uint256 tokenId)](#_beforetokentransfer) 39 | - [supportsInterface(bytes4 interfaceId)](#supportsinterface) 40 | 41 | ### initialize 42 | 43 | Initialize the activate token smart contract 44 | Called during first deployment only (not on upgrade) as 45 | this is an OpenZepellin upgradable contract 46 | 47 | ```js 48 | function initialize(address commonContractAddr, address entityContractAddr) public nonpayable initializer 49 | ``` 50 | 51 | **Arguments** 52 | 53 | | Name | Type | Description | 54 | | ------------- |------------- | -----| 55 | | commonContractAddr | address | The StringCommon contract address | 56 | | entityContractAddr | address | The ImmutableEntity token contract address | 57 | 58 | ### restrictToken 59 | 60 | Restrict the token to the activate contract 61 | Called once after deployment to initialize Ecosystem. 62 | msg.sender must be contract owner 63 | 64 | ```js 65 | function restrictToken(address activateAddress, address creatorAddress) public nonpayable onlyOwner 66 | ``` 67 | 68 | **Arguments** 69 | 70 | | Name | Type | Description | 71 | | ------------- |------------- | -----| 72 | | activateAddress | address | The ProductActivate contract address | 73 | | creatorAddress | address | The Creator token contract address | 74 | 75 | ### burn 76 | 77 | Burn a product activation license. 78 | Not public, called internally. msg.sender must be the token owner. 79 | 80 | ```js 81 | function burn(uint256 tokenId) public nonpayable 82 | ``` 83 | 84 | **Arguments** 85 | 86 | | Name | Type | Description | 87 | | ------------- |------------- | -----| 88 | | tokenId | uint256 | The tokenId to burn | 89 | 90 | ### mint 91 | 92 | Create a product activation license. 93 | Public but internal. msg.sender must be product activate contract 94 | 95 | ```js 96 | function mint(address sender, uint256 entityIndex, uint256 productIndex, uint256 licenseHash, uint256 licenseValue, uint256 ricardianParent) public nonpayable 97 | returns(uint256) 98 | ``` 99 | 100 | **Returns** 101 | 102 | tokenId The resulting new unique token identifier 103 | 104 | **Arguments** 105 | 106 | | Name | Type | Description | 107 | | ------------- |------------- | -----| 108 | | sender | address | | 109 | | entityIndex | uint256 | The local entity index of the license | 110 | | productIndex | uint256 | The specific ID of the product | 111 | | licenseHash | uint256 | The external license activation hash | 112 | | licenseValue | uint256 | The activation value and flags (192 bits) | 113 | | ricardianParent | uint256 | The Ricardian contract parent (if required) | 114 | 115 | ### activateOwner 116 | 117 | Change owner for all activate tokens (activations) 118 | Not public, called internally. msg.sender is the license owner. 119 | 120 | ```js 121 | function activateOwner(address newOwner) external nonpayable 122 | ``` 123 | 124 | **Arguments** 125 | 126 | | Name | Type | Description | 127 | | ------------- |------------- | -----| 128 | | newOwner | address | The new owner to receive transfer of tokens | 129 | 130 | ### activateTokenMoveHash 131 | 132 | Change activation identifier for an activate token 133 | Caller must be the ProductActivate contract. 134 | 135 | ```js 136 | function activateTokenMoveHash(uint256 tokenId, uint256 newHash, uint256 oldHash) external nonpayable 137 | ``` 138 | 139 | **Arguments** 140 | 141 | | Name | Type | Description | 142 | | ------------- |------------- | -----| 143 | | tokenId | uint256 | The token identifier to move | 144 | | newHash | uint256 | The new activation hash/identifier | 145 | | oldHash | uint256 | The previous activation hash/identifier | 146 | 147 | ### activateIdToTokenId 148 | 149 | Find token identifier associated with activation hash 150 | 151 | ```js 152 | function activateIdToTokenId(uint256 licenseHash) external view 153 | returns(uint256) 154 | ``` 155 | 156 | **Returns** 157 | 158 | the tokenId value 159 | 160 | **Arguments** 161 | 162 | | Name | Type | Description | 163 | | ------------- |------------- | -----| 164 | | licenseHash | uint256 | the external unique identifier | 165 | 166 | ### tokenIdToActivateId 167 | 168 | Find activation hash associated with token identifier 169 | 170 | ```js 171 | function tokenIdToActivateId(uint256 tokenId) external view 172 | returns(uint256) 173 | ``` 174 | 175 | **Returns** 176 | 177 | the license hash/unique activation identifier 178 | 179 | **Arguments** 180 | 181 | | Name | Type | Description | 182 | | ------------- |------------- | -----| 183 | | tokenId | uint256 | is the unique token identifier | 184 | 185 | ### activateStatus 186 | 187 | Find end user activation value and expiration for product 188 | Entity and product must be valid. 189 | 190 | ```js 191 | function activateStatus(uint256 entityIndex, uint256 productIndex, uint256 licenseHash) external view 192 | returns(value uint256, price uint256) 193 | ``` 194 | 195 | **Returns** 196 | 197 | value (with flags) and price of the activation.\ 198 | **value** The activation value (flags, expiration, value)\ 199 | **price** The price in tokens if offered for resale 200 | 201 | **Arguments** 202 | 203 | | Name | Type | Description | 204 | | ------------- |------------- | -----| 205 | | entityIndex | uint256 | The entity the product license is for | 206 | | productIndex | uint256 | The specific ID of the product | 207 | | licenseHash | uint256 | the external unique identifier to activate | 208 | 209 | ### activateAllDetailsForAddress 210 | 211 | Find all license activation details for an address 212 | 213 | ```js 214 | function activateAllDetailsForAddress(address entityAddress) public view 215 | returns(entities uint256[], products uint256[], hashes uint256[], values uint256[], prices uint256[]) 216 | ``` 217 | 218 | **Returns** 219 | 220 | entities , products, hashes, values and prices as arrays.\ 221 | **entities** Array of entity ids of product\ 222 | **products** Array of product ids of product\ 223 | **hashes** Array of activation identifiers\ 224 | **values** Array of token values\ 225 | **prices** Array of price in tokens if for resale 226 | 227 | **Arguments** 228 | 229 | | Name | Type | Description | 230 | | ------------- |------------- | -----| 231 | | entityAddress | address | The address that owns the activations | 232 | 233 | ### activateAllDetails 234 | 235 | Find all license activation details for an entity 236 | Entity must be valid. 237 | 238 | ```js 239 | function activateAllDetails(uint256 entityIndex) external view 240 | returns(entities uint256[], products uint256[], hashes uint256[], values uint256[], prices uint256[]) 241 | ``` 242 | 243 | **Returns** 244 | 245 | entities , products, hashes, values and prices as arrays.\ 246 | **entities** Array of entity ids of product\ 247 | **products** Array of product ids of product\ 248 | **hashes** Array of activation identifiers\ 249 | **values** Array of token values (flags, expiration)\ 250 | **prices** Array of price in tokens if for resale 251 | 252 | **Arguments** 253 | 254 | | Name | Type | Description | 255 | | ------------- |------------- | -----| 256 | | entityIndex | uint256 | The entity to return activations for | 257 | 258 | ### activateAllForSaleTokenDetails 259 | 260 | Return all license activations for sale in the ecosystem 261 | When this exceeds available return size index will be added 262 | 263 | ```js 264 | function activateAllForSaleTokenDetails() external view 265 | returns(entities uint256[], products uint256[], hashes uint256[], values uint256[], prices uint256[]) 266 | ``` 267 | 268 | **Returns** 269 | 270 | entities , products, hashes, values and prices as arrays.\ 271 | **entities** Array of entity ids of product\ 272 | **products** Array of product ids of product\ 273 | **hashes** Array of activation identifiers\ 274 | **values** Array of token values (flags, expiration)\ 275 | **prices** Array of price in tokens if for resale 276 | 277 | **Arguments** 278 | 279 | | Name | Type | Description | 280 | | ------------- |------------- | -----| 281 | 282 | ### _beforeTokenTransfer 283 | 284 | Perform validity check before transfer of token allowed. 285 | Called internally before any token transfer and used to enforce 286 | resale rights and Ricardian contract agreement requirements, 287 | even when using third party exchanges. 288 | 289 | ```js 290 | function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal nonpayable 291 | ``` 292 | 293 | **Arguments** 294 | 295 | | Name | Type | Description | 296 | | ------------- |------------- | -----| 297 | | from | address | The token origin address | 298 | | to | address | The token destination address | 299 | | tokenId | uint256 | The token intended for transfer | 300 | 301 | ### supportsInterface 302 | 303 | Return the type of supported ERC interfaces 304 | 305 | ```js 306 | function supportsInterface(bytes4 interfaceId) public view 307 | returns(bool) 308 | ``` 309 | 310 | **Returns** 311 | 312 | TRUE (1) if supported, FALSE (0) otherwise 313 | 314 | **Arguments** 315 | 316 | | Name | Type | Description | 317 | | ------------- |------------- | -----| 318 | | interfaceId | bytes4 | The interface desired | 319 | 320 | ## Contracts 321 | 322 | * [ActivateToken](ActivateToken.md) 323 | * [AddressUpgradeable](AddressUpgradeable.md) 324 | * [ContextUpgradeable](ContextUpgradeable.md) 325 | * [CreatorToken](CreatorToken.md) 326 | * [CustomToken](CustomToken.md) 327 | * [ERC165Upgradeable](ERC165Upgradeable.md) 328 | * [ERC20Upgradeable](ERC20Upgradeable.md) 329 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 330 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 331 | * [ERC721Upgradeable](ERC721Upgradeable.md) 332 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 333 | * [IERC165Upgradeable](IERC165Upgradeable.md) 334 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 335 | * [IERC20Upgradeable](IERC20Upgradeable.md) 336 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 337 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 338 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 339 | * [IERC721Upgradeable](IERC721Upgradeable.md) 340 | * [ImmutableEntity](ImmutableEntity.md) 341 | * [ImmutableProduct](ImmutableProduct.md) 342 | * [Initializable](Initializable.md) 343 | * [Migrations](Migrations.md) 344 | * [OwnableUpgradeable](OwnableUpgradeable.md) 345 | * [ProductActivate](ProductActivate.md) 346 | * [StringCommon](StringCommon.md) 347 | * [StringsUpgradeable](StringsUpgradeable.md) 348 | -------------------------------------------------------------------------------- /contracts/CollectionProxy.sol: -------------------------------------------------------------------------------- 1 | // Copyright 2022 ImmutableSoft Inc. 2 | 3 | pragma solidity >=0.7.6; 4 | 5 | // SPDX-License-Identifier: GPL-3.0-or-later 6 | 7 | // OpenZepellin upgradable contracts 8 | import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; 9 | import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; 10 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol"; 11 | import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721EnumerableUpgradeable.sol"; 12 | 13 | /* 14 | // OpenZepellin standard contracts 15 | //import "@openzeppelin/contracts/proxy/utils/Initializable.sol"; 16 | import "@openzeppelin/contracts/access/Ownable.sol"; 17 | import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; 18 | import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; 19 | */ 20 | 21 | // ImmutableSoft DAO smart contracts 22 | import "./StringCommon.sol"; 23 | import "./ImmutableEntity.sol"; 24 | import "./ImmutableProduct.sol"; 25 | import "./CreatorToken.sol"; 26 | 27 | /// @title Example call proxy for NFT collection - uses CreatorToken 28 | /// @author Sean Lawless for ImmutableSoft Inc. 29 | contract CollectionProxy is Initializable, OwnableUpgradeable, 30 | IERC721MetadataUpgradeable, 31 | IERC721EnumerableUpgradeable 32 | /* 33 | contract CollectionProxy is Ownable, IERC721Metadata, IERC721Enumerable 34 | */ 35 | { 36 | string private _name; 37 | string private _symbol; 38 | uint256 private _entity; 39 | uint256 private _product; 40 | 41 | // External contract interfaces (ImmutableSoft DAO) 42 | StringCommon private commonInterface; 43 | CreatorToken private creatorToken; 44 | 45 | /// @notice Initialize the CollectionProxy smart contract 46 | /// Called during first deployment only 47 | /// @param commonAddr The StringCommon contract address 48 | /// @param creatorTokenAddr The Creator Token contract address 49 | /// @param entity The Immutable DAO entityID of collection 50 | /// @param product The Immutable DAO productID of collection 51 | /* constructor(address commonAddr, address creatorTokenAddr, 52 | uint256 entity, uint256 product) 53 | Ownable()*/ 54 | function initialize(address commonAddr, address creatorTokenAddr, 55 | address entityAddr, address productAddr, 56 | string memory collectionName, string memory theSymbol, 57 | uint256 entity, uint256 product) public initializer 58 | { 59 | __Ownable_init(); 60 | ImmutableEntity entityInterface = ImmutableEntity(entityAddr); 61 | 62 | // If not immutablesoft owner, check entity owner matches sender 63 | if (msg.sender != entityInterface.owner()) 64 | { 65 | uint256 entityStatus = entityInterface.entityAddressStatus(msg.sender); 66 | uint256 entityIndex = entityInterface.entityAddressToIndex(msg.sender); 67 | 68 | // Ensure the proxy is deployed with entity address 69 | require(entity == entityIndex, "Not authorized"); 70 | 71 | // Only a validated commercial entity can create a proxy 72 | require(entityStatus > 0, commonInterface.EntityNotValidated()); 73 | require((entityStatus & commonInterface.Nonprofit()) != 74 | commonInterface.Nonprofit(), "Nonprofit prohibited"); 75 | 76 | // Verify product and use product name as collection name 77 | string memory url; 78 | string memory logo; 79 | uint256 details; 80 | ImmutableProduct productInterface = ImmutableProduct(productAddr); 81 | (_name, url, logo, details) = productInterface.productDetails(entity, product); 82 | require(commonInterface.stringsEqual(_name, collectionName), 83 | "Product name does not match"); 84 | } 85 | else 86 | _name = collectionName; 87 | 88 | // Finalize the smart contract data 89 | _symbol = theSymbol; 90 | _entity = entity; 91 | _product = product; 92 | commonInterface = StringCommon(commonAddr); 93 | creatorToken = CreatorToken(creatorTokenAddr); 94 | } 95 | 96 | /// @notice Retrieve the token name (ie. collection name) 97 | /// @return Return the token name as a string 98 | function name() public view 99 | returns (string memory) 100 | { 101 | return _name; 102 | } 103 | 104 | /// @notice Retrieve the token symbol 105 | /// @return Return the token symbol as a string 106 | function symbol() public view 107 | returns (string memory) 108 | { 109 | return _symbol; 110 | } 111 | 112 | /// @notice Return the type of supported ERC interfaces 113 | /// @param interfaceId The interface desired 114 | /// @return TRUE (1) if supported, FALSE (0) otherwise 115 | function supportsInterface(bytes4 interfaceId) public view 116 | returns (bool) 117 | { 118 | return creatorToken.supportsInterface(interfaceId); 119 | } 120 | 121 | /// @notice Convert tokenID from this proxy to ImmutableSoft DAO 122 | /// @param tokenId The proxy identifier (only release id) 123 | /// @return The CreatorToken (ImmutableSoft) token Id 124 | function idToDAO(uint256 tokenId) 125 | public view returns (uint256) 126 | { 127 | return ((_entity << commonInterface.EntityIdOffset()) & 128 | commonInterface.EntityIdMask()) | 129 | ((_product << commonInterface.ProductIdOffset()) & 130 | commonInterface.ProductIdMask()) | 131 | ((tokenId << commonInterface.ReleaseIdOffset()) & 132 | commonInterface.ReleaseIdMask()); 133 | } 134 | 135 | /// @notice Look up the release URI from the token Id 136 | /// @param tokenId The unique token identifier 137 | /// @return the file name and/or URI secured by this token 138 | function tokenURI(uint256 tokenId) public view 139 | returns (string memory) 140 | { 141 | return creatorToken.tokenURI(idToDAO(tokenId)); 142 | } 143 | 144 | /// @notice Approve and address for token Id transfer/burn 145 | /// @param to The address to approve (smart contract, etc.) 146 | /// @param to The tokenId to approve 147 | function approve(address to, uint256 tokenId) public 148 | { 149 | return creatorToken.approve(to, idToDAO(tokenId)); 150 | } 151 | 152 | /// @notice Query approval address for token Id 153 | /// @param tokenId The token identifier 154 | /// @return operator The approved address of operator 155 | function getApproved(uint256 tokenId) public view 156 | returns (address operator) 157 | { 158 | return creatorToken.getApproved(idToDAO(tokenId)); 159 | } 160 | 161 | /// @notice Query approval address for owner 162 | /// @param owner The address of token owner 163 | /// @param operator The address of operator to check 164 | /// @return The true if approved for all tokens 165 | function isApprovedForAll(address owner, address operator) public view 166 | returns (bool) 167 | { 168 | return creatorToken.isApprovedForAll(owner, operator); 169 | } 170 | 171 | /// @notice Query owner of token 172 | /// @param tokenId The token identifier to lookup owner of 173 | /// @return owner The address of the token owner 174 | function ownerOf(uint256 tokenId) public view 175 | returns (address owner) 176 | { 177 | return creatorToken.ownerOf(idToDAO(tokenId)); 178 | } 179 | 180 | /// @notice Change approval rights for operator 181 | /// @param operator The address to token operator 182 | /// @param _approved True or false of new approval status 183 | function setApprovalForAll(address operator, bool _approved) public 184 | { 185 | return creatorToken.setApprovalForAll(operator, _approved); 186 | } 187 | 188 | /// @notice Safely transfer a token 189 | /// @param from The old token owner address 190 | /// @param to The new token owner address 191 | /// @param tokenId The token id to transfer 192 | function safeTransferFrom(address from, address to, uint256 tokenId) 193 | public 194 | { 195 | return creatorToken.safeTransferFrom(from, to, idToDAO(tokenId)); 196 | } 197 | 198 | /// @notice Safely transfer a token with data 199 | /// @param from The old token owner address 200 | /// @param to The new token owner address 201 | /// @param tokenId The token id to transfer 202 | /// @param data Additional data 203 | function safeTransferFrom(address from, address to, uint256 tokenId, 204 | bytes calldata data) 205 | public 206 | { 207 | return creatorToken.safeTransferFrom(from, to, idToDAO(tokenId), 208 | data); 209 | } 210 | 211 | /// @notice Transfer a token 212 | /// @param from The old token owner address 213 | /// @param to The new token owner address 214 | /// @param tokenId The token id to transfer 215 | function transferFrom(address from, address to, uint256 tokenId) 216 | public 217 | { 218 | return creatorToken.transferFrom(from, to, idToDAO(tokenId)); 219 | } 220 | 221 | /// @notice Find and return the number of or tokenID of 222 | /// @param owner The (optional) owner of 223 | /// @param index The (optaionl) index of 224 | /// @return The token count or ID of the lookup 225 | function _tokenOf(address owner, uint256 index) 226 | internal view returns (uint256) 227 | { 228 | uint256 currentIndex = 0; 229 | uint256 i; 230 | uint256 max =(owner != address(0)) ? 231 | creatorToken.balanceOf(owner) : 232 | creatorToken.totalSupply(); 233 | 234 | //Interate ownedTokens and count only this entity and product 235 | for (i = 0;i < max; ++i) 236 | { 237 | // Read the next token id (by owner or global) 238 | uint256 tokenId = (owner != address(0)) ? 239 | creatorToken.tokenOfOwnerByIndex(owner, i) : 240 | creatorToken.tokenByIndex(i); 241 | 242 | // Deserialize the entity and product identifiers 243 | uint256 entityIndex = ((tokenId & 244 | commonInterface.EntityIdMask()) >> 245 | commonInterface.EntityIdOffset()); 246 | uint256 productIndex = ((tokenId & 247 | commonInterface.ProductIdMask()) >> 248 | commonInterface.ProductIdOffset()); 249 | 250 | // If identifiers match this proxy, count and/or return if found 251 | if ((entityIndex == _entity) && (productIndex == _product)) 252 | { 253 | ++currentIndex; 254 | 255 | // If specific token, return just the release identifier 256 | // shifted to LSB. 257 | if ((index > 0) && (index == currentIndex)) 258 | return ((tokenId & commonInterface.ReleaseIdMask()) >> 259 | commonInterface.ReleaseIdOffset()); 260 | } 261 | } 262 | 263 | // If not a tokenId lookup then return the token count 264 | if (index == 0) 265 | return currentIndex; 266 | 267 | // Otherwise return tokenId zero (not found) 268 | else 269 | return 0; 270 | } 271 | 272 | /// @notice Return balance of owned tokens 273 | /// @dev Returns subset of ImmutableSoft DAO tokens that match 274 | /// the entity and product this proxy was initialized for. 275 | /// @param owner The old token owner address 276 | /// @return balance The number of tokens owned 277 | function balanceOf(address owner) public view 278 | returns (uint256 balance) 279 | { 280 | return _tokenOf(owner, 0); 281 | } 282 | 283 | /// @notice Return tokenId of index owned by an address 284 | /// @dev Returns subset of ImmutableSoft DAO tokens that match 285 | /// the entity and product this proxy was initialized for. 286 | /// @param owner The old token owner address 287 | /// @param index The old token index of this specific owner 288 | /// @return the tokenId of the specific token 289 | function tokenOfOwnerByIndex(address owner, uint256 index) public view 290 | returns (uint256) 291 | { 292 | return _tokenOf(owner, index); 293 | } 294 | 295 | /// @notice Return the total supply of tokens 296 | /// @dev Returns subset of ImmutableSoft DAO tokens that match 297 | /// the entity and product this proxy was initialized for. 298 | /// @return the number of tokens within this collection 299 | function totalSupply() public view 300 | returns (uint256) 301 | { 302 | return _tokenOf(address(0), 0); 303 | } 304 | 305 | /// @notice Return the tokenId by global index 306 | /// @dev Returns subset of ImmutableSoft DAO tokens that match 307 | /// the entity and product this proxy was initialized for. 308 | /// @return the tokenId of specific index within this collection 309 | function tokenByIndex(uint256 index) public view 310 | returns (uint256) 311 | { 312 | return _tokenOf(address(0), index); 313 | } 314 | } 315 | -------------------------------------------------------------------------------- /contracts/StringCommon.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.7.6; 2 | 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | // OpenZepellin upgradable contracts 6 | import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; 7 | import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; 8 | 9 | /// @title Immutable String - common constants and string routines 10 | /// @author Sean Lawless for ImmutableSoft Inc. 11 | /// @dev StringCommon is string related general/pure functions 12 | contract StringCommon is Initializable, OwnableUpgradeable 13 | { 14 | // Entity Status 15 | // Type is first 32 bits (bits 0 through 31) 16 | uint256 public constant Unknown = 0; 17 | uint256 public constant Creator = 1; 18 | uint256 public constant Distributor = 2; 19 | uint256 public constant EndUser = 3; 20 | 21 | // Flags begin at bit 32 and go until bit 63 22 | uint256 public constant Nonprofit = (1 << 32); 23 | uint256 public constant Automatic = (1 << 33); 24 | uint256 public constant CustomToken = (1 << 34); 25 | 26 | // Country of origin 27 | uint256 public constant CoutryCodeOffset =64; 28 | uint256 public constant CoutryCodeMask = (0xFFFF << CoutryCodeOffset); 29 | 30 | // Product Details 31 | // Category is first 32 bits (bits 0 through 31) 32 | uint256 public constant Tools = 0; 33 | uint256 public constant System = 1; 34 | uint256 public constant Platform = 2; 35 | uint256 public constant Education = 3; 36 | uint256 public constant Entertainment = 4; 37 | uint256 public constant Communications = 5; 38 | uint256 public constant Professional = 6; 39 | uint256 public constant Manufacturing = 7; 40 | uint256 public constant Business = 8; 41 | // Room here for expansion 42 | 43 | // Flags begin at bit 32 and go until bit 63 44 | uint256 public constant Hazard = (1 << 32); 45 | uint256 public constant Adult = (1 << 33); 46 | uint256 public constant Restricted = (1 << 34); 47 | // Distribution restricted by export laws of orgin country? 48 | uint256 public constant USCryptoExport = (1 << 35); 49 | uint256 public constant EUCryptoExport = (1 << 36); 50 | 51 | // Languages begin at bit 64 and go until bit 127 52 | // Ordered by percentage of native speakers 53 | // https://en.wikipedia.org/wiki/List_of_languages_by_number_of_native_speakers 54 | uint256 public constant Mandarin = (1 << 64); 55 | uint256 public constant Spanish = (1 << 65); 56 | uint256 public constant English = (1 << 66); 57 | uint256 public constant Hindi = (1 << 67); 58 | uint256 public constant Bengali = (1 << 68); 59 | uint256 public constant Portuguese = (1 << 69); 60 | uint256 public constant Russian = (1 << 70); 61 | uint256 public constant Japanese = (1 << 71); 62 | uint256 public constant Punjabi = (1 << 71); 63 | uint256 public constant Marathi = (1 << 72); 64 | uint256 public constant Teluga = (1 << 73); 65 | uint256 public constant Wu = (1 << 74); 66 | uint256 public constant Turkish = (1 << 75); 67 | uint256 public constant Korean = (1 << 76); 68 | uint256 public constant French = (1 << 77); 69 | uint256 public constant German = (1 << 78); 70 | uint256 public constant Vietnamese = (1 << 79); 71 | // Room here for 47 additional languages (bit 127) 72 | // Bits 128 - 255 Room here for expansion 73 | // Up to 128 additional languages for example 74 | 75 | // Product Release Version 76 | // Version is first four 16 bit values (first 64 bits) 77 | // Version 0.0.0.0 78 | 79 | // Language bits from above form bits 64 to 127 80 | 81 | // The Platform Type begins at bit 128 and goes until bit 159 82 | uint256 public constant Windows_x86 = (1 << 128); 83 | uint256 public constant Windows_amd64 = (1 << 129); 84 | uint256 public constant Windows_aarch64 =(1 << 130); 85 | uint256 public constant Linux_x86 = (1 << 131); 86 | uint256 public constant Linux_amd64 = (1 << 132); 87 | uint256 public constant Linux_aarch64 = (1 << 133); 88 | uint256 public constant Android_aarch64 =(1 << 134); 89 | uint256 public constant iPhone_arm64 = (1 << 135); 90 | uint256 public constant BIOS_x86 = (1 << 136); 91 | uint256 public constant BIOS_amd64 = (1 << 137); 92 | uint256 public constant BIOS_aarch32 = (1 << 138); 93 | uint256 public constant BIOS_aarch64 = (1 << 139); 94 | uint256 public constant BIOS_arm64 = (1 << 140); 95 | uint256 public constant Mac_amd64 = (1 << 141); 96 | uint256 public constant Mac_arm64 = (1 << 142); 97 | // Room here for expansion 98 | 99 | // End with general types 100 | uint256 public constant SourceCode = (1 << 156); 101 | uint256 public constant Agnostic = (1 << 157); 102 | uint256 public constant NotApplicable = (1 << 158); 103 | uint256 public constant Other = (1 << 159); 104 | // Room for expansion up to value (255 << 152) (last byte of type) 105 | 106 | // Bits 160 through 256 are available for expansion 107 | 108 | // Product License Activation Flags 109 | 110 | // Flags begin at bit 160 and go until bit 191 111 | uint256 public constant ExpirationFlag = (1 << 160); // Activation expiration 112 | uint256 public constant LimitationFlag = (1 << 161); // Version/language limitations 113 | // Cannot be used with feature 114 | uint256 public constant NoResaleFlag = (1 << 162); // Disallow resale after purchase 115 | // Per EU "first sale" law, cannot 116 | // be set if expiration NOT set 117 | uint256 public constant FeatureFlag = (1 << 163); // Specific application feature 118 | // ie. Value is feature specific 119 | // CANNOT be used with Limitation 120 | // flag 121 | 122 | uint256 public constant LimitedOffersFlag = (1 << 164); // Limited number of offers 123 | // UniqueId is used for number 124 | // Offer flag only, not used in 125 | // activate token id 126 | uint256 public constant BulkOffersFlag = (1 << 165); // Limited number of offers 127 | // UniqueId is used for number 128 | // Offer flag only, not used in 129 | // activate token id. Cannot be 130 | // used with LimitedOffersFlag 131 | uint256 public constant RicardianReqFlag = (1 << 166); // Ricardian client token 132 | // ownership required before 133 | // transfer or activation is allowed 134 | 135 | // Offset and mask of entity and product identifiers 136 | uint256 public constant EntityIdOffset = 224; 137 | uint256 public constant EntityIdMask = (0xFFFFFFFF << EntityIdOffset); 138 | uint256 public constant ProductIdOffset = 192; 139 | uint256 public constant ProductIdMask = (0xFFFFFFFF << ProductIdOffset); 140 | 141 | // CreatorToken only: Release id 32 bits 142 | uint256 public constant ReleaseIdOffset = 160; 143 | uint256 public constant ReleaseIdMask = (0xFFFFFFFF << ReleaseIdOffset); 144 | 145 | // ActivateToken only: 16 bits to enforce unique token 146 | uint256 public constant UniqueIdOffset = 176; 147 | uint256 public constant UniqueIdMask = (0xFFFF << UniqueIdOffset); 148 | 149 | // Flags allow different activation types and Value layout 150 | uint256 public constant FlagsOffset = 160; 151 | uint256 public constant FlagsMask = (0xFFFF << FlagsOffset); 152 | 153 | // Expiration is common, last before common 128 bit Value 154 | uint256 public constant ExpirationOffset = 128; 155 | uint256 public constant ExpirationMask = (0xFFFFFFFF << 156 | ExpirationOffset); 157 | 158 | // If limitation flag set, the Value is entirely utilized 159 | /* NOT USED BY SMART CONTRACTS - Dapp only - here for reference 160 | // Bits 64 - 127 are for language (as defined above) 161 | uint256 public constant LanguageOffset = 64; 162 | uint256 public constant LanguageMask = (0xFFFFFFFFFFFFFFFF << 163 | LanguageOffset); 164 | 165 | // Final 64 bits of value is version (4 different 16 bit values) 166 | uint256 public constant LimitVersionOffset = 0; 167 | uint256 public constant LimitVersionMask = (0xFFFFFFFFFFFFFFFF << 168 | LimitVersionOffset); 169 | */ 170 | 171 | // The value is the 128 LSBs 172 | // 32 bits if limitations flag set (96 bits version/language) 173 | // All 128 bits if limitations flag not set 174 | // 175 | uint256 public constant ValueOffset = 0; 176 | uint256 public constant ValueMask = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; 177 | 178 | // Error strings 179 | string public constant EntityIsZero = "EntityID zero"; 180 | string public constant OfferNotFound = "Offer not found"; 181 | string public constant EntityNotValidated = "Entity not validated"; 182 | 183 | string public constant ProductNotFound = "Product not found"; 184 | 185 | string public constant TokenEntityNoMatch = "Token entity does not match"; 186 | string public constant TokenProductNoMatch = "Token product id does not match"; 187 | string public constant TokenNotUnique = "TokenId is NOT unique"; 188 | 189 | /// @notice Initialize the StringCommon smart contract 190 | /// Called during first deployment only (not on upgrade) as 191 | /// this is an OpenZepellin upgradable contract 192 | function initialize() public initializer 193 | { 194 | __Ownable_init(); 195 | /* 196 | constructor() Ownable() 197 | { 198 | */ 199 | } 200 | 201 | /* 202 | /// @notice Convert a base ENS node and label to a node (namehash). 203 | /// ENS nodes are represented as bytes32. 204 | /// @param node The ENS subnode the label is a part of 205 | /// @param label The bytes32 of end label 206 | /// @return The namehash in bytes32 format 207 | function namehash(bytes32 node, bytes32 label) 208 | public pure returns (bytes32) 209 | { 210 | return keccak256(abi.encodePacked(node, label)); 211 | } 212 | 213 | /// @notice Convert an ASCII string to a normalized string. 214 | /// Oversimplified, removes many legitimate characters. 215 | /// @param str The string to normalize 216 | /// @return The normalized string 217 | function normalizeString(string memory str) 218 | public pure returns (string memory) 219 | { 220 | bytes memory bStr = bytes(str); 221 | uint j = 0; 222 | uint i = 0; 223 | 224 | // Loop to count number of characters result will have 225 | for (i = 0; i < bStr.length; i++) { 226 | // Skip if character is not a letter 227 | if ((bStr[i] < 'A') || (bStr[i] > 'z') || 228 | ((bStr[i] > 'Z') && (bStr[i] < 'a'))) 229 | continue; 230 | ++j; 231 | } 232 | 233 | // Allocate the resulting string 234 | bytes memory bLower = new bytes(j); 235 | 236 | // Loop again converting characters to normalized equivalent 237 | j = 0; 238 | for (i = 0; i < bStr.length; i++) 239 | { 240 | // Skip if character is not a letter 241 | if ((bStr[i] < 'A') || (bStr[i] > 'z') || 242 | ((bStr[i] > 'Z') && (bStr[i] < 'a'))) 243 | continue; 244 | 245 | // Convert uppercase to lower 246 | if ((bStr[i] >= 'A') && (bStr[i] <= 'Z')) { 247 | // So we add 32 to make it lowercase 248 | bLower[j] = bytes1(uint8(bStr[i]) + 32); 249 | } else { 250 | bLower[j] = bStr[i]; 251 | } 252 | ++j; 253 | } 254 | return string(bLower); 255 | } 256 | */ 257 | 258 | /// @notice Compare strings and return true if equal. 259 | /// Case sensitive. 260 | /// @param _a The string to be compared 261 | /// @param _b The string to compare 262 | /// @return true if strings are equal, otherwise false 263 | function stringsEqual(string memory _a, string memory _b) 264 | public pure virtual returns (bool) 265 | { 266 | bytes memory a = bytes(_a); 267 | bytes memory b = bytes(_b); 268 | 269 | // Return false if length mismatch 270 | if (a.length != b.length) 271 | return false; 272 | 273 | // Loop and return false if any character does not match 274 | for (uint i = 0; i < a.length; i ++) 275 | if (a[i] != b[i]) 276 | return false; 277 | 278 | // Otherwise strings match so return true 279 | return true; 280 | } 281 | 282 | /* 283 | /// @notice Convert a string to a bytes32 equivalent. 284 | /// Case sensitive. 285 | /// @param source The source string 286 | /// @return the bytes32 equivalent of 'source' 287 | function stringToBytes32(string memory source) 288 | public pure returns (bytes32 result) 289 | { 290 | bytes memory tempEmptyStringTest = bytes(source); 291 | if (tempEmptyStringTest.length == 0) 292 | return 0x0; 293 | 294 | assembly 295 | { 296 | result := mload(add(source, 32)) 297 | } 298 | } 299 | */ 300 | } 301 | -------------------------------------------------------------------------------- /docs/CreatorToken.md: -------------------------------------------------------------------------------- 1 | # The Immutable Product - authentic product distribution (CreatorToken.sol) 2 | 3 | View Source: [\contracts\CreatorToken.sol](..\contracts\CreatorToken.sol) 4 | 5 | **↗ Extends: [Initializable](Initializable.md), [OwnableUpgradeable](OwnableUpgradeable.md), [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md), [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md), [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md)** 6 | 7 | **CreatorToken** 8 | 9 | Token transfers use the ImmuteToken only 10 | 11 | ## Structs 12 | ### Release 13 | 14 | ```js 15 | struct Release { 16 | uint256 hash, 17 | uint256 version, 18 | uint256 parent 19 | } 20 | ``` 21 | 22 | ### ReleaseInformation 23 | 24 | ```js 25 | struct ReleaseInformation { 26 | uint256 index, 27 | uint256 product, 28 | uint256 release, 29 | uint256 version, 30 | string fileURI, 31 | uint256 parent 32 | } 33 | ``` 34 | 35 | ## Contract Members 36 | **Constants & Variables** 37 | 38 | ```js 39 | //private members 40 | mapping(uint256 => struct CreatorToken.Release) private Releases; 41 | mapping(uint256 => uint256) private HashToRelease; 42 | mapping(uint256 => mapping(uint256 => uint256)) private ReleasesNumberOf; 43 | uint256 private AnonProductID; 44 | contract StringCommon private commonInterface; 45 | contract ImmutableEntity private entityInterface; 46 | contract ImmutableProduct private productInterface; 47 | string private __name; 48 | string private __symbol; 49 | 50 | //public members 51 | uint256 public AnonFee; 52 | 53 | ``` 54 | 55 | ## Functions 56 | 57 | - [initialize(address commonAddr, address entityAddr, address productAddr)](#initialize) 58 | - [creatorAnonFee(uint256 newFee)](#creatoranonfee) 59 | - [anonFile(uint256 newHash, string newFileUri, uint256 version)](#anonfile) 60 | - [creatorReleases(uint256[] productIndex, uint256[] newVersion, uint256[] newHash, string[] newFileUri, uint256[] parentHash)](#creatorreleases) 61 | - [creatorReleaseDetails(uint256 entityIndex, uint256 productIndex, uint256 releaseIndex)](#creatorreleasedetails) 62 | - [creatorReleaseHashDetails(uint256 fileHash)](#creatorreleasehashdetails) 63 | - [creatorParentOf(uint256 childHash, uint256 parentHash)](#creatorparentof) 64 | - [creatorHasChildOf(address clientAddress, uint256 parentHash)](#creatorhaschildof) 65 | - [creatorAllReleaseDetails(uint256 entityIndex, uint256 productIndex)](#creatorallreleasedetails) 66 | - [creatorReleasesNumberOf(uint256 entityIndex, uint256 productIndex)](#creatorreleasesnumberof) 67 | - [_beforeTokenTransfer(address from, address to, uint256 tokenId)](#_beforetokentransfer) 68 | - [tokenURI(uint256 tokenId)](#tokenuri) 69 | - [setTokenURI(uint256 tokenId, string _tokenURI)](#settokenuri) 70 | - [_burn(uint256 tokenId)](#_burn) 71 | - [supportsInterface(bytes4 interfaceId)](#supportsinterface) 72 | - [name()](#name) 73 | - [symbol()](#symbol) 74 | 75 | ### initialize 76 | 77 | Initialize the ImmutableProduct smart contract 78 | Called during first deployment only (not on upgrade) as 79 | this is an OpenZepellin upgradable contract 80 | 81 | ```js 82 | function initialize(address commonAddr, address entityAddr, address productAddr) public nonpayable initializer 83 | ``` 84 | 85 | **Arguments** 86 | 87 | | Name | Type | Description | 88 | | ------------- |------------- | -----| 89 | | commonAddr | address | The StringCommon contract address | 90 | | entityAddr | address | The ImmutableEntity token contract address | 91 | | productAddr | address | The ImmutableProduct token contract address | 92 | 93 | ### creatorAnonFee 94 | 95 | Retrieve fee to upgrade. 96 | Administrator only. 97 | 98 | ```js 99 | function creatorAnonFee(uint256 newFee) external nonpayable onlyOwner 100 | ``` 101 | 102 | **Arguments** 103 | 104 | | Name | Type | Description | 105 | | ------------- |------------- | -----| 106 | | newFee | uint256 | the new anonymous use fee | 107 | 108 | ### anonFile 109 | 110 | Anonymous file security (PoE without credentials) 111 | Entity and Product must exist. 112 | 113 | ```js 114 | function anonFile(uint256 newHash, string newFileUri, uint256 version) external payable 115 | ``` 116 | 117 | **Arguments** 118 | 119 | | Name | Type | Description | 120 | | ------------- |------------- | -----| 121 | | newHash | uint256 | The file SHA256 CRC hash | 122 | | newFileUri | string | URI/name/reference of the file | 123 | | version | uint256 | The version and flags of the file | 124 | 125 | ### creatorReleases 126 | 127 | Create new release(s) of an existing product. 128 | Entity and Product must exist. 129 | 130 | ```js 131 | function creatorReleases(uint256[] productIndex, uint256[] newVersion, uint256[] newHash, string[] newFileUri, uint256[] parentHash) external nonpayable 132 | ``` 133 | 134 | **Arguments** 135 | 136 | | Name | Type | Description | 137 | | ------------- |------------- | -----| 138 | | productIndex | uint256[] | Array of product IDs of new release(s) | 139 | | newVersion | uint256[] | Array of version, architecture and languages | 140 | | newHash | uint256[] | Array of file SHA256 CRC hash | 141 | | newFileUri | string[] | Array of valid URIs of the release binary | 142 | | parentHash | uint256[] | Array of SHA256 CRC hash of parent contract | 143 | 144 | ### creatorReleaseDetails 145 | 146 | Return version, URI and hash of existing product release. 147 | Entity, Product and Release must exist. 148 | 149 | ```js 150 | function creatorReleaseDetails(uint256 entityIndex, uint256 productIndex, uint256 releaseIndex) external view 151 | returns(flags uint256, URI string, fileHash uint256, parentHash uint256) 152 | ``` 153 | 154 | **Returns** 155 | 156 | flags , URI, fileHash and parentHash are return values.\ 157 | **flags** The version, architecture and language(s)\ 158 | **URI** The URI to the product release file\ 159 | **fileHash** The SHA256 checksum hash of the file\ 160 | **parentHash** The SHA256 checksum hash of the parent file 161 | 162 | **Arguments** 163 | 164 | | Name | Type | Description | 165 | | ------------- |------------- | -----| 166 | | entityIndex | uint256 | The index of the entity owner of product | 167 | | productIndex | uint256 | The product ID of the new release | 168 | | releaseIndex | uint256 | The index of the product release | 169 | 170 | ### creatorReleaseHashDetails 171 | 172 | Reverse lookup, return entity, product, URI of product release. 173 | Entity, Product and Release must exist. 174 | 175 | ```js 176 | function creatorReleaseHashDetails(uint256 fileHash) public view 177 | returns(entity uint256, product uint256, release uint256, version uint256, URI string, parent uint256) 178 | ``` 179 | 180 | **Returns** 181 | 182 | entity , product, release, version, URI and parent are return values.\ 183 | **entity** The index of the entity owner of product\ 184 | **product** The product ID of the release\ 185 | **release** The release ID of the release\ 186 | **version** The version, architecture and language(s)\ 187 | **URI** The URI to the product release file 188 | **parent** The SHA256 checksum of ricarding parent file 189 | 190 | **Arguments** 191 | 192 | | Name | Type | Description | 193 | | ------------- |------------- | -----| 194 | | fileHash | uint256 | The index of the product release | 195 | 196 | ### creatorParentOf 197 | 198 | Return depth of ricardian parent relative to child 199 | The childHash and parentHash must exist as same product 200 | 201 | ```js 202 | function creatorParentOf(uint256 childHash, uint256 parentHash) public view 203 | returns(uint256) 204 | ``` 205 | 206 | **Returns** 207 | 208 | the child document depth compared to parent (> 0 is parent) 209 | 210 | **Arguments** 211 | 212 | | Name | Type | Description | 213 | | ------------- |------------- | -----| 214 | | childHash | uint256 | SHA256 checksum hash of the child file | 215 | | parentHash | uint256 | SHA256 checksum hash of the parent file | 216 | 217 | ### creatorHasChildOf 218 | 219 | Determine if an address owns a client token of parent 220 | The clientAddress and parentHash must be valid 221 | 222 | ```js 223 | function creatorHasChildOf(address clientAddress, uint256 parentHash) public view 224 | returns(uint256) 225 | ``` 226 | 227 | **Returns** 228 | 229 | The child Ricardian depth to parent (> 0 has child) 230 | 231 | **Arguments** 232 | 233 | | Name | Type | Description | 234 | | ------------- |------------- | -----| 235 | | clientAddress | address | Ethereum address of client | 236 | | parentHash | uint256 | SHA256 checksum hash of the parent file | 237 | 238 | ### creatorAllReleaseDetails 239 | 240 | Retrieve details for all product releases 241 | Status of empty arrays if none found. 242 | 243 | ```js 244 | function creatorAllReleaseDetails(uint256 entityIndex, uint256 productIndex) external view 245 | returns(versions uint256[], URIs string[], hashes uint256[], parents uint256[]) 246 | ``` 247 | 248 | **Returns** 249 | 250 | versions , URIs, hashes, parents are array return values.\ 251 | **versions** Array of version, architecture and language(s)\ 252 | **URIs** Array of URI to the product release files\ 253 | **hashes** Array of SHA256 checksum hash of the files\ 254 | **parents** Aarray of SHA256 checksum hash of the parent files 255 | 256 | **Arguments** 257 | 258 | | Name | Type | Description | 259 | | ------------- |------------- | -----| 260 | | entityIndex | uint256 | The index of the entity owner of product | 261 | | productIndex | uint256 | The product ID of the new release | 262 | 263 | ### creatorReleasesNumberOf 264 | 265 | Return the number of releases of a product 266 | Entity must exist. 267 | 268 | ```js 269 | function creatorReleasesNumberOf(uint256 entityIndex, uint256 productIndex) external view 270 | returns(uint256) 271 | ``` 272 | 273 | **Returns** 274 | 275 | the current number of products for the entity 276 | 277 | **Arguments** 278 | 279 | | Name | Type | Description | 280 | | ------------- |------------- | -----| 281 | | entityIndex | uint256 | The index of the entity | 282 | | productIndex | uint256 | | 283 | 284 | ### _beforeTokenTransfer 285 | 286 | ```js 287 | function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal nonpayable 288 | ``` 289 | 290 | **Arguments** 291 | 292 | | Name | Type | Description | 293 | | ------------- |------------- | -----| 294 | | from | address | | 295 | | to | address | | 296 | | tokenId | uint256 | | 297 | 298 | ### tokenURI 299 | 300 | Look up the release URI from the token Id 301 | 302 | ```js 303 | function tokenURI(uint256 tokenId) public view 304 | returns(string) 305 | ``` 306 | 307 | **Returns** 308 | 309 | the file name and/or URI secured by this token 310 | 311 | **Arguments** 312 | 313 | | Name | Type | Description | 314 | | ------------- |------------- | -----| 315 | | tokenId | uint256 | The unique token identifier | 316 | 317 | ### setTokenURI 318 | 319 | Change the URI of the token Id 320 | Token must exist and caller must be owner or approved 321 | 322 | ```js 323 | function setTokenURI(uint256 tokenId, string _tokenURI) public nonpayable 324 | ``` 325 | 326 | **Arguments** 327 | 328 | | Name | Type | Description | 329 | | ------------- |------------- | -----| 330 | | tokenId | uint256 | The unique token identifier | 331 | | _tokenURI | string | The NFT's new associated URI/URL for this token | 332 | 333 | ### _burn 334 | 335 | Burn a product file release. 336 | Not public, called internally. msg.sender must be the token owner. 337 | 338 | ```js 339 | function _burn(uint256 tokenId) internal nonpayable 340 | ``` 341 | 342 | **Arguments** 343 | 344 | | Name | Type | Description | 345 | | ------------- |------------- | -----| 346 | | tokenId | uint256 | The tokenId to burn | 347 | 348 | ### supportsInterface 349 | 350 | Return the type of supported ERC interfaces 351 | 352 | ```js 353 | function supportsInterface(bytes4 interfaceId) public view 354 | returns(bool) 355 | ``` 356 | 357 | **Returns** 358 | 359 | TRUE (1) if supported, FALSE (0) otherwise 360 | 361 | **Arguments** 362 | 363 | | Name | Type | Description | 364 | | ------------- |------------- | -----| 365 | | interfaceId | bytes4 | The interface desired | 366 | 367 | ### name 368 | 369 | Retrieve the token name 370 | 371 | ```js 372 | function name() public view 373 | returns(string) 374 | ``` 375 | 376 | **Returns** 377 | 378 | Return the token name as a string 379 | 380 | **Arguments** 381 | 382 | | Name | Type | Description | 383 | | ------------- |------------- | -----| 384 | 385 | ### symbol 386 | 387 | Retrieve the token symbol 388 | 389 | ```js 390 | function symbol() public view 391 | returns(string) 392 | ``` 393 | 394 | **Returns** 395 | 396 | Return the token symbol as a string 397 | 398 | **Arguments** 399 | 400 | | Name | Type | Description | 401 | | ------------- |------------- | -----| 402 | 403 | ## Contracts 404 | 405 | * [ActivateToken](ActivateToken.md) 406 | * [AddressUpgradeable](AddressUpgradeable.md) 407 | * [ContextUpgradeable](ContextUpgradeable.md) 408 | * [CreatorToken](CreatorToken.md) 409 | * [CustomToken](CustomToken.md) 410 | * [ERC165Upgradeable](ERC165Upgradeable.md) 411 | * [ERC20Upgradeable](ERC20Upgradeable.md) 412 | * [ERC721BurnableUpgradeable](ERC721BurnableUpgradeable.md) 413 | * [ERC721EnumerableUpgradeable](ERC721EnumerableUpgradeable.md) 414 | * [ERC721Upgradeable](ERC721Upgradeable.md) 415 | * [ERC721URIStorageUpgradeable](ERC721URIStorageUpgradeable.md) 416 | * [IERC165Upgradeable](IERC165Upgradeable.md) 417 | * [IERC20MetadataUpgradeable](IERC20MetadataUpgradeable.md) 418 | * [IERC20Upgradeable](IERC20Upgradeable.md) 419 | * [IERC721EnumerableUpgradeable](IERC721EnumerableUpgradeable.md) 420 | * [IERC721MetadataUpgradeable](IERC721MetadataUpgradeable.md) 421 | * [IERC721ReceiverUpgradeable](IERC721ReceiverUpgradeable.md) 422 | * [IERC721Upgradeable](IERC721Upgradeable.md) 423 | * [ImmutableEntity](ImmutableEntity.md) 424 | * [ImmutableProduct](ImmutableProduct.md) 425 | * [Initializable](Initializable.md) 426 | * [Migrations](Migrations.md) 427 | * [OwnableUpgradeable](OwnableUpgradeable.md) 428 | * [ProductActivate](ProductActivate.md) 429 | * [StringCommon](StringCommon.md) 430 | * [StringsUpgradeable](StringsUpgradeable.md) 431 | --------------------------------------------------------------------------------