Skip to content

Commit

Permalink
Merge pull request #73 from Itheum/develop
Browse files Browse the repository at this point in the history
V2.0 - Support 3rd party market deposits. Withdraw feature for admins to support royalty DAO claiming.
  • Loading branch information
newbreedofgeek authored Dec 17, 2023
2 parents beebc90 + e814563 commit c2b46d8
Show file tree
Hide file tree
Showing 16 changed files with 3,350 additions and 649 deletions.
1,734 changes: 1,465 additions & 269 deletions Cargo.lock

Large diffs are not rendered by default.

28 changes: 13 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
[package]
name = "datanftmint"
version = "1.0.0"
edition = "2021"
publish = false
authors = [ "Ovidiu Damian - Itheum","Bucur David - Itheum","Mark Paul - Itheum"]

[lib]
path = "src/lib.rs"

[dependencies.multiversx-sc]
version = "0.39.7"

[dev-dependencies.multiversx-sc-scenario]
version = "0.39.7"
[package]
name = "datanftmint"
version = "2.0.0"
edition = "2021"
publish = false
authors = [ "Ovidiu Damian - Itheum","Bucur David - Itheum","Mark Paul - Itheum"]

[lib]
path = "src/lib.rs"
[dependencies.multiversx-sc]
version = "0.45.1"
[dev-dependencies.multiversx-sc-scenario]
version = "0.45.1"
69 changes: 55 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,22 @@ Call structure: "setAdministrator" + "@" + administrator hex encoded.

Example: "setAdministrator@afb9aa109340a83cdb2129635b060a3a2d67ba2659ad86bf6ef49f948c43572c"

#### setWithdrawalAddress

```rust
#[endpoint(setWithdrawalAddress)]
fn set_withdrawal_address(
&self,
withdrawal_address: ManagedAddress
);
```

Endpoint that sets the withdrawal address. The withdrawal address is the address that will receive the funds from the smart contract.

Call structure: "setWithdrawalAddress" + "@" + withdrawal_address hex encoded.

Example: "setWithdrawalAddress@afb9aa109340a83cdb2129635b060a3a2d67ba2659ad86bf6ef49f948c43572c"

### Owner and administrator endpoints

#### freezeSingleNFT
Expand Down Expand Up @@ -381,6 +397,25 @@ Call structure: "ESDTTransfer" + "@" + NFT-FT token identifier hex encoded + "@"

Example: "ESDTNFTTransfer@4e465446542d373736336637@01@1e@00000000000000000500c72532eb1c8f5e32034b46b5041babade020fdefd5fd@6275726e"

### withdrawal address endpoints

#### withdraw

```rust
#[endpoint(withdraw)]
fn withdraw(&self,
token_identifier: &EgldOrEsdtTokenIdentifier,
nonce: u64,
amount: BigUint
);
```

Endpoint that allows the withdrawal address to withdraw funds from the smart contract. The endpoint takes as arguments the token identifier, the nonce of the token and the amount to withdraw.

Call structure: "withdraw" + "@" + token_identifier hex encoded + "@" + nonce hex encoded + "@" + amount hex encoded.

Example: "withdraw@4e465446542d373736336637@00@91b77e5e5d9a0000"

### Views

#### getUserDataOut
Expand Down Expand Up @@ -413,12 +448,13 @@ Main view of the contract. Receives an address and a token identifier as argumen

This smart contract aims to offer the Elrond community an audited NFT minter smart contract that is easy to use, well documented and secure.

### Setting up dev environment (project development bootstrap) + how to build
### Setting up dev environment (project development bootstrap) + how to build (and upgrade)

- Uses `multiversx-sc-* 0.39.4` SDK libs (see Cargo.toml)
- Building requires minimum **mxpy 6.1.1** (newer version should also work but devs used 6.1.1). Check version using `mxpy --version`
- To build the project, requires minimum Rust version `1.69.0-nightly`. Check your Rust version by running `rustc --version`. To update your Rust, run `rustup update`. To set to nightly run `rustup default nightly` (devs used 1.69.0-nightly)
- Uses `multiversx-sc-* 0.39.4` (starting v2.0.0, we used 0.45.1) SDK libs (see Cargo.toml)
- Building requires minimum **mxpy 6.1.1** (starting v2.0.0, we used mxpy 8.1.2). Check version using `mxpy --version`
- To build the project, requires minimum Rust version `1.69.0-nightly` (staring v2.0.0, we used 1.75.0-nightly). Check your Rust version by running `rustc --version`. To update your Rust, run `rustup update`. To set to nightly run `rustup default nightly`
- After you make sure you have the minimum Rust version you can then begin development. After you clone repo and before you run build, deploy or run the tests - follow these steps (most likely only needed the 1st time)
- [Upgrades] Note that when we upgrade smart contract, we should again follow the steps below too as lib version may have changed (but for upgrade I skipped the rustup default nightly cmd and did the others)

```
rustup default nightly
Expand All @@ -427,7 +463,7 @@ cargo clean
cargo build
```

- The above should all work without any errors, next you can successfully run the following command to build via mxpy: `mxpy contract build`
- The above should all work without any errors, next you can successfully run the following command to build via mxpy: `mxpy contract build`
- mxpy may ask you to install `nodejs` and `wasm-opt` to optimize the build, if so then follow instructions given by mxpy and do this
- You can now run the tests. See "How to test" section below
- You can now update code as needed
Expand All @@ -445,15 +481,18 @@ The Smart Contract is structured in 6 files:

### How to test

Prior to running the below, make sure you check section called **Setting up dev environment (project development bootstrap)** above and your dev environment is configured correctly. You also need to run `mxpy contract build` (requires you to be online with internet connection) prior to running tests.

The tests are located in the tests folder, in the rust_tests file. In order to run the tests one can use the command:

```shell
cargo test --package datanftmint --test rust_tests -- --nocapture
cargo test --package datanftmint --test blackbox_tests -- --nocapture // [NOT DONE YET]
cargo test --package datanftmint --test whitebox_tests -- --nocapture // [NOT DONE YET]

cargo test --package datanftmint --test rust_tests -- --nocapture // [OLD WAY, will work!]
```

Another way of running the tests is by using the rust-analyzer extension in Visual Studio Code, which is also very helpful for Elrond Smart Contract development. If one has the extension installed, they can go open and go to the top of the rust_tests file and click the Run Tests button.
- Note that in Oct 2023 we moved the Claim contract to blackbox and whitebox testing as recommended by the multiversX dev docs. We have HAVE NOT upgraded this yet for this smart contract so you need to use the OLD WAY

Another way of running the tests is by using the rust-analyzer extension in Visual Studio Code, which is also very helpful for MultiversX Smart Contract development. If one has the extension installed, they can go open and go to the top of the rust_tests file and click the Run Tests button.

Note: In order to run the tests, one has to use the rust nightly version. One can switch to the nightly version by using:

Expand All @@ -480,32 +519,35 @@ After using that, to deploy one can simply use:
After deployment, one can interact with the smart contract and test its functionality. To do so, one can use the interaction snippets already presented above. More explanations can be found about the snippets inside the devnet.snippets file.

### Mainnet Deployment (via Reproducible Builds)

- After the security audit has passed the Mainnet deployment need to be verified to match the version that was audited. This guarantee is given via [Reproducible Builds](https://docs.multiversx.com/developers/reproducible-contract-builds/#how-to-run-a-reproducible-build-using-mxpy)

**Step 1 (Final build + Code Hash):**

- Be in the latest `main` branch. On the commit that was audited. Update the cargo.toml files with the correct version. This should match the version we use in our requirements files (i.e Notion). e.g. 1.0.0. you need to update the `cargo.toml` files in the root folder, wasm folder and meta folder.

- In the `cargo.toml` files make sure you set the correct `edition`. i.e. edition = "2021"

- As the `cargo.toml` files has been updated. Build locally as normal. i.e. see "how to build" above and also run tests as per "how to test". This will reflect the `cargo.toml` update in the linked cargo.lock files and produces the final local meta build files to keep the final github check-in and version tagging perfect.


**Step 2 (Final build + Code Hash):**
Once the main commit is locked in, we can then produce the code hash and build to deploy to devnet 1st (for final testing) and then to mainnet (after sending the code hash to the auditor)

1. Make sure your mxpy version is >= 6.
1. Make sure your mxpy version is >= 6 (starting v2.0.0, we used mxpy 8.1.2).
2. If Cargo.lock is in gitignore, remove it, build the contract and make a new commit. Otherwise this step can be skipped. (see Step 1 and repeat if needed)
3. Run the following in the root of the repository (run the latest Docker client in your computer. Used `Docker Desktop 4.18.0 (104112) on MacOX 12.6`):

`mxpy contract reproducible-build --docker-image="multiversx/sdk-rust-contract-builder:v4.1.4"`

Note that if you already have a output-docker from a previous build and deploy then delete this folder.

Also note that if you are upgrading you may need to use a newer docker `sdk-rust-contract-builder` version. You can see the tags here https://hub.docker.com/r/multiversx/sdk-rust-contract-builder/tags. Starting v2.0.0, we used v5.3.0 for the build to upgrade to. We tested this on devnet before doing it on mainnet.

This process may take some time. After it's done you should see "Docker build ran successfully!". An output-docker folder will be created containing the WASM files built in a reproducible way and artifacts.json containing the code hash of the WASM files.

You can then share the auditor the code hash. The auditor will follow the same steps and compare the code hash with yours. If they match, we will be good to go!

Note that "output-docker" folder should not be check-into GIT.
Note that "output-docker" folder should not be check-into GIT.

**Step 4 (Send Code Hash to auditor to verify against devnet and give us all final clear):**
We should have got this final clear in Step 2, but we still do a final check here.
Expand All @@ -514,8 +556,7 @@ We should have got this final clear in Step 2, but we still do a final check her

**Step 6 (Tag the commit in the main branch of Github with the version that was deployed. e.g. 1.0.0):**

**Step 6 (Deploy SC to Mainnet):**

**Step 7 (Deploy SC to Mainnet):**

## Contributing

Expand Down
46 changes: 41 additions & 5 deletions interaction/devnet.snippets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ PROXY=https://devnet-gateway.multiversx.com
CHAIN_ID="D"

WALLET="./wallet.pem"
USER="../wallet2.pem"
USER="./wallet2.pem"

ADDRESS=$(mxpy data load --key=address-devnet)
DEPLOY_TRANSACTION=$(mxpy data load --key=deployTransaction-devnet)
Expand Down Expand Up @@ -90,9 +90,7 @@ initializeContract(){
--send || return
}


setLocalRoles()
{
setLocalRoles(){
mxpy --verbose contract call ${ADDRESS} \
--recall-nonce \
--pem=${WALLET} \
Expand Down Expand Up @@ -463,4 +461,42 @@ getUserDataOut(){
--proxy ${PROXY} \
--function 'getUserDataOut' \
--arguments $address $token_identifier
}
}

# v2.0.0
setWithdrawalAddress(){
# $1 = address

address="0x$(mxpy wallet bech32 --decode ${1})"

mxpy --verbose contract call ${ADDRESS} \
--recall-nonce \
--pem=${WALLET} \
--gas-limit=10000000 \
--function "setWithdrawalAddress" \
--arguments $address \
--proxy ${PROXY} \
--chain ${CHAIN_ID} \
--send || return

}

withdraw(){
# $1 = token identifier
# $2 = nonce
# $3 = amount

token_identifier="0x$(echo -n ${1} | xxd -p -u | tr -d '\n')"
nonce=${2}
amount=${3}

mxpy --verbose contract call ${ADDRESS} \
--recall-nonce \
--pem=${USER} \
--gas-limit=10000000 \
--function "withdraw" \
--arguments $token_identifier $nonce $amount \
--proxy ${PROXY} \
--chain ${CHAIN_ID} \
--send || return
}
43 changes: 41 additions & 2 deletions interaction/mainnet.snippets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ upgrade(){
}

# if you interact without calling deploy(), then you need to 1st run this to restore the vars from data
restoreDeployDataLedgerMainnet() {
restoreDeployDataLedgerMainnet(){
TRANSACTION=$(mxpy data parse --file="./interaction/deploy-mainnet.interaction.json" --expression="data['emittedTransactionHash']")
ADDRESS=$(mxpy data parse --file="./interaction/deploy-mainnet.interaction.json" --expression="data['contractAddress']")

Expand Down Expand Up @@ -463,4 +463,43 @@ getUserDataOutMainnet(){
--proxy ${PROXY} \
--function 'getUserDataOut' \
--arguments $address $token_identifier
}
}

# v2.0.0
setWithdrawalAddressMainnet(){
# $1 = address

address="0x$(mxpy wallet bech32 --decode ${1})"

mxpy --verbose contract call ${ADDRESS} \
--recall-nonce \
--gas-limit=10000000 \
--function "setWithdrawalAddress" \
--arguments $address \
--proxy ${PROXY} \
--chain ${CHAIN_ID} \
--ledger \
--ledger-address-index 0 \
--send || return
}

withdrawMainnet(){
# $1 = token identifier
# $2 = nonce
# $3 = amount

token_identifier="0x$(echo -n ${1} | xxd -p -u | tr -d '\n')"
nonce=${2}
amount=${3}

mxpy --verbose contract call ${ADDRESS} \
--recall-nonce \
--gas-limit=10000000 \
--function "withdraw" \
--arguments $token_identifier $nonce $amount \
--proxy ${PROXY} \
--chain ${CHAIN_ID} \
--ledger \
--ledger-address-index 0 \
--send || return
}
Loading

0 comments on commit c2b46d8

Please sign in to comment.