Skip to content
This repository has been archived by the owner on Jul 28, 2022. It is now read-only.

Commit

Permalink
Sample application.
Browse files Browse the repository at this point in the history
This branch is the basic implementation, without any GSN support.

- The "workshop-with-gsn" is the same app with GSN support
- The "workshop-with-paymaster" is the same app with GSN and custom
paymaster
  • Loading branch information
drortirosh committed Jun 13, 2021
1 parent ef3a7b5 commit 9458b96
Show file tree
Hide file tree
Showing 13 changed files with 7,863 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.sol linguist-language=Solidity
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/node_modules/
/.idea/
/.DS_Store
/build/
/html/
19 changes: 19 additions & 0 deletions contracts/CaptureTheFlag.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* SPDX-License-Identifier:MIT
*/
pragma solidity ^0.7.6;

contract CaptureTheFlag {

event FlagCaptured(address previousHolder, address currentHolder);

address public currentHolder = address(0);

function captureTheFlag() external {
address previousHolder = currentHolder;

currentHolder = msg.sender;

emit FlagCaptured(previousHolder, currentHolder);
}
}
21 changes: 21 additions & 0 deletions contracts/Migrations.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* SPDX-License-Identifier:MIT
*/
pragma solidity >=0.4.25 <0.8.0;

contract Migrations {
address public owner;
uint public last_completed_migration;

modifier restricted() {
if (msg.sender == owner) _;
}

constructor() {
owner = msg.sender;
}

function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
}
5 changes: 5 additions & 0 deletions migrations/1_initial_migration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const Migrations = artifacts.require("Migrations");

module.exports = function(deployer) {
deployer.deploy(Migrations);
};
5 changes: 5 additions & 0 deletions migrations/2_deploy_contracts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const CaptureTheFlag = artifacts.require('CaptureTheFlag')

module.exports = async function (deployer) {
await deployer.deploy(CaptureTheFlag)
}
25 changes: 25 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "01_simple_use",
"version": "2.2.0",
"description": "Simple example of how to use GSNv2",
"private": true,
"dependencies": {
"@opengsn/cli": "^2.2.2",
"@opengsn/contracts": "^2.2.2",
"@opengsn/provider": "^2.2.2",
"browserify": "^17.0.0",
"ethers": "^5.3.0",
"ganache-cli": "^6.12.2",
"run-with-testrpc": "^0.3.1",
"serve": "^11.3.2",
"web3": "^1.3.6"
},
"scripts": {
"ganache": "yarn run ganache-cli -d --chainId 1337",
"test": "run-with-testrpc 'truffle test'",
"compile": "truffle compile",
"start": "truffle deploy && ./ui/compile.sh && yarn serve ./html"
},
"author": "",
"license": "ISC"
}
21 changes: 21 additions & 0 deletions test/testcontracts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const CaptureTheFlag = artifacts.require('CaptureTheFlag')

const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'

contract("CaptureTheFlag", async accounts => {

it ('Runs without GSN', async () => {
const captureFlagContract = await CaptureTheFlag.new();

const res = await captureFlagContract.captureTheFlag();
assert.equal(res.logs[0].event, "FlagCaptured", "Wrong event");
assert.equal(res.logs[0].args.previousHolder, ZERO_ADDRESS, "Wrong previous flag holder");
assert.equal(res.logs[0].args.currentHolder, accounts[0], "Wrong current flag holder");

const res2 = await captureFlagContract.captureTheFlag({from: accounts[1]});
assert.equal(res2.logs[0].event, "FlagCaptured", "Wrong event");
assert.equal(res2.logs[0].args.previousHolder, accounts[0], "Wrong previous flag holder");
assert.equal(res2.logs[0].args.currentHolder, accounts[1], "Wrong current flag holder");
});

});
17 changes: 17 additions & 0 deletions truffle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
var mnemonic = 'wild render law slight strike seven close damp glory jaguar dawn scan';
var kovanUrl = "https://kovan.infura.io/v3/c3422181d0594697a38defe7706a1e5b";

module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 8545,
network_id: "*"
}
},
compilers: {
solc: {
version: "0.7.6"
}
}
};
11 changes: 11 additions & 0 deletions ui/compile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#! /bin/bash -e

rm -rf ./html/
mkdir ./html/

#browserify ./ui/index.js | tr -dc '\0-\177' > ./html/bundle.js
browserify ./ui/index.js -o ./html/bundle.js
cp ./ui/index.html ./html/

echo Done at
date
28 changes: 28 additions & 0 deletions ui/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<html>
<head>

<title>GSNv2 Test</title>

<script src="bundle.js">
</script>

</head>
<body>
<h2>GSNv2 Test App</h2>

<script>
window.app.initContract().then(function ({contractAddress, network}) {
console.log( 'CaptureTheFlag contract', contractAddress)
console.log(`identified network: ${JSON.stringify(network)}`)
document.getElementById('capture_button').disabled = false
})
</script>

<button id="capture_button" disabled onClick="window.app.contractCall()">
Capture the flag
</button>

<hr>
<div id="logview"> </div>
</body>
</html>
71 changes: 71 additions & 0 deletions ui/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const ethers = require('ethers')

const contractArtifact = require('../build/contracts/CaptureTheFlag.json')
const contractAbi = contractArtifact.abi

let theContract
let provider

async function initContract() {

if (!window.ethereum) {
throw new Error('provider not found')
}
window.ethereum.on('accountsChanged', () => {
console.log('acct');
window.location.reload()
})
window.ethereum.on('chainChanged', () => {
console.log('chainChained');
window.location.reload()
})
const networkId = await window.ethereum.request({method: 'net_version'})

provider = new ethers.providers.Web3Provider(window.ethereum)

const network = await provider.getNetwork()
const artifactNetwork = contractArtifact.networks[networkId]
if (!artifactNetwork)
throw new Error('Can\'t find deployment on network ' + networkId)
const contractAddress = artifactNetwork.address
theContract = new ethers.Contract(
contractAddress, contractAbi, provider.getSigner())

await listenToEvents()
return {contractAddress, network}
}

async function contractCall() {
await window.ethereum.send('eth_requestAccounts')

const transaction = await theContract.captureTheFlag()
const hash = transaction.hash
console.log(`Transaction ${hash} sent`)
const receipt = await provider.waitForTransaction(hash)
console.log(`Mined in block: ${receipt.blockNumber}`)
}

let logview

function log(message) {
message = message.replace(/(0x\w\w\w\w)\w*(\w\w\w\w)\b/g, '<b>$1...$2</b>')
if (!logview) {
logview = document.getElementById('logview')
}
logview.innerHTML = message + "<br>\n" + logview.innerHTML
}

async function listenToEvents() {

theContract.on('FlagCaptured', (previousHolder, currentHolder, rawEvent) => {
log(`Flag Captured from&nbsp;${previousHolder} by&nbsp;${currentHolder}`)
console.log(`Flag Captured from ${previousHolder} by ${currentHolder}`)
})
}

window.app = {
initContract,
contractCall,
log
}

Loading

0 comments on commit 9458b96

Please sign in to comment.