diff --git a/.gitignore b/.gitignore index 915f6ef..c391d98 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,24 @@ -# Draft files (to be removed) -*.sl.* +# Draft files and solutions dft* -*.sol +student* ## Potential key files *.txt *.pem +*.cer *key* ## Typical unecessary files & folders package-lock.json node_modules/ .vscode +pnpm-lock.yaml -## build folders & files +## Build folders & files (should not be necessary when everyting is run in docker) build/ artifacts/ cache/ coverage/ coverage.json -bin/ \ No newline at end of file +bin/ +solc \ No newline at end of file diff --git a/introductions.md b/introductions.md index c9975fa..f698514 100644 --- a/introductions.md +++ b/introductions.md @@ -19,7 +19,7 @@ You should not use any crypto with value for any exercise of the module. If you 1. [sendTransaction](sendTransaction/README.md) _Send a Bitcoin transaction_ 2. [retrieveBlockDate](retrieveBlockDate/README.md) _get a block date_ 3. [retrieveTransactionValue](retrieveTransactionValue/README.md) _get the value of a transaction_ -4. [sendTransactionToPeer](sendTransactionToPeer/README.md) _send a bitcoin transaction to a peer +4. [sendTransactionToPeer](sendTransactionToPeer/README.md) _send a bitcoin transaction to a peer_ 5. [sendEthTransaction](sendEthTransaction/README.md) _Send a transaction to an address on a testnet_ #### Optional @@ -74,8 +74,7 @@ node test.mjs ### Festival Smart Contract Quest -*We didn't take the Bastille to make an opera out of it! - -Pierre Desproges* +*We didn't take the Bastille to make an opera out of it! - Pierre Desproges* Today we will build our first Smart Contracts. Smart Contracts are programs deployed on a blockchain network to provide additional functionalities. In the context of this quest, we will focus on Ethereum Smart Contracts. There main development language is Solidity. @@ -116,7 +115,7 @@ npx hardhat test tests/.test.js ### Anchoring -A simple use of blockhains is to anchor documents. We will hash documents and store them in a blockchain. +A simple use of blockchains is to anchor documents. We will hash documents and store them in a blockchain. For this, we will use a local test node and interact with it using JavaScript @@ -255,9 +254,9 @@ In addition, each token is linked to an Uniform Resource Identifier (URI) where *I accidentally killed it - devops199* -It is time for us to advance beyond basic contracts for integrate with actual DeFi smart contrat. For this we will need to use current standards and implementations. +It is time for us to advance beyond basic contracts for integrate with actual DeFi smart contract. For this we will need to use current standards and implementations. -First, we will create a simple stablecoin, following the ERC20 standart and an oracle. We will then create a decentralised exchange that will allow us to exchange our stablecoin. Finally, we will create the tests for this project. +First, we will create a simple stablecoin, following the ERC20 standard and an oracle. We will then create a decentralised exchange that will allow us to exchange our stablecoin. Finally, we will create the tests for this project. #### Content 1. [stablecoin](stablecoin/README.md) diff --git a/tests/.gitignore b/tests/.gitignore deleted file mode 100755 index 1d92022..0000000 --- a/tests/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -## Exclusions specific to this folder -student -cache -artifacts -solc \ No newline at end of file diff --git a/tests/btc/retrieve-block-date.test.js b/tests/btc/retrieve-block-date.test.js index 5aa9be1..87075fc 100644 --- a/tests/btc/retrieve-block-date.test.js +++ b/tests/btc/retrieve-block-date.test.js @@ -1,15 +1,15 @@ -const { expect } = require("chai"); -const Client = require('bitcoin-core'); -const {retrieveBlockDate}= require("/jail/student/retrieve-block-date.js") +const { expect } = require("chai") +const Client = require('bitcoin-core') +const { retrieveBlockDate } = require("/jail/student/retrieve-block-date.js") -describe("retrieve block date", function() { +describe("retrieve block date", function () { let client, hashLatest, timeLatest - beforeEach( async function () { - client = new Client({ - network: 'regtest', - username: 'leeloo', - password: 'multipass', + beforeEach(async function () { + client = new Client({ + network: 'regtest', + username: 'leeloo', + password: 'multipass', port: 18443 //18445 }) hashLatest = await client.getBestBlockHash() @@ -17,7 +17,7 @@ describe("retrieve block date", function() { timeLatest = block.time }) - it("latest block is ok", async function() { + it("latest block is ok", async function () { let retrievedTime = await retrieveBlockDate(hashLatest) expect(retrievedTime).to.equal(timeLatest) }) diff --git a/tests/btc/retrieve-transaction-in-out.test.js b/tests/btc/retrieve-transaction-in-out.test.js index b6732e2..86a1b82 100644 --- a/tests/btc/retrieve-transaction-in-out.test.js +++ b/tests/btc/retrieve-transaction-in-out.test.js @@ -1,27 +1,27 @@ -const { expect } = require("chai"); -const Client = require('bitcoin-core'); -const {retrieveTransactionInOut}= require("/jail/student/retrieve-transaction-in-out.js") +const { expect } = require("chai") +const Client = require('bitcoin-core') +const { retrieveTransactionInOut } = require("/jail/student/retrieve-transaction-in-out.js") -describe("retrieve transaction ins and outs", function() { +describe("retrieve transaction ins and outs", function () { let client, hashLatest, txLatest - beforeEach( async function () { - client = new Client({ - network: 'regtest', - username: 'leeloo', - password: 'multipass', + beforeEach(async function () { + client = new Client({ + network: 'regtest', + username: 'leeloo', + password: 'multipass', port: 18443 }) }) - - it("Value of the latest transaction is correct", async function() { + + it("Value of the latest transaction is correct", async function () { let hashLatest = await client.getBestBlockHash() - console.assert(hashLatest!=null) + console.assert(hashLatest != null) let block = await client.getBlockByHash(hashLatest) let values = [] // expect a second transaction in the latest block (see dockerfile) if (typeof block.tx[1] !== 'undefined') { - for (const vout of block.tx[1].vout) { + for (const vout of block.tx[1].vout) { values.push(vout.value) } } else { @@ -31,6 +31,6 @@ describe("retrieve transaction ins and outs", function() { let retrievedInOuts = await retrieveTransactionInOut(txLatest) expect(retrievedInOuts.out).to.deep.equal(values) }) - + }) diff --git a/tests/js/local-node.test.js b/tests/js/local-node.test.js index c839188..12f8843 100644 --- a/tests/js/local-node.test.js +++ b/tests/js/local-node.test.js @@ -1,14 +1,14 @@ -const { expect } = require("chai"); +const { expect } = require("chai") -describe("Have you read the tutorial?", function() { +describe("Have you read the tutorial?", function () { let register = {} - beforeEach( async function () { + beforeEach(async function () { }) - it("Should validate", async function() { + it("Should validate", async function () { expect(0).to.be.equal(0) - }); + }) }); diff --git a/tests/js/send-eth-transaction.test.js b/tests/js/send-eth-transaction.test.js index 5dd87bb..fcf7379 100644 --- a/tests/js/send-eth-transaction.test.js +++ b/tests/js/send-eth-transaction.test.js @@ -6,7 +6,6 @@ let {txid} = require("/jail/student/send-eth-transaction.js"); function isSha256(h) { h = h.slice(2) - console.log(h) const regex = /^[a-f0-9]{64}$/gi return regex.test(h) } @@ -18,7 +17,7 @@ describe('Send transaction', function () { }); - +// Prior version of the test using test.mjs // // /*/ // ⚡ // setup = function (params) { diff --git a/tests/mjs/test.mjs b/tests/mjs/test.mjs deleted file mode 100644 index 1c7b92c..0000000 --- a/tests/mjs/test.mjs +++ /dev/null @@ -1,124 +0,0 @@ -// Modified version of js/tests/tests.mjs to run nodejs code XL -const DEBUG = true - - -import { join as joinPath, dirname } from 'path' -import { fileURLToPath } from 'url' -import { deepStrictEqual } from 'assert' -import * as fs from 'fs' -const { readFile, writeFile } = fs.promises -// eval for nodejs code -import { createRequire } from 'module'; -const require = createRequire(import.meta.url); -// const vm = require('vm') -// import * as vm from 'vm' - - -global.window = global -global.fetch = (url) => { - // this is a fake implementation of fetch for the tester - // -> refer to https://devdocs.io/javascript/global_objects/fetch - const accessBody = async () => { throw Error('body unavailable') } - return { - ok: false, - type: 'basic', - status: 500, - statusText: 'Internal Server Error', - json: accessBody, - text: accessBody, - } -} - -const wait = delay => new Promise(s => setTimeout(s, delay)) -const fail = fn => { try { fn() } catch (err) { return true } } -const { join } = [] -const { split } = '' -const eq = (a, b) => { - const noSplit = !''.split - const noJoin = ![].join - String.prototype.split = split - Array.prototype.join = join - deepStrictEqual(a, b) - noSplit && (String.prototype.split = undefined) - noJoin && (Array.prototype.join = undefined) - return true -} - -const name = process.argv[2] -const fatal = (...args) => { - console.error(...args) - process.exit(1) -} - -if (!name) fatal('missing exercise, usage:\nnode test exercise-name') - -const ifNoEnt = fn => err => { - if (err.code !== 'ENOENT') throw err - fn(err) -} - -const root = dirname(fileURLToPath(import.meta.url)) -const read = (filename, description) => - readFile(filename, 'utf8').catch( - ifNoEnt(() => fatal(`Missing ${description} for ${name}`)), - ) - -const stackFmt = (err, url) => { - if (!(err instanceof Error)) { - throw Error(`Unexpected type thrown: ${typeof err}. usage: throw Error('my message')`) - } - String.prototype.split = split - Array.prototype.join = join - return err.stack.split(url).join(`${name}.js`) -} - -const main = async () => { - const [test, rawCode] = await Promise.all([ - read(joinPath(root, `${name}.test.js`), 'test'), - // Local version XL - read(joinPath(root, `${name}.sl.js`), 'student solution'), - // Prod XL - // read(`/jail/student/${name}.js`, 'student solution'), - ]) - - // this is a very crude and basic removal of comments - // since checking code is only use to prevent cheating - // it's not that important if it doesn't work 100% of the time. - const code = rawCode.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, '').trim() - if (code.includes('import')) fatal('import keyword not allowed') - - const parts = test.split('// /*/ // ⚡') - const [inject, testCode] = parts.length < 2 ? ['', test] : parts - const combined = `${inject.trim()}\n${rawCode - .replace(inject.trim(), '') - .trim()}\n${testCode.trim()}\n` - - // const b64 = Buffer.from(combined).toString('base64') - // const url = `data:text/javascript;base64,${b64}` - // const { setup, tests } = await import(url).catch(err => - // fatal(`Unable to execute ${name} solution, error:\n${stackFmt(err, url)}`), - // ) - // let sandBox1 = vm.createContext({foo:'bar', require}); - // vm.runInThisContext(combined,sandBox1) - // Node eval XL - const tests = [] - let setup - const t = (f) => tests.push(f) - eval(combined) - - const ctx = (await ( setup && setup())) || {} - const tools = { eq, fail, wait, code, ctx } - for (const [i, t] of tests.entries()) { - try { - if (!await t(tools)) { - throw Error('Test failed') - } - } catch (err) { - console.warn("\x1b[33m",`Test #${i} failed:\n${t.toString()}\n`, "\x1b[0m") - fatal(stackFmt(err))//, url)) - } - } - console.log("\x1b[32m",`\n✔ ${name} passed (${tests.length} tests)`, "\x1b[0m") -} - -main().catch(err => fatal(err.stack)) diff --git a/tests/sol/namedFestival.test.js b/tests/sol/namedFestival.test.js deleted file mode 100755 index b327f97..0000000 --- a/tests/sol/namedFestival.test.js +++ /dev/null @@ -1,36 +0,0 @@ -const { expect } = require("chai") -const { ethers } = require("hardhat") - -// For optimisation, as it is mostly checks, tests on the same instance -describe("Festival Name", function() { - let Festival, festival, deployed - - before( async function () { - Festival = await ethers.getContractFactory("NamedFestival") - }) - - it("Should deploy", async function() { - festival = await Festival.deploy() - deployed = await festival.deployed() - expect(deployed.hasOwnProperty("deployTransaction")).to.be.true - }) - - it("Should have an getName function", async function() { - expect(deployed.functions.hasOwnProperty("getName")).to.be.true - }) - - it("Should have an setName function", async function() { - expect(deployed.functions.hasOwnProperty("setName")).to.be.true - }) - - it("Should be able to set a name ", async function() { - let response = await festival.setName("Sziget mundo!") - let receipt = await response.wait() - expect(receipt.status).to.equal(1) - }) - - it("Should change name and return new one", async function() { - await festival.setName("Sziget mundo2!") - expect(await festival.getName()).to.equal("Sziget mundo2!") - }) -}) \ No newline at end of file