From d043ac37a87c40e24da56dddaf2e62b70b765b8e Mon Sep 17 00:00:00 2001 From: xalava Date: Tue, 20 Dec 2022 11:39:30 +0100 Subject: [PATCH] Last blockchain projects --- .../blockchain/benchmarking-tool/README.md | 43 +++++ .../benchmarking-tool/audit/README.md | 37 ++++ .../blockchain/trading-platform/README.md | 182 ++++++++++++++++++ .../trading-platform/audit/README.md | 35 ++++ subjects/blockchain/trading-platform/viz.png | Bin 0 -> 41288 bytes subjects/shop/audit/README.md | 94 ++++----- 6 files changed, 344 insertions(+), 47 deletions(-) create mode 100644 subjects/blockchain/benchmarking-tool/README.md create mode 100644 subjects/blockchain/benchmarking-tool/audit/README.md create mode 100644 subjects/blockchain/trading-platform/README.md create mode 100644 subjects/blockchain/trading-platform/audit/README.md create mode 100644 subjects/blockchain/trading-platform/viz.png diff --git a/subjects/blockchain/benchmarking-tool/README.md b/subjects/blockchain/benchmarking-tool/README.md new file mode 100644 index 000000000..fb8af33d0 --- /dev/null +++ b/subjects/blockchain/benchmarking-tool/README.md @@ -0,0 +1,43 @@ +# A network dashboard and benchmarking tool + +Blockchain nodes participate in a common peer-to-peer network retrieving information, executing and validating transactions and blocks. However, software clients differ in their functionalities and resource consumption. The purpose of this project is to create a tool, `benchy` that can launch, monitor and benchmark Ethereum networks. + +## launch-network + +At first, we will focus on deploying a private Ethereum network while monitoring the nodes. The nodes can be launched directly or within containers. + +* The network should consist of five nodes named Alice, Bob, Cassandra, Driss, and Elena. The first three are validating nodes. Each node has a corresponding Ethereum address. +* Two different clients must be used, for instance, Geth and Nethermind +* The consensus mechanism must be clique. + +The network should be launched with the command `benchy launch-network`. The nodes should be launched in the background and the command should return immediately. + +## Infos + +Using the `infos` command, Benchy should display information on each node, in the terminal or in a webpage. The information must include: + +* Their latest block +* Their list of connected peers +* The number of transactions in their mempool +* Their current CPU and memory consumption (Hint: the outputs of commands such as `docker stats` or `ps` can be used) +* Their corresponding Ethereum address and its balance. + + +## Scenario + +To analyze our network, we need to simulate some transactions. Benchy should propose the following scenarios available with the command `benchy scenario X`. Each scenario must provide feedback on its execution, including updated balances after transfers. +0. Initialise the network by letting it run for a few minutes. Validating nodes must have Eth available as reward or part of the initial configuration. +1. Alice sends every 10 seconds 0.1 ETH to Bob +2. Cassandra deploys an ERC20 smart contract with 3000 tokens BY, and gives 1000 to Driss and 1000 to Elena. +3. Cassandra tries to send 1 ETH to Driss and immediately tries to cancel it by sending a transaction with a higher fee to send it to Elena. + +## temporary-failure + +To study our network further, benchy can disrupt the current network by randomly stopping one node of the network. The command “temporary-failure X” stops the node X for 40 seconds and puts it back online. + +## Optional + +* _an option `-u [time] runs any command continuously each ‘time’ in seconds, 60 by default._ +* _Add the possibility to connect one node to a testnet network _ + * _Infos displays information only about this node_ + * _`Scenario` runs the same scenarios on different addresses_ \ No newline at end of file diff --git a/subjects/blockchain/benchmarking-tool/audit/README.md b/subjects/blockchain/benchmarking-tool/audit/README.md new file mode 100644 index 000000000..6cb21665d --- /dev/null +++ b/subjects/blockchain/benchmarking-tool/audit/README.md @@ -0,0 +1,37 @@ +## Benchmarking tool audit + +#### Read the documentation +##### Does the README file contains the instructions to launch the project? +##### Are two different clients launched? +##### Is clique the consensus algorithm? + +#### Launch the network with the `launch-network` and display its status with `infos` +##### Does the command launch the five nodes? +##### Does the interface display the latest block of each node? +##### Does the interface display their Ethereum address and balance? +##### Does the interface display the CPU and memory consumption of each node? + +#### Launch scenario 0 +##### Does Alice, Bob and Cassandra have a positive balance of ETH? + +#### Launch scenario 1 +##### Does the command provide feedback? +##### Does the `infos` command show the updated ETH balance? +##### Does the `infos` command displays transactions in the mempool? + +#### Launch scenario 2 +##### Does the command provide feedback? +##### Do Driss and Elena appear to have received 1000 BY tokens? + +#### Launch scenario 3 +##### Does the command provide feedback? +##### Does the `infos` command show the updated balance of Elena receiving one ETH? + +#### Run `temporary-failure Alice` and launch `infos` +##### Is the node disabled in the `infos` output? +##### Does it come back online after 40 seconds? +##### Does it appear to be up to date a couple of minutes later? + +### Bonus +##### Does the `-u` option allow you to launch each command with a regular update? +##### Does the tool offer the possibility of launching a node connected to one of the testnet networks? diff --git a/subjects/blockchain/trading-platform/README.md b/subjects/blockchain/trading-platform/README.md new file mode 100644 index 000000000..e938aaa83 --- /dev/null +++ b/subjects/blockchain/trading-platform/README.md @@ -0,0 +1,182 @@ +# An international settlement platform + +_"Computer science education cannot make anybody an expert programmer any more than studying brushes and pigment can make somebody an expert painter." - Eric S. Raymond_ + +One of the key elements of blockchains' value proposition is providing the technology stack for the “internet of value”. For this, a combination with existing financial instruments is necessary. Several startups and experiments have been developed with this objective. + +In that context, we will build a trading platform. First, we will represent a stablecoin, shares and bonds on a private blockchain network. Then a marketplace website will allow users to list, buy and sell assets. + +In this project, you are free to use the blockchain, technologies, and tools that you want. However, the project must offer complete documentation. + +## Private network + +The network must have a minimum of 3 validating nodes. A script must facilitate the deployment of the network. You can reuse prior work. + +## Financial instruments + +Three categories of financial instruments can be exchanged on the platform. Functionally, each asset is a type of smart contract + +* **Stablecoins**: It must be a standard fungible token (ERC20 or equivalent). It initially has 1000 units. The creator of the stablecoin can issue or remove units. +* **Shares**: Shares are a fungible token for each company. Occasionally, its issuer can do a dividend payout. In that case, the issuer sends the stablecoin to the share contract, and each owner can retrieve proportionally to its possessions. +* **Bonds: **A smart contract represents all the outstanding bonds from an issuer. Each bond has a unique serial number, a current principal, an interest rate, an issuance date, a maturity date, a current owner, and if it has been repaid. For simplicity, we assume each bond to be issued for one year, requiring only one payment. + +## Populating + +In order to facilitate tests and audits, we will populate those financial instruments. An interactive script is available to create several addresses and deploy smart contracts. + +* A stablecoin called “triangle” with the ticker “TRG” and 4000 units available. +* Shares from “Clove Company” represented as “CLV” and “Rooibos Limited” “ROO”, with 100 shares each. +* Government bonds, “GOV”, for a principal of 200 each and an interest rate of 10%, 20 units. + +Each instrument is issued by a distinct address that owns all units initially. + +Additionally, the script asks for two Ethereum addresses, Aya and Beatriz. +- Aya should receive 200 TRG, 10 CLV and 2 GOV. +- Beatriz should receive 150 TRV, 20 ROO and 5 GOV. + + +## Marketplace + +The marketplace consists of + + + +* A web interface that allows users to visualise information and give orders. +* A server with an API and a database that stores listed assets and orders. +* A multi-signature vault smart contract that contains customer assets. + +Our model is hybrid, as order execution is centralised, but assets are not in full custody of the platform. + + +## Web interface + +The interface must consist of a homepage, an asset page, a portfolio page, and an FAQ page. + +### Homepage +An introduction page to the platform that allows the user to connect a wallet + +### Asset pages +A page per asset (only share and bonds) that provides on the left a curve with the price of prior trades and on the right control buttons + * The price by default is 10 TRG for a CLV and a ROO share and 200 TRG for GOV bonds. The curve is a straight line until trades are made. + * Command buttons allow users to + * Create a sell order for this asset or a buy order for this asset with an input field allowing them to select the number of units and establish a price. + * To buy or sell a certain asset at the current market price. + +### Portfolio page +A portfolio page that shows to the user his possessions. + +A table shows in one column the number of units available in total for each asset and another column with the amount currently stored on the platform with a button to withdraw it. Each asset name should redirect to the dedicated page. + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

+On platform

+ +

+Total available

+ +
TRG +

+0

+ +

+300

+ +
CLV +

+⬇️19

+ +

+19

+ +
ROO +

+0

+ +

+0

+ +
GOV +

+0

+ +

+5

+ +
+ +A visualization part allows the user to have a sense of his possession in TRG. For instance, a pie chart proportional to the current price of each asset can be displayed. For instance, assuming the default prices, the table above should render this way. + + ![alt_text](viz.png "Vizualisation") + +### FAQ page +An FAQ page that explains how to use the platform + + +## The server + +The server serves the fronted using the database information, exposes an API for the frontend and interacts with the blockchain. Its API must offer a function to monitor deposits, triggered from the user interface, that verifies on the blockchain the transaction that sent the funds and another one to authorise withdrawals. + +The database contains +* A table with the assets usable on the platform, their type, the address of their smart contract, and their price history. +* A table of the users of the platform registered after the first connection. They must provide their legal name and upload a “passport” picture. No check is made when login in, but the picture is stored for future reference +* A table of all ongoing sell and buy offers on the platform + + +## The vault smart contract + +The vault smart contract will receive the various financial assets. In a simple form, it includes an `operateWithdrawal(user, asset, amount)` reserved to the platform issuer allows the platform to send assets to the user, after verifying that the funds were theirs and that there are no pending orders. + +_Optionally, a more sophisticated security model can be proposed._ + + +## Trade execution + +If a user, Aya, wants to sell CLV shares, she will go to the dedicated CLV page. On the panel on the right, she will select a number of shares, for instance 5, among her total number of shares, and a price, for instance, 9. The shares will then be transferred to the smart contract of the platform. Her address however will be approved to retrieve. When a user, Beatriz, wants to buy 3 CLV shares at the current market price, he selects this option on the panel. The platform will select the best offers. In this example, it will retain the 3 shares of Aya as available. Then, the platform will update the balance of both users in its database. + +The platform must handle all the cases where various offers must be used to fulfil a demand. + + +## Withdrawal + +At any point, the users can ask to withdraw their funds. On their portfolio page, users can click on assets that are on the platform. The platform server verifies that the assets are not part of any pending offer and send an `operateWithdrawal()` to the vault smart contract. Once validated, the frontend updates the user information. + + +## Documentation + +In addition to the FAQ on the website explaining functionality as mentioned in the interface section, we need a full developer documentation. It must explain + +* How to launch and deploy the platform. It must contain a step-by-step guide to install dependencies and launch the project. +* Describe how to launch the populating script (see section populating) +* Describe the architecture of the project +* Specify each API function exposed from the server +* Describe in detail each smart contact function of the smart contract vault. + +The README file at the root of the project must specify where to find this documentation. + diff --git a/subjects/blockchain/trading-platform/audit/README.md b/subjects/blockchain/trading-platform/audit/README.md new file mode 100644 index 000000000..9b427d9bc --- /dev/null +++ b/subjects/blockchain/trading-platform/audit/README.md @@ -0,0 +1,35 @@ +## Trading Platform Audit + +#### Read the documentation +##### Does the README file contain or redirect to the instructions to launch the project? +##### Are the instructions to install and deploy the project usable to you? +##### Does the documentation contain a description of the architecture of the project? +##### Does the documentation contain details on the API and smart contract functions? + +#### Launch the project +##### Is a blockchain network running? +##### Can you display the web interface? +##### Does the homepage allow you to connect a wallet? + +#### Connect a wallet +##### Were you asked to provide a name and upload a passport picture? +##### Does your wallet appear to be connected? + +#### Use the provided script to populate the platform +##### Was the documentation clear enough to launch the populating script? +##### Does the website show the various digital assets? +##### Did the two accounts receive the corresponding asset looking at the portfolio page once connected? + +#### As the first user, Aya, opens the CLV page and offers to sell 10 CLV at 9 TRG +##### Does the interface reflect the amount of CLV available to Aya? +##### Does the order validation trigger a transfer of funds? + +#### As the second user, Beatriz, open the CLV page and buys 10 CLV at market price +##### Does the platform correctly offer to buy at 9 TRG? +##### Does the trade seem to execute? +##### Does Beatriz have 60 TRG and 10 CLV now? +##### Does Beatriz portfolio display a withdrawal button for CLV? + +#### From the portfolio page, click on withdraw for CLV +##### Does the transaction execute? +##### Does Beatriz now have full possession of its assets (in the second column)? diff --git a/subjects/blockchain/trading-platform/viz.png b/subjects/blockchain/trading-platform/viz.png new file mode 100644 index 0000000000000000000000000000000000000000..ccb80b862b728ebd18c11bdfb7e5a73cd1329e50 GIT binary patch literal 41288 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⪙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 Urv^KWP0$Cn)=vAYEf1diAHaw84gdfE literal 0 HcmV?d00001 diff --git a/subjects/shop/audit/README.md b/subjects/shop/audit/README.md index 6926f548a..b42f0d19d 100644 --- a/subjects/shop/audit/README.md +++ b/subjects/shop/audit/README.md @@ -1,93 +1,93 @@ -### Functional + ### Functional -##### Try to create a new user and login. + ##### Try to create a new user and login. -###### Can you confirm that the user was created? + ###### Can you confirm that the user was created? -##### Navigate to the homepage using the user you created. Try to erase products that were + ##### Navigate to the homepage using the user you created. Try to erase products that were -##### not created by the user. + ##### not created by the user. -###### Is it impossible to edit and delete products that were not created by your user? + ###### Is it impossible to edit and delete products that were not created by your user? -##### Try to sell a product by creating an add with the user created. + ##### Try to sell a product by creating an add with the user created. -###### Is it possible to create adds and sell a product using your user? + ###### Is it possible to create adds and sell a product using your user? -##### Navigate to the homepage and try to edit the add that you have created. + ##### Navigate to the homepage and try to edit the add that you have created. -###### Is it possible for you to edit your own add? + ###### Is it possible for you to edit your own add? -##### Try to create another new user, login and create at least two new adds. + ##### Try to create another new user, login and create at least two new adds. -###### Can you confirm that the new user and the adds were created? + ###### Can you confirm that the new user and the adds were created? -##### Login in with the first user and check if the adds created by the second user are there. + ##### Login in with the first user and check if the adds created by the second user are there. -###### Can you confirm that the adds created by the second user are present? + ###### Can you confirm that the adds created by the second user are present? -##### Navigate to the homepage with a user of your choice and try to delete an add that you have created. + ##### Navigate to the homepage with a user of your choice and try to delete an add that you have created. -###### Is it possible for you to delete your own add? + ###### Is it possible for you to delete your own add? -##### Navigate to the homepage with any user and try to check who is selling each product. + ##### Navigate to the homepage with any user and try to check who is selling each product. -###### Is it possible for you to see who is selling the products without opening the add? + ###### Is it possible for you to see who is selling the products without opening the add? -##### Navigate to the homepage and try to find the cart icon. + ##### Navigate to the homepage and try to find the cart icon. -###### Can you confirm that the cart icon is present in the homepage? + ###### Can you confirm that the cart icon is present in the homepage? -##### Try to add one item to the cart using the first user. + ##### Try to add one item to the cart using the first user. -###### Can you confirm that the item was added to the cart of the first user? + ###### Can you confirm that the item was added to the cart of the first user? -###### Did the message "Added to your cart" appear on the screen when you added something to the cart? + ###### Did the message "Added to your cart" appear on the screen when you added something to the cart? -###### Can you confirm that the cart icon in the homepage shows the number "1", meaning that you have one product in the cart? + ###### Can you confirm that the cart icon in the homepage shows the number "1", meaning that you have one product in the cart? -##### Try to add four more items to the cart. + ##### Try to add four more items to the cart. -###### Can you confirm that all the added items are present in the cart? + ###### Can you confirm that all the added items are present in the cart? -###### Can you confirm that the cart icon in the homepage shows the number "5", meaning that you have five products in the cart? + ###### Can you confirm that the cart icon in the homepage shows the number "5", meaning that you have five products in the cart? -##### Try to open your cart and check if you can see how much you have to pay for all the products in your cart. + ##### Try to open your cart and check if you can see how much you have to pay for all the products in your cart. -###### Can you confirm that the cart displays the total of all the products in your cart? + ###### Can you confirm that the cart displays the total of all the products in your cart? -##### Try to open your cart and remove one item from it. + ##### Try to open your cart and remove one item from it. -###### Can you confirm that the product was removed from the cart and the message "Removed from your cart" appeared on the screen? + ###### Can you confirm that the product was removed from the cart and the message "Removed from your cart" appeared on the screen? -##### Try to go to the cart and check the total. + ##### Try to go to the cart and check the total. -###### Can you confirm that the total was updated accordingly when you removed the item? + ###### Can you confirm that the total was updated accordingly when you removed the item? -###### Can you confirm that the cart item in the homepage was updated an shows the number "4", meaning that you have four products in the cart? + ###### Can you confirm that the cart item in the homepage was updated an shows the number "4", meaning that you have four products in the cart? -##### Try to login with the second user and check if the cart is empty. + ##### Try to login with the second user and check if the cart is empty. -###### Can you confirm that the cart is empty, and the cart from the first user was not carried to the second user? + ###### Can you confirm that the cart is empty, and the cart from the first user was not carried to the second user? -##### Try to logout and add items in the cart without any user. Now after you add items to the cart, login to one user of your choice. + ##### Try to logout and add items in the cart without any user. Now after you add items to the cart, login to one user of your choice. -###### Can you confirm that the items that you added to the cart are present in the user cart? + ###### Can you confirm that the items that you added to the cart are present in the user cart? -##### Try to add some items to the cart and then push the button `Empty cart`. After the message appears, confirm that you want to empty the cart. + ##### Try to add some items to the cart and then push the button `Empty cart`. After the message appears, confirm that you want to empty the cart. -###### Did the message "Are you sure?" appeared on the screen for you to confirm the action? + ###### Did the message "Are you sure?" appeared on the screen for you to confirm the action? -###### After the confirmation were you redirected to the homepage? + ###### After the confirmation were you redirected to the homepage? -### Bonus + ### Bonus -###### +Can you confirm that the student created or added something new like a new brand or the category field? + ###### +Can you confirm that the student created or added something new like a new brand or the category field? -###### +Can you add a product to the cart without opening the add? + ###### +Can you add a product to the cart without opening the add? -###### +If you add four products to the cart from the same seller, can you remove just one from the cart and keep the other three? + ###### +If you add four products to the cart from the same seller, can you remove just one from the cart and keep the other three? -###### +Did the student implement its own display and design? + ###### +Did the student implement its own display and design? -###### +Did the student implement a payment method? + ###### +Did the student implement a payment method?