From 8bbc87e8264a619500a816bcbead9ddae45c330f Mon Sep 17 00:00:00 2001 From: Gheorghe Pinzaru Date: Fri, 1 May 2020 19:01:23 +0300 Subject: [PATCH 1/6] Add spec for IPFS gateway for Sticker Pack --- docs/draft/sticker-pack.md | 78 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 docs/draft/sticker-pack.md diff --git a/docs/draft/sticker-pack.md b/docs/draft/sticker-pack.md new file mode 100644 index 0000000..ae1c871 --- /dev/null +++ b/docs/draft/sticker-pack.md @@ -0,0 +1,78 @@ +--- +title: IPFS gateway for Sticker Pack +version: 0.1.0 +status: Draft +authors: Gheorghe Pinzaru +redirect_from: + - /sticker-pack.html +--- + +## Table of Contents + + 1. [Abstract](#abstract) + 2. [Specification](#specification) + 3. [Copyright](#copyright) + +## Abstract + +In this specification, we describe how Status app uses IPFS gateway to store stickers. +We will explore image format, how they are uploaded and how an end user can see them +insed the Status app. + +## Definition + +| Term | Description | +|------------------|----------------------------------------------------------------------------------------| +| **Stickers** | A set of images which can be used to express emotions | +| **Sticker Pack** | ERC721 token which includes the set of stickers | +| **IPFS** | P2P network used to store and share data, in this case, the images for the stickerpack | + +## Specification + +### Image format +Accepted image file types are **PNG, JPG/JPEG and GIF**, with a maximum allowed size of 300kb. +The minimum sticker image resoulution is 512x512, and background of clipart should be transparent. + +### Distribution + +Sticker pack are implemented as ERC721 token and contains a set of stickers. These stickers +are stored inside the sticker pack as a set of hyperlinks pointing to IPFS storage. These +hyperlinks are publically available and can be accessed by any user inside the status chat. +Stickers can be sent in chat only by accounts that own the sticker pack. + +### IPFS gateway +At the moment of writing, the Status uses the [Infura](https://infura.io/) gateway. +Infura gateway is an HTTPS gateway, which based on an HTTP GET request with the +multihash block will return the stored content at that block address. + +The use of gateway is required to enable easy access to the resources over HTTP. +Each image of a sticker is stored inside IPFS using a unique address that is +derived from the hash of the file. This ensures that a file can't be overridden, +and an end-user of the IPFS will receive the same file at a given address. + +The IPFS gateway acts as an end-user of the IPFS and allows users of the gateway +to access IPFS without connection to the P2P network. Usage of a gateway introduces +potential risk for the users of that gateway provider. In case of a compromising +of security of the provider, meta information of its users can be leaked. Or if the +provider servers are unavailable the access to the whole IPFS network will be lost. + +When a sticker is shown in the app, Status app makes an http GET request to IPFS gateway using the hyperlink. + +### Status sticker usage +To send a sticker in chat, a user of Status should buy or install a sticker pack. +To install a sticker pack, we need to fetch all sticker packs which are available in Sticker Market. +The following steps are needed to fetch all sticker packs: +#### 1. Get total number of sticker packs +Call `packCount()` on the sticker market contract, will return number of sticker pack registered as `uint256`. +#### 2. Get sticker pack by id +ID's are represented as `uint256` and are incremental from `0` to totatl number of sticker packs in contract, which we received on previous step. To get a sticker pack we should call `getPackData(sticker-pack-id)`, the return type is `["bytes4[]" "address" "bool" "uint256" "uint256" "bytes"]` which represents the following fields: `[category owner mintable timestamp price contenthash]`. +`TODO:` Describe contenthash, it's a hash in IPFS (what it contains?) +##### 3. Get owned stick packs +To get owned packs, we should get all owned tokens for the current account address. To do that we should call `balanceOf(address)` where address is the address for current account. This method returns a `uint256` representing the token id representing the count of available tokens. Using `tokenOfOwnerByIndex(address,uint256)` method, with the address of the user and ID in form of a `uint256` which is an incremented int from 0 to total number of tokens, we will get token id. To get sticker pack id from token we call`tokenPackId(uint256)` where `uint256` is the token id. This method will return an `uint256` which is the id of the owned sticker pack. + +##### 4. Buy a sticker pack +To buy a sticker pack we should call `approveAndCall(address,uint256,bytes)` where `address` is the address of buyer,`uint256` is the price and third parameters `bytes` is the callback called if approved. In callback we call `buyToken(uint256,address,uint256)`, first parameter is sticker pack id, second buyers address, and the last is the price. +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). + From c3b5e9c0537eb9dfa7f3e347636d771ef5d3bc28 Mon Sep 17 00:00:00 2001 From: Gheorghe Pinzaru Date: Mon, 4 May 2020 15:42:47 +0300 Subject: [PATCH 2/6] Misspelling Co-authored-by: yenda --- docs/draft/sticker-pack.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/draft/sticker-pack.md b/docs/draft/sticker-pack.md index ae1c871..9e47036 100644 --- a/docs/draft/sticker-pack.md +++ b/docs/draft/sticker-pack.md @@ -17,7 +17,7 @@ redirect_from: In this specification, we describe how Status app uses IPFS gateway to store stickers. We will explore image format, how they are uploaded and how an end user can see them -insed the Status app. +inside the Status app. ## Definition @@ -41,7 +41,7 @@ hyperlinks are publically available and can be accessed by any user inside the s Stickers can be sent in chat only by accounts that own the sticker pack. ### IPFS gateway -At the moment of writing, the Status uses the [Infura](https://infura.io/) gateway. +At the moment of writing, Status uses the [Infura](https://infura.io/) gateway. Infura gateway is an HTTPS gateway, which based on an HTTP GET request with the multihash block will return the stored content at that block address. @@ -65,14 +65,13 @@ The following steps are needed to fetch all sticker packs: #### 1. Get total number of sticker packs Call `packCount()` on the sticker market contract, will return number of sticker pack registered as `uint256`. #### 2. Get sticker pack by id -ID's are represented as `uint256` and are incremental from `0` to totatl number of sticker packs in contract, which we received on previous step. To get a sticker pack we should call `getPackData(sticker-pack-id)`, the return type is `["bytes4[]" "address" "bool" "uint256" "uint256" "bytes"]` which represents the following fields: `[category owner mintable timestamp price contenthash]`. +ID's are represented as `uint256` and are incremental from `0` to total number of sticker packs in contract, which we received on previous step. To get a sticker pack we should call `getPackData(sticker-pack-id)`, the return type is `["bytes4[]" "address" "bool" "uint256" "uint256" "bytes"]` which represents the following fields: `[category owner mintable timestamp price contenthash]`. `TODO:` Describe contenthash, it's a hash in IPFS (what it contains?) ##### 3. Get owned stick packs -To get owned packs, we should get all owned tokens for the current account address. To do that we should call `balanceOf(address)` where address is the address for current account. This method returns a `uint256` representing the token id representing the count of available tokens. Using `tokenOfOwnerByIndex(address,uint256)` method, with the address of the user and ID in form of a `uint256` which is an incremented int from 0 to total number of tokens, we will get token id. To get sticker pack id from token we call`tokenPackId(uint256)` where `uint256` is the token id. This method will return an `uint256` which is the id of the owned sticker pack. +To get owned packs, we should get all owned tokens for the current account address. To do that we should call `balanceOf(address)` where address is the address for current account. This method returns a `uint256` representing the count of available tokens. Using `tokenOfOwnerByIndex(address,uint256)` method, with the address of the user and ID in form of a `uint256` which is an incremented int from 0 to total number of tokens, we will get token id. To get sticker pack id from token we call`tokenPackId(uint256)` where `uint256` is the token id. This method will return an `uint256` which is the id of the owned sticker pack. ##### 4. Buy a sticker pack To buy a sticker pack we should call `approveAndCall(address,uint256,bytes)` where `address` is the address of buyer,`uint256` is the price and third parameters `bytes` is the callback called if approved. In callback we call `buyToken(uint256,address,uint256)`, first parameter is sticker pack id, second buyers address, and the last is the price. ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). - From 263d9047964696feb199425393dd8494260db107 Mon Sep 17 00:00:00 2001 From: Gheorghe Pinzaru Date: Fri, 8 May 2020 10:31:50 +0300 Subject: [PATCH 3/6] Follow up review comments --- docs/draft/sticker-pack.md | 79 +++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 30 deletions(-) diff --git a/docs/draft/sticker-pack.md b/docs/draft/sticker-pack.md index 9e47036..3a7628b 100644 --- a/docs/draft/sticker-pack.md +++ b/docs/draft/sticker-pack.md @@ -1,12 +1,19 @@ --- -title: IPFS gateway for Sticker Pack -version: 0.1.0 -status: Draft -authors: Gheorghe Pinzaru -redirect_from: - - /sticker-pack.html +permalink: /spec/8 +parent: Draft specs +title: 8/IPFS gateway for Sticker Pack --- +# 8/IPFS gateway for Sticker Pack + +> Version: 0.1.0 +> +> Status: Draft +> +> Authors: Gheorghe Pinzaru +> + + ## Table of Contents 1. [Abstract](#abstract) @@ -16,8 +23,7 @@ redirect_from: ## Abstract In this specification, we describe how Status app uses IPFS gateway to store stickers. -We will explore image format, how they are uploaded and how an end user can see them -inside the Status app. +We will explore image format, how they are uploaded and how an end user can see them inside the Status app. ## Definition @@ -25,7 +31,7 @@ inside the Status app. |------------------|----------------------------------------------------------------------------------------| | **Stickers** | A set of images which can be used to express emotions | | **Sticker Pack** | ERC721 token which includes the set of stickers | -| **IPFS** | P2P network used to store and share data, in this case, the images for the stickerpack | +| **IPFS** | P2P network used to store and share data, in this case, the images for the stickerpack | ## Specification @@ -35,39 +41,52 @@ The minimum sticker image resoulution is 512x512, and background of clipart shou ### Distribution -Sticker pack are implemented as ERC721 token and contains a set of stickers. These stickers -are stored inside the sticker pack as a set of hyperlinks pointing to IPFS storage. These -hyperlinks are publically available and can be accessed by any user inside the status chat. +Sticker pack are implemented as [ERC721 token](https://eips.ethereum.org/EIPS/eip-721) and contains a set of stickers. These stickers +are stored inside the sticker pack as a set of hyperlinks pointing to IPFS storage. These hyperlinks are publically available and can be accessed by any user inside the status chat. Stickers can be sent in chat only by accounts that own the sticker pack. ### IPFS gateway -At the moment of writing, Status uses the [Infura](https://infura.io/) gateway. -Infura gateway is an HTTPS gateway, which based on an HTTP GET request with the -multihash block will return the stored content at that block address. +At the moment of writing, the current main Status app uses the [Infura](https://infura.io/) gateway. However clients could choose a different gateway or to run own IPFS node. +Infura gateway is an HTTPS gateway, which based on an HTTP GET request with the multihash block will return the stored content at that block address. The use of gateway is required to enable easy access to the resources over HTTP. Each image of a sticker is stored inside IPFS using a unique address that is -derived from the hash of the file. This ensures that a file can't be overridden, -and an end-user of the IPFS will receive the same file at a given address. +derived from the hash of the file. This ensures that a file can't be overridden, and an end-user of the IPFS will receive the same file at a given address. -The IPFS gateway acts as an end-user of the IPFS and allows users of the gateway -to access IPFS without connection to the P2P network. Usage of a gateway introduces -potential risk for the users of that gateway provider. In case of a compromising -of security of the provider, meta information of its users can be leaked. Or if the -provider servers are unavailable the access to the whole IPFS network will be lost. - -When a sticker is shown in the app, Status app makes an http GET request to IPFS gateway using the hyperlink. +### Security +The IPFS gateway acts as an end-user of the IPFS and allows users of the gateway to access IPFS without connection to the P2P network. +Usage of a gateway introduces potential risk for the users of that gateway provider. In case of a compromise in the security of the provider, meta information such as IP address, User-Agent and other of its users can be leaked. +If the provider servers are unavailable the access trought gateway to the IPFS network is lost. ### Status sticker usage -To send a sticker in chat, a user of Status should buy or install a sticker pack. -To install a sticker pack, we need to fetch all sticker packs which are available in Sticker Market. -The following steps are needed to fetch all sticker packs: +When a sticker is shown in the app, Status app makes an http GET request to IPFS gateway using the hyperlink. + +To send a sticker in chat, a user of Status should buy or install a sticker pack. + +To be available for installation a Sticker Pack should be submitted to Sticker market by an author. + +#### Submit a sticker + +To submit a sticker pack, the author should upload all assets to IPFS. Then generate a payload including name, author, thumbnail, preview and a list of stickers in the [EDN format](https://github.com/edn-format/edn). Following this structure: +``` +{meta {:name "Sticker pack name" + :author "Author Name" + :thumbnail "https://ipfs.infura.io/ipfs/QmfFVKK6uvP7nqZGx6MQd2oiwxgz1d14RAHsnADazq6dBw" + :preview "https://ipfs.infura.io/ipfs/QmfFVKK6uvP7nqZGx6MQd2oiwxgz1d14RAHsnADazq6dBw" + :stickers [{:uri "https://ipfs.infura.io/ipfs/QmSakonhLgK9zoyZmDW3oTqNeKoQPYoL9CJvoQ4uUQvTpc/"} + {:uri "https://ipfs.infura.io/ipfs/Qmf1iMPeMaNf2aSww7yhVbCVyDy5iiZPyrLA4qPgZ9LWpM/"}]}} +``` + This payload is uploaded also to IPFS, and the IPFS address is used in the content field of the Sticker Market contract. See [Sticker Market spec](https://github.com/status-im/sticker-market/blob/651e88e5f38c690e57ecaad47f46b9641b8b1e27/docs/specification.md) for a detailed description of the contract. + +#### Install a sticker pack + +To install a sticker pack, we need to fetch all sticker packs which are available in Sticker Market. The following steps are needed to fetch all sticker packs: #### 1. Get total number of sticker packs Call `packCount()` on the sticker market contract, will return number of sticker pack registered as `uint256`. #### 2. Get sticker pack by id -ID's are represented as `uint256` and are incremental from `0` to total number of sticker packs in contract, which we received on previous step. To get a sticker pack we should call `getPackData(sticker-pack-id)`, the return type is `["bytes4[]" "address" "bool" "uint256" "uint256" "bytes"]` which represents the following fields: `[category owner mintable timestamp price contenthash]`. -`TODO:` Describe contenthash, it's a hash in IPFS (what it contains?) -##### 3. Get owned stick packs +ID's are represented as `uint256` and are incremental from `0` to total number of sticker packs in contract, which we received on previous step. To get a sticker pack we should call `getPackData(sticker-pack-id)`, the return type is `["bytes4[]" "address" "bool" "uint256" "uint256" "bytes"]` which represents the following fields: `[category owner mintable timestamp price contenthash]`. Price is the SNT value in wei setted by sticker pack owner. The contenthash is the IPFS address described in the [submit desction](#submit-a-sticker-pack) above. Other fields specification could be found in [Sticker Market spec](https://github.com/status-im/sticker-market/blob/651e88e5f38c690e57ecaad47f46b9641b8b1e27/docs/specification.md) +##### 3. Get owned sticker packs +The current Status app fetches owned sticker packs during the open of any sticker view (a screen which shows a sticker pack or the list of sticker packs). To get owned packs, we should get all owned tokens for the current account address. To do that we should call `balanceOf(address)` where address is the address for current account. This method returns a `uint256` representing the count of available tokens. Using `tokenOfOwnerByIndex(address,uint256)` method, with the address of the user and ID in form of a `uint256` which is an incremented int from 0 to total number of tokens, we will get token id. To get sticker pack id from token we call`tokenPackId(uint256)` where `uint256` is the token id. This method will return an `uint256` which is the id of the owned sticker pack. ##### 4. Buy a sticker pack From 26a75a880ec66d10cae956804cd12c244aec1746 Mon Sep 17 00:00:00 2001 From: Gheorghe Pinzaru Date: Wed, 13 May 2020 16:02:19 +0300 Subject: [PATCH 4/6] Text style fixes Co-authored-by: Dean Eigenmann <7621705+decanus@users.noreply.github.com> --- docs/draft/sticker-pack.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/draft/sticker-pack.md b/docs/draft/sticker-pack.md index 3a7628b..09b5e6d 100644 --- a/docs/draft/sticker-pack.md +++ b/docs/draft/sticker-pack.md @@ -22,7 +22,7 @@ title: 8/IPFS gateway for Sticker Pack ## Abstract -In this specification, we describe how Status app uses IPFS gateway to store stickers. +In this specification, we describe how Status uses the IPFS gateway to store stickers. We will explore image format, how they are uploaded and how an end user can see them inside the Status app. ## Definition @@ -36,12 +36,12 @@ We will explore image format, how they are uploaded and how an end user can see ## Specification ### Image format -Accepted image file types are **PNG, JPG/JPEG and GIF**, with a maximum allowed size of 300kb. -The minimum sticker image resoulution is 512x512, and background of clipart should be transparent. +Accepted image file types are `PNG`, `JPG/JPEG` and `GIF`, with a maximum allowed size of 300kb. +The minimum sticker image resolution is 512x512, and its background SHOULD be transparent. ### Distribution -Sticker pack are implemented as [ERC721 token](https://eips.ethereum.org/EIPS/eip-721) and contains a set of stickers. These stickers +Sticker packs are implemented as [ERC721 token](https://eips.ethereum.org/EIPS/eip-721) and contain a set of stickers. These stickers are stored inside the sticker pack as a set of hyperlinks pointing to IPFS storage. These hyperlinks are publically available and can be accessed by any user inside the status chat. Stickers can be sent in chat only by accounts that own the sticker pack. From 7607cdc3f3cd7755f529e7bf367065743dff3a7b Mon Sep 17 00:00:00 2001 From: Gheorghe Pinzaru Date: Wed, 13 May 2020 16:59:08 +0300 Subject: [PATCH 5/6] Update sticker pack contenthsh example --- docs/draft/sticker-pack.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/draft/sticker-pack.md b/docs/draft/sticker-pack.md index 09b5e6d..9e67f86 100644 --- a/docs/draft/sticker-pack.md +++ b/docs/draft/sticker-pack.md @@ -71,11 +71,12 @@ To submit a sticker pack, the author should upload all assets to IPFS. Then gene ``` {meta {:name "Sticker pack name" :author "Author Name" - :thumbnail "https://ipfs.infura.io/ipfs/QmfFVKK6uvP7nqZGx6MQd2oiwxgz1d14RAHsnADazq6dBw" - :preview "https://ipfs.infura.io/ipfs/QmfFVKK6uvP7nqZGx6MQd2oiwxgz1d14RAHsnADazq6dBw" - :stickers [{:uri "https://ipfs.infura.io/ipfs/QmSakonhLgK9zoyZmDW3oTqNeKoQPYoL9CJvoQ4uUQvTpc/"} - {:uri "https://ipfs.infura.io/ipfs/Qmf1iMPeMaNf2aSww7yhVbCVyDy5iiZPyrLA4qPgZ9LWpM/"}]}} + :thumbnail "e30101701220602163b4f56c747333f43775fdcbe4e62d6a3e147b22aaf6097ce0143a6b2373" + :preview "e30101701220ef54a5354b78ef82e542bd468f58804de71c8ec268da7968a1422909357f2456" + :stickers [{:hash "e301017012207737b75367b8068e5bdd027d7b71a25138c83e155d1f0c9bc5c48ff158724495"} + {:hash "e301017012201a9cdea03f27cda1aede7315f79579e160c7b2b6a2eb51a66e47a96f47fe5284"}]}} ``` +All assets fileds, are contenthash fileds as per [EIP 1577](https://eips.ethereum.org/EIPS/eip-1577). This payload is uploaded also to IPFS, and the IPFS address is used in the content field of the Sticker Market contract. See [Sticker Market spec](https://github.com/status-im/sticker-market/blob/651e88e5f38c690e57ecaad47f46b9641b8b1e27/docs/specification.md) for a detailed description of the contract. #### Install a sticker pack From 8799b31c805e8c0659ab1d44ccfce21a6e0d2861 Mon Sep 17 00:00:00 2001 From: Gheorghe Pinzaru Date: Fri, 15 May 2020 12:15:15 +0300 Subject: [PATCH 6/6] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Oskar Thorén --- docs/draft/sticker-pack.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/draft/sticker-pack.md b/docs/draft/sticker-pack.md index 9e67f86..f723e22 100644 --- a/docs/draft/sticker-pack.md +++ b/docs/draft/sticker-pack.md @@ -82,16 +82,20 @@ All assets fileds, are contenthash fileds as per [EIP 1577](https://eips.ethereu #### Install a sticker pack To install a sticker pack, we need to fetch all sticker packs which are available in Sticker Market. The following steps are needed to fetch all sticker packs: + #### 1. Get total number of sticker packs Call `packCount()` on the sticker market contract, will return number of sticker pack registered as `uint256`. + #### 2. Get sticker pack by id -ID's are represented as `uint256` and are incremental from `0` to total number of sticker packs in contract, which we received on previous step. To get a sticker pack we should call `getPackData(sticker-pack-id)`, the return type is `["bytes4[]" "address" "bool" "uint256" "uint256" "bytes"]` which represents the following fields: `[category owner mintable timestamp price contenthash]`. Price is the SNT value in wei setted by sticker pack owner. The contenthash is the IPFS address described in the [submit desction](#submit-a-sticker-pack) above. Other fields specification could be found in [Sticker Market spec](https://github.com/status-im/sticker-market/blob/651e88e5f38c690e57ecaad47f46b9641b8b1e27/docs/specification.md) +ID's are represented as `uint256` and are incremental from `0` to total number of sticker packs in contract, which we received on previous step. To get a sticker pack we should call `getPackData(sticker-pack-id)`, the return type is `["bytes4[]" "address" "bool" "uint256" "uint256" "bytes"]` which represents the following fields: `[category owner mintable timestamp price contenthash]`. Price is the SNT value in wei setted by sticker pack owner. The contenthash is the IPFS address described in the [submit description](#submit-a-sticker-pack) above. Other fields specification could be found in [Sticker Market spec](https://github.com/status-im/sticker-market/blob/651e88e5f38c690e57ecaad47f46b9641b8b1e27/docs/specification.md) + ##### 3. Get owned sticker packs The current Status app fetches owned sticker packs during the open of any sticker view (a screen which shows a sticker pack or the list of sticker packs). To get owned packs, we should get all owned tokens for the current account address. To do that we should call `balanceOf(address)` where address is the address for current account. This method returns a `uint256` representing the count of available tokens. Using `tokenOfOwnerByIndex(address,uint256)` method, with the address of the user and ID in form of a `uint256` which is an incremented int from 0 to total number of tokens, we will get token id. To get sticker pack id from token we call`tokenPackId(uint256)` where `uint256` is the token id. This method will return an `uint256` which is the id of the owned sticker pack. ##### 4. Buy a sticker pack To buy a sticker pack we should call `approveAndCall(address,uint256,bytes)` where `address` is the address of buyer,`uint256` is the price and third parameters `bytes` is the callback called if approved. In callback we call `buyToken(uint256,address,uint256)`, first parameter is sticker pack id, second buyers address, and the last is the price. + ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).