-
Notifications
You must be signed in to change notification settings - Fork 117
Apps as first-class citizens #4307
Description
Background
When an application brings a creator to the platform, or a creator publishes a video, often this is positive spillover for the system as a whole. It makes the system more attractive for other applications, consumers and creators, and it also allows the DAO to capture value from downstream activities associated with this publishing, like NFT fees, gateway burns, etc. This means that it is efficient for the DAO to directly subsidies such onboarding in a way which is informed by how much value a creator brings to the platform down stream, for example as measured by various burns or shares of creator payouts. Such subsidisation however requires attribution. It must be known what application actually was the vehicle for capturing and onboarding the creator and content. Such attribution has another strong benefit. When content is published with authentic application attribution, other applications receive a signal about the properties of the content being published, by virtue of things like their creator/content pool post processing steps (screening, transcoding, ...). Lastly, attribution involves creating an application index which will serve as an excellent public index of what exactly is being built on and served on the platform at any given time.
Proposal
Introduce applications at the metaprotocol level, and wrap existing metaprotocol messaging inside authenticated application action messages. The reason we put applications at the metaprotocol is that we don't need automated value transfer, e.g. x% of creator payout going to onboarding application. This is not only overkill right now, but we are unlikely to pick the exact right approach out of the box, so sticking to a more light weight and flexible approach is better.
Member & Content lead remarks
We make applications owned by either members or the DAO itself, as presented by the content lead. We add the following new messages with obvious semantics to be used over content lead or member remark extrinsics:
CreateApp: creates new app with incremental ID.- name: immutable
- website_url: where to read more about the project, company for this app.
- use_uri: where to actually get or use this app.
- small_icon: url+hash.
- medium_icon: url+hash.
- big_icon: url+hash.
- one_liner: tagline.
- description: longer description.
- terms_of_service: terms of service that will be clickwrapped, some URL+hash is enough, raw text will be too long.
- auth_key: public key used for authenticating messages, may as well be same signature scheme as blockchain accounts.
- platform: mobile, tablet, roku, web, native (win), native (osx), smart tv,...
versions: native win, native osx, iphone, android,...- category: messaging, streaming, adult, ...
UpdateApp: updates app properties- app ID.
- optional new values for everything except
name
DeleteApp: drops an app.- app ID.
Content Directory Creation Extrinsics
As preface note that we still allow people to create channels and publish just like before.
We introduce a new message AppAction that represents the use of some content directory functionality through a specific application. with fields
app_id: ID of app.metadata: raw metadata, can be anything.raw_action: serialised form of primary content directory message (see more below).signature: signature over app action commitment (see more below) usingauth_keyof app.
The reason raw_action is not locked to a specific set of messages is that it allows apps to start playing with distinct metadata formats while still being able to signal that actions are through a specific app. The app action commitment refers to all of the information relevant to identifying a distinct action. There are two types of runtime-level actions with which application actions can be combined channel creation and video creation. Arguably editing videos could also be covered, but it's more reasonable to just start with the basics.
Channel creation
Here the following extrinsic is used
pub fn create_channel(
origin,
channel_owner: ChannelOwner<T::MemberId, T::CuratorGroupId>,
params: ChannelCreationParameters<T>,
)
pub struct ChannelCreationParametersRecord
...
/// Assets referenced by metadata
pub assets: Option<StorageAssets>,
/// Metadata about the channel.
pub meta: Option<Vec<u8>>,
/// Map from collaborator's MemberId to collaborator's ChannelAgentPermissions
pub collaborators: BTreeMap<MemberId, ChannelAgentPermissions>,
/// Storage buckets to assign to a bag.
pub storage_buckets: BTreeSet<StorageBucketId>,
/// Distribution buckets to assign to a bag.
pub distribution_buckets: BTreeSet<DistributionBucketId>,
/// Commitment for the channel state bloat bond.
pub expected_channel_state_bloat_bond: Balance,
/// Commitment for the data object state bloat bond for the storage pallet.
pub expected_data_object_state_bloat_bond: Balance,
}In this case the
ChannelCreationParametersRecord::metais set toSome(serialized_app_action_instance)whereserialized_app_action_instanceis serialized message of typeAppAction- app commitment is
serialize(channel_owner)||serialize(assets)||AppAction::raw_action||AppAction::metadata, whereserializegives the SCALE codec of the value. In this caseraw_actionwould for example be the serialized form of the existingCreateChannelmetaprotocol message. Appcation::signatureis generated by server side of application interactively with client side application logic before extrinsic is sent.
NB: be aware of replay attack mentioned by @kdembler here #4307 (comment)
Video creation
Here the following extrinsic is used
pub fn create_video(
origin,
actor: ContentActor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
channel_id: T::ChannelId,
params: VideoCreationParameters<T>,
)and its basically an analogous story, just include channel_id in commitment (no time!).
NB: be aware of replay attack mentioned by @kdembler here #4307 (comment), same issue exists for videos.