Skip to content

Commit 14e4cef

Browse files
authored
add evm getting started section (#179)
1 parent ab3544f commit 14e4cef

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed

docs/.vuepress/configs/sidebar.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ export const sidebar: Record<string, SidebarConfig> = {
8686
text: 'EVM',
8787
children: [
8888
'/build/evm/',
89+
'/build/evm/getting-started.md',
8990
'/build/evm/accounts.md',
9091
{
9192
text: 'Smart contracts',

docs/build/evm/getting-started.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# Getting started
2+
3+
We prepared this document in the hopes that it will answer most of your questions regarding the matter of implementing native NFTs in the context of your Solidity-centric application.
4+
5+
The premise of this document is as follows (for whom this document is intended):
6+
7+
- your non-native NFT project has been principally developed on and for an Ethereum-based, general-contract, ERC-721 concept NFT environment
8+
- you wish to transform your ERC-721 collection to a native version of the NFT because you desire to implement the advanced features provided to the NFTs in the Unique network in you application
9+
- you wish to have access to the methods that provide these features in your Solidity contracts if necessary
10+
- you do not want to write complex code to use the new features
11+
- you need to retain any already created Solidity contracts that provide crucial application functionality and you do not want to make radical changes to your contracts to be able to adapt your existing code
12+
- you need access to both Ethereum and Substrate address spaces so your existing Solidity contracts can interact in both spaces
13+
- you wish to be able to provide access to your app to wallets in both address spaces (Metamask, Subwallet, Talisman, Wallet Connect wallets, etc) without a complex recoding of your contracts
14+
15+
Since your core functionality is provided via Solidity contracts, we have taken care to provide you with as much examples and instructions as possible to help you navigate the transition from the existing ERC-721 tokens to the Unique native model.
16+
17+
:::tip
18+
One note to be mindful of is: the most efficient way of accomplishing this goal is by using the Unique SDK 2.0. It will provide you with the framework, the tools and the methods to make this fast and easy, so do brush up on your Typescript if you have been away from it for a while. It will save you an enormous amount of time. To make it as real-world as possible, we have implemented our SDK calls in a React framework so you can gauge how the SDK functions in a UI context and you can see it all in the video listed below.
19+
:::
20+
21+
That said...
22+
23+
Once you read through this document, we propose that you attempt to replicate the following steps to master your challenge:
24+
25+
1. Create a wallet selector that uses any of {Polkadot.js wallet, Subwallet, Talisman, Metamask, Wallet Connect} wallet to connect to your app.
26+
2. Create a collection using the SDK
27+
3. Mint a token using the SDK
28+
4. Write a Solidity contract in the EVM to use with the native NFT to change some NFT attribute, for example
29+
5. Call that contract from the SDK
30+
6. Nest a token
31+
32+
ALL the examples for this except point 6 are shown in this video: https://youtu.be/Cid_Ui5e0rk
33+
34+
To nest, you just send a native token to a native token address as though it is a wallet using a simple send call via the SDK. That's all. Nesting doesn't even have a dedicated method. It is a simple send of a token to another tokens address.
35+
36+
Read on...
37+
38+
39+
# 1. EVM and Substrate
40+
41+
There are two types of accounts – Substrate (5Grw...) and EVM (0x...)
42+
In terms of calling contracts:
43+
- EVM accounts operate the same way as in Ethereum, nothing special
44+
- Substrate accounts cannot call EVM contracts directly because EVM works only with EVM accounts. But they can do it through the `evm.call` extrinsic (in SDK - `sdk.evm.send` method). For contract, `msg.sender` will be Substrate's account mirror – EVM account. To calculate the Substrate account mirror, use the `Address` utility from `@unique-nft/utils`
45+
46+
```ts
47+
import { Address } from "@unique-nft/utils";
48+
49+
const ethMirror = Address.mirror.SubstrateToEthereum('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY');
50+
// 0xd43593c715Fdd31c61141ABd04a99FD6822c8558
51+
```
52+
53+
or play with the converter in the documentation – https://docs.unique.network/reference/tools.html
54+
55+
It is essential to understand that mirror calculation is a one-way operation. You cannot calculate the origin address from its mirror.
56+
57+
```ts
58+
import { Address } from "@unique-nft/utils";
59+
60+
const ethMirror = Address.mirror.SubstrateToEthereum('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY');
61+
// 0xd43593c715Fdd31c61141ABd04a99FD6822c8558
62+
63+
const subMirrorBack = Address.mirror.EthereumToSubstrate('0xd43593c715Fdd31c61141ABd04a99FD6822c8558');
64+
// !!! different address 5FrLxJsyJ5x9n2rmxFwosFraxFCKcXZDngRLNectCn64UjtZ != 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
65+
```
66+
67+
It is also worth noting that the EVM mirror cannot be controlled directly (e.g., it cannot be added to MetaMask).
68+
69+
### `CrossAddress` struct
70+
71+
To make direct interaction between contracts and Substrate accounts possible, we support the `CrossAddress` struct in Solidity. This struct represents the "Ethereum or Substrate" account.
72+
73+
```Solidity
74+
// Solidity
75+
struct CrossAddress {
76+
address eth;
77+
uint256 sub;
78+
}
79+
```
80+
81+
* For the EVM account, set the `eth` property with the EVM address (0x...), and the `sub` should be 0.
82+
* For the Substrate account, set the `sub` property with the Substrate public key (not address!). The `eth` property should be equal to Ethereum zero address (0x000...00000);
83+
84+
To calculate Substrate public key from an address in Javascript, use `Address` utils.
85+
86+
```ts
87+
import { Address } from "@unique-nft/utils";
88+
89+
const publicKey = Address.extract.SubstratePublicKey("5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY");
90+
```
91+
92+
or convert the address to CrossAccount directly:
93+
94+
```ts
95+
const cross = Address.extract.ethCrossAccountId(
96+
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
97+
// or "0xd43593c715Fdd31c61141ABd04a99FD6822c8558"
98+
);
99+
```
100+
101+
A lot of examples of how to use CrossAddress with EVM and Substrate accounts can be found in recipes of unique-contracts repo. For example:
102+
- minter contract: https://github.com/UniqueNetwork/unique-contracts/blob/main/contracts/recipes/Minter.sol#L100
103+
- test: how to call the minter contract with EVM account https://github.com/UniqueNetwork/unique-contracts/blob/main/test/minter.spec.ts
104+
- test: how to call the minter contract with Substrate account: https://github.com/UniqueNetwork/unique-contracts/blob/main/test/minter.spec.ts
105+
106+
## Signers and Wallets
107+
108+
Documentation section on how to build applications, and specifically connecting accounts
109+
https://docs.unique.network/build/sdk/v2/dapps.html#connecting-accounts
110+
111+
It could be much easier to understand playing with code. Here is a react template: https://github.com/UniqueNetwork/unique-react-template
112+
113+
## SDK
114+
115+
SDK is only for Substrate accounts (remember that Substrate accounts can invoke contracts).
116+
The build section of the documentation explains all the needed concepts - https://docs.unique.network/build/sdk/v2/quick-start.html
117+
118+
## Why it makes sense to use the schema 2.0 and why you don't have to if you do not need it.
119+
120+
Unique Network implements NFTs natively – they are not contracts.
121+
122+
And yes, because of EVM support, plain ERC-721 NFTs can be created. However, no wallets, marketplaces, or other UIs in the ecosystem track this type of NFTs.
123+
124+
We support Unique Schema 2.0, an OpenSea compatible, on-chain metadata format, to make your metadata readable for all interfaces. So, you need to stick this format until you understand why not.
125+
126+
However, there is good news—if you use SDK or unique contracts, you don't need to understand this format in detail. You only need to understand its features. Everything else is handled for you.
127+
128+
The reference section in the documentation explaining all the features of unique schema – https://docs.unique.network/reference/schemas
129+
The js library for the unique schema. You don't need it if you use SDK https://github.com/UniqueNetwork/unique_schemas
130+
131+
# How to call EVM contracts using Substrate account and SDK
132+
133+
docs – https://docs.unique.network/build/sdk/v2/evm.html
134+
135+
EVM workshop – https://github.com/UniqueNetwork/unique-react-template/tree/workshop-EVM
136+
- [This function](https://github.com/UniqueNetwork/unique-react-template/blob/ab923457ece54f6ac6d1f2f47fc08ea52363dad1/src/pages/BreedingPage.tsx#L58-L107) covers how to invoke contracts
137+
138+
Long story short:
139+
140+
- You save the contract's ABI as JSON file and import it
141+
- You call sdk.evm.send and pass abi, contract address, function name, and params
142+
143+
## To change a schema 2.0 compliant data attribute from EVM
144+
145+
Use @unique-nft/contracts, [TokenManager.sol](https://github.com/UniqueNetwork/unique-contracts?tab=readme-ov-file#tokenmanagersol)
146+
147+
EVM workhop demonstrates how to do this.
148+
149+
- [How do we mutate token image](https://github.com/UniqueNetwork/unique-react-template/blob/ab923457ece54f6ac6d1f2f47fc08ea52363dad1/contracts/contracts/BreedingGame.sol#L111-L119)
150+
- [How do we mutate token attributes](https://github.com/UniqueNetwork/unique-react-template/blob/ab923457ece54f6ac6d1f2f47fc08ea52363dad1/contracts/contracts/BreedingGame.sol#L197-L202)
151+
- [How do we call these solidity functions on the UI](https://github.com/UniqueNetwork/unique-react-template/blob/ab923457ece54f6ac6d1f2f47fc08ea52363dad1/src/pages/BreedingPage.tsx#L138-L173)
152+
153+
154+
Please remember to view this video: https://youtu.be/Cid_Ui5e0rk

0 commit comments

Comments
 (0)