Web3: Factories, Contracts and NFTs

Unifying User Accounts Across Platforms

The Users plugin is designed to have all of the methods we need to interface with external platforms like Facebook and Telegram, and that includes Web3 (EVM-compatible blockchains).

Just like other external platforms, each userId can have one or more external IDs (xids), with the associations stored using Users_ExternalFrom and Users_ExternalTo. Unlike with Facebook, xids on Web3 (and Telegram) platforms are not app-scoped, meaning that the xid is the same across all blockchains: if you control an ECDSA private key, you can sign payloads as an address, regardless of blockchain!

Q.Users.login({using: platforms}) is used to log the user in through external platforms, while Q.Users.authenticate(platform) can used to tie an existing external authenticated account so the currently logged-in user. Also look at Q.Users.loggedInUser.xids .

Unifying Data Access Across Platforms

Qbix is designed for users to collaboratively manage data that is hosted by web servers, whether on a local network or on the internet. It has a robust set of ways to represent access control, involving relations, communities, roles, permissions, etc. You can read more about that in https://qbix.com/platform/guide/access

On the blockchain, however, the business rules are enforced by smart contracts, rather than PHP applications; it is verified and stored on many computers, rather than one central database. This allows large communities to ensure that data stored on blockchains can only be acted upon by those who have the private keys to take some individual actions, as opposed to one key to the entire database, as is the case with centralized sites (including Big Tech companies). This gives the community a lot more security for data managed by Intercoin smart contracts.

The data on a public blockchain is also publicly readable by anyone, especially the nodes securing the blockchain, so it is not confidential. However, communities can store hashes of confidential data on blockchains.

How do we integrate data on Qbix with data on Web3? Essentially we now we have seven simple rules:

  1. BLOCKCHAIN RELATIONS: When a smart contract on a blockchain has the relations stored and exposed, then it is the source of truth. For example if factory has list of instances, or if a contract has list of NFTs by owner. We consult the blockchain by calling public methods of the smart contract.

  2. QBIX RELATIONS: Otherwise, if a blockchain doesn’t store the relations (for example, factory.produce may not store an enumerable array of instances, but only emits Events) then we can store in Streams relations some subset of these relations… for example we wait for transaction to be successfully mined and add an Assets/NFT stream published by “Assets”, related to global Assets/NFT/factory stream published by “Assets”.

  3. ADDRESSES: Factories have fixed addresses on each blockchain (usually it is the same on all blockchains). But there can be many instances of contracts produced by factories. Regardless of whether we discover new blockchain objects using method 1 or 2 (reading blockchain or reading our database), the instance address should be an option for a tool. Or for a page representing an instance (eg NFT page) there must be an :address component of route. And for streams representing these instances (of whatever), the streamName should contain at least the first 16 characters of its 0x… address.

  4. EDITING: We may want to allow some users to customize some metadata on our database for blockchain instance at some addresses: title, url, keywords, description, etc. For this we have Websites/seo tool which we can place on any page. And in listings of links to pages (whether generated by method 1 or 2) we can now have Streams/image/preview and Streams/inplace tools that reference streamNames that have not yet been created, but can be used to create and edit these streams.

  1. BLOCKCHAIN AUTHORIZATION: All blockchain data is public for reading, but not everyone can call every smart contract method. Each smart contract (factory or instance) may respond to certain blockchain xids only. In this case we call blockchain methods to see if loggedInUserXid() has the ability to call some methods X, Y on blockchain contract (factory or instance), before showing that tool or Q/action to the user. (If tools are rendered in PHP, we do this in PHP using Users_Web3::execute() that caches results for e.g 10 minutes).

  2. QBIX AUTHORIZATION: This continues to be done using the Streams access control system for readLevel, writeLevel and adminLevel. Qbix relies on on template access and mutable access to know whether a user is authorized to create a new stream and relate it to a category. Streams may refer to content that is stored on the local filesystem (which is usually public but may be at an obscure URL), inside a database as BLOBs (usually access controlled) or even encrypted (requiring private keys to read and write offchain data).

  3. NFTs: For NFTs, inside instances, we further have tokenId. Again, same rules 1-4 apply, but we may require routes, tool options, and streamNames to have both the :address and the :tokenId. Currently, the :publisherId, :streamName comes from Streams::fromHexString($tokenId) which, if you notice, doesn’t have dependence on $contractAddress! This means that, currently in any given Qbix site, the same $publisher can publish metadata for NFTs across many different smart contracts. We may have to watch out for a conflict between same tokenId on different smart contracts. Since Intercoin’s code runs the NFT contracts, it might actually give us a lot of opportunities to allow people to manage NFTs across smart contracts.

We have to keep in mind these 7 rules as we build out ever-tighter integration between Web2 and Web3 = Web5!