Solidity Smart Contracts now on β¨ Polkadot Network
Demo dapp showcasing Uniswap V2 on Polkadot using PolkVM and @parity/hardhat-polkadot with Solidity smart contracts and hardhat. Leverage the power of the Polkadot ecosystem to build a decentralized exchange with PolkVM and standard tools like Hardhat and TypeScript with custom hardhat-polkadot plugins.
Contracts: uniswap/contracts
First Step: Choose Devcontainers or Local Setup
Read the GitHub Docs
- Option 1: Create GitHub Codespace from the GitHub UI
- Option 2: Use a template string:
https://codespaces.new/OWNER/REPO-NAME
- Replace
OWNER
with your GitHub name - Replace
REPO-NAME
with whatever you named this repo
- Replace
Create an Open in GitHub Codespaces Badge:
- Option 3: Replace the fields as indicated
[](https://codespaces.new/OWNER/REPO-NAME)
Guide built for macOS
Instructions available here: Local environment setup For support, visit the Discord
Install protobuf
brew update && brew install protobuf
Install SSL
brew install openssl
Install Rustup(Standard installation)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Update terminal Example command for zsh users
if [ -r ~/.zshrc ]; then echo -e '. "$HOME/.cargo/env"' >> ~/.zshrc; \
else echo -e '. "$HOME/.cargo/env"' >> ~/.zprofile; fi
Update Rust and set target
rustup default stable &&
rustup update &&
rustup target add wasm32-unknown-unknown &&
rustup component add rust-src &&
rustup show
Verify rust install
rustup show &&
rustc --version &&
cargo --version
Install cmake
brew install cmake
- You can also use Docker
- This approach is experimental
Run Substrate Server
- Spin up Substrate node
- Start up eth adapter
pnpx hardhat node
Error Output:
starting server ...
------------------------------------------
β‘οΈ running in production (standard) mode β‘οΈ
------------------------------------------
ErrorEvent {
type: 'error',
defaultPrevented: false,
cancelable: false,
timeStamp: 1679.599333
}
Fork live Testnet
pnpx hardhat node --fork https://testnet-passet-hub.polkadot.io
\ --adapter-binary-path /Users/chrisanatalio/IdeaProjects/polkavm-hardhat-examples/uniswap/bin/eth-rpc
Or use the plugin native way to spin up a node
pnpx hardhat node-polkadot
Download Polkadot SDK GitHub Release binary
- Westend Testnet Relay Chain Runtime
- Saves wasm as filename:
westend_runtime-v1019002.compact.compressed.wasm
- Prints filename to console and adds to your .env file as
SUBSTRATE_SERVER_FILE_NAME
curl --proto '=https' --tlsv1.2 -sSfLO \
https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506/westend_runtime-v1019002.compact.compressed.wasm -w "%{filename_effective}" \
| xargs -0 -I {} echo "SUBSTRATE_SERVER_FILE_NAME={}" |tee .env
//TODO pull keys from https://github.com/paritytech/hardhat-polkadot/blob/main/packages/hardhat-polkadot-node/src/constants.ts#L22
Verify your workspace is configured correctly:
rustc --version && cargo version && nvm current
Setup steps:
- Setup Project
- Compile and Test your Contract
- Deploy contract and setup env
- Interact with a deployed contract
Next Step: Setup project
Install dependencies
pnpm install
Strict Mode(Catch potential errors at build time) This is optional, but recommended.
pnpm install --strict-peer-dependencies --no-optional && pnpm update
Next Step: Build/Test Contract
- Compile your contract
- Test your contract
Compile your contract(With type checking):
pnpx hardhat compile --typecheck
Run your tests:
pnpx hardhat test --network localNode
Verify:
Next Step: Deploy Contract
- Setup up account using Hardhat vars
- Use Hardhat Ignition to deploy contract using
.env
vars - Sets Deployed contract address
- Faucet: https://faucet.polkadot.io/?parachain=1111
pnpx hardhat vars set PRIVATE_KEY "INSERT_PRIVATE_KEY"
Deploy using Ignition Modules:
- Use the and from
.env
- Sets the output package to
- Sets Deployed contract address to
We have included packages
in our include statement in tsconfig.json
Verify your Deployed Contract:
Review
- Your
.env
file with everything you need to build a dapp around your Contract
Now let's invoke the deployed contract.
- The id of the deployed contract, our default source account and the public key are stored in our
.env
file - Which will invoke the
mint()
function passing in the Owner public key as the recipient
Execute this command:
Output type(json):
We showed you how to use the PAPI CLI to invoke your contract, now let's do it with the JavaScript SDK
Parameters:
- contract_id (optional)βDeployed contract ID
- SOURCE_KEYPAIR (optional)
Execute:
We will now create a backend to provide data for your UI. We will take a flexible approach to building a dapp backend, giving your working examples of various ways to supply data to your client front-end.
Indexers extract and transform raw blockchain data and present the data in a format that is more easily consumable by a front-end client.
Indexers are generally provided as third-party services. The following nest.js service is a micro-indexer
primarily
built to consume
contract events emitted by your contract and presents them to your front-end client in a streaming event-driven format.
Available Formats:
- β Server Sent Events -> https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events
- Websocket -> TODO
- GraphQL -> TODO
- JSON REST API -> TODO
Mock Data vs Testnet:
- Mock data streams allow you to quickly iterate on your front-end UI without having to stage data on-chain. This data will be generated according to the schema to ensure it works with live testnet data.
- Testnet data streams will include the ability to invoke the
mint()
function to generate testnet data
Run locally
Choose a Testnet RPC Provider
Start locally:
pnpm start:dev
Backend:
- Using SSE
- Moves complex code from front-end to backend
- Push JSON, HTML code, or React components or fragments to your front-end client
Front-end β Single HTML file
- Check out
mock-sse.html
ormock-sse-by-contractid.html
for a working example - Requires running micro-indexer on port
3000
Backend SSE Example
- This example uses RxJS to generate a stream of MessageEvents pushed to a front-end client
- Example stream URL:
@Sse('sse/:contractId')
sse_by_contract_id(
@Param('contractId') contractId: string,
): Observable<MessageEvent> {
return interval(1000).pipe(
map(
this.stellarMockEventService.transformMessageEventWithContract(
contractId,
),
),
);
}
Update the contract to make it truly yours.
- Update the contract
- Re-build the contract
- Upgrade the deployed contract
- Re-generate contract bindings
Open up the contract uniswap/contracts/src/contract.
Modify
Execute this command:
TODO
The method of UI creation is a template that is actively maintained, 500+ deployments, and full test suite + static analysis with app generation test. 218 GitHub stars.
-
Generates Next.js boilerplate basic UI
Related
//TODO Organize
- https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/revive/rpc/examples/westend_local_network.toml
- https://github.com/paritytech/polkadot-sdk/tree/master/substrate/frame/revive/rpc/examples
- https://github.com/paritytech/evm-test-suite/tree/main/eth-rpc
- https://github.com/AcalaNetwork/Acala/tree/master/modules/evm
- https://hub.docker.com/r/acala/eth-rpc-adapter/tags
- https://github.com/AcalaNetwork/Acala/releases/download/2.30.0/acala_runtime_tracing_2300.compact.compressed.wasm
- https://github.com/paritytech/hardhat-polkadot/blob/500cba0310fad38cf01cc7b11cb2e4043bd71482/packages/hardhat-polkadot-node/src/type-extensions.ts#L4
- https://github.com/paritytech/hardhat-polkadot/blob/main/packages/hardhat-polkadot-node/src/services/eth-rpc.ts
- https://github.com/paritytech/hardhat-polkadot/blob/main/packages/hardhat-polkadot-node/src/services/substrate-node.ts
Feel free to check the documentation or jump into the Discord server.