27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/01- Hello World Full Stack dApp on BSC/contracts/HelloWorld.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.0;
3 |
4 | /** @title Documents. */
5 | contract HelloWorld {
6 |
7 | string defaultName;
8 | mapping (address => string) public accounts;
9 |
10 | constructor() {
11 | defaultName = 'World';
12 | }
13 |
14 | /** @dev Retrieve Message to Print
15 | * @return The Message to Print, Hello, Concatenated with the User Name
16 | */
17 | function getMessage() public view returns(string memory){
18 | string memory name = bytes(accounts[msg.sender]).length > 0 ? accounts[msg.sender] : defaultName;
19 | return concat("Hello, " , name);
20 | }
21 |
22 | /** @dev Set the Name to Greet
23 | * @param _name user name
24 | * @return success Returns bool value (True or False) to indicate if save was successful or not
25 | */
26 | function setName(string memory _name) public returns(bool success){
27 | require(bytes(_name).length > 0);
28 | accounts[msg.sender] = _name;
29 | return true;
30 | }
31 |
32 | /** @dev Set the Name to Greet
33 | * @param _base contains the base value " Hello, "
34 | * @param _value contains the name to append to message to display
35 | * @return the concatenated string of _base+_value i.e. Hello, Name
36 | */
37 | function concat(string memory _base, string memory _value) internal pure returns (string memory) {
38 | bytes memory _baseBytes = bytes(_base);
39 | bytes memory _valueBytes = bytes(_value);
40 |
41 | string memory _tmpValue = new string(_baseBytes.length + _valueBytes.length);
42 | bytes memory _newValue = bytes(_tmpValue);
43 |
44 | uint i;
45 | uint j;
46 |
47 | for(i=0; i<_baseBytes.length; i++) {
48 | _newValue[j++] = _baseBytes[i];
49 | }
50 |
51 | for(i=0; i<_valueBytes.length; i++) {
52 | _newValue[j++] = _valueBytes[i];
53 | }
54 |
55 | return string(_newValue);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/01- Hello World Full Stack dApp on BSC/contracts/Migrations.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.4.22 <0.9.0;
3 |
4 | contract Migrations {
5 | address public owner = msg.sender;
6 | uint public last_completed_migration;
7 |
8 | modifier restricted() {
9 | require(
10 | msg.sender == owner,
11 | "This function is restricted to the contract's owner"
12 | );
13 | _;
14 | }
15 |
16 | function setCompleted(uint completed) public restricted {
17 | last_completed_migration = completed;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/01- Hello World Full Stack dApp on BSC/migrations/1_initial_migration.js:
--------------------------------------------------------------------------------
1 | const Migrations = artifacts.require("Migrations");
2 |
3 | module.exports = function (deployer) {
4 | deployer.deploy(Migrations);
5 | };
6 |
--------------------------------------------------------------------------------
/01- Hello World Full Stack dApp on BSC/migrations/2_hello_world.js:
--------------------------------------------------------------------------------
1 | var HelloWorld = artifacts.require('HelloWorld');
2 |
3 | module.exports = function(deployer) {
4 | // Use deployer to state migration tasks.
5 | deployer.deploy(HelloWorld);
6 | };
--------------------------------------------------------------------------------
/01- Hello World Full Stack dApp on BSC/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "helloworld",
3 | "version": "1.0.0",
4 | "main": "truffle-config.js",
5 | "directories": {
6 | "test": "test"
7 | },
8 | "scripts": {
9 | "test": "echo \"Error: no test specified\" && exit 1",
10 | "start": "node server/main.js",
11 | "dev": "node_modules/.bin/webpack && node server/main.js",
12 | "webpack": "node_modules/.bin/webpack --watch",
13 | "build": "npx webpack "
14 | },
15 | "author": "",
16 | "license": "ISC",
17 | "dependencies": {
18 | "@metamask/detect-provider": "^1.2.0",
19 | "@rails/webpacker": "^5.4.3",
20 | "@truffle/hdwallet-provider": "^2.0.9",
21 | "dotenv": "^16.0.1",
22 | "express": "^4.18.1",
23 | "node_modules-path": "^2.0.5",
24 | "truffle-hdwallet-provider": "^1.0.17",
25 | "webpack": "4",
26 | "webpack-cli": "^4.10.0"
27 | },
28 | "devDependencies": {
29 | "truffle-contract": "^4.0.31"
30 | },
31 | "description": ""
32 | }
33 |
--------------------------------------------------------------------------------
/01- Hello World Full Stack dApp on BSC/server/main.js:
--------------------------------------------------------------------------------
1 | require('dotenv').config();
2 | const express = require('express');
3 | const app = express();
4 | const PORT = process.env.PORT || 3000;
5 |
6 | app.use(express.static('client'));
7 | app.use(express.static('build/contracts'));
8 | app.get('/', (req, res) => {
9 | res.sendFile(`${__dirname}/client/index.html`);
10 | });
11 |
12 | app.get('*', (req, res) => {
13 | res.status(404);
14 | res.send('Sorry this URL does not exist');
15 | });
16 |
17 | app.listen(PORT, () => {
18 | console.log(`HelloWorld App running on port ${PORT}...`);
19 | });
--------------------------------------------------------------------------------
/01- Hello World Full Stack dApp on BSC/test/hello_world.js:
--------------------------------------------------------------------------------
1 | var helloworld = artifacts.require('HelloWorld');
2 | contract('HelloWorld', function(accounts) {
3 | let instance;
4 | before(async () => {
5 | instance = await helloworld.deployed();
6 | });
7 |
8 | //Test to check if the default value is set to "hello, world"
9 | it('Default message should be hello, world',async () => {
10 | let message = await instance.getMessage.call({from: accounts[0]});
11 | assert.equal(message, "Hello, World","Incorrect message.");
12 | });
13 |
14 | //Test to check if the save button is working or not
15 | it('Should save name',async () => {
16 | let result = await instance.setName.sendTransaction('Rumeel',{from: accounts[0]});
17 | let message = await instance.getMessage.call({from: accounts[0]});
18 | assert.equal(message, "Hello, Rumeel","Incorrect message.");
19 | });
20 |
21 | //Test to check if the default values for accounts other than the 1s default account of wallet
22 | it('Should be default message for other accounts',async () => {
23 | let message1 = await instance.getMessage.call({from: accounts[0]});
24 | let message2 = await instance.getMessage.call({from: accounts[1]});
25 | assert.equal(message1, "Hello, Rumeel","Incorrect user message.");
26 | assert.equal(message2, "Hello, World","Incorrect message.");
27 | });
28 |
29 | //Test to check if error is thrown on empty name field
30 | it('Should throw error on empty name',async () => {
31 | try{
32 | let result = await instance.setName.sendTransaction('',{from: accounts[0]});
33 | assert.fail(true,false,"The function should throw error");
34 | }
35 | catch(err){
36 | assert.include(String(err),'revert','throws different error');
37 | }
38 | });
39 | });
40 |
--------------------------------------------------------------------------------
/01- Hello World Full Stack dApp on BSC/truffle-config.js:
--------------------------------------------------------------------------------
1 | const HDWalletProvider = require('@truffle/hdwallet-provider');
2 | const fs = require('fs');
3 | const mnemonic = fs.readFileSync(".secret").toString().trim();
4 |
5 | module.exports = {
6 |
7 | networks: {
8 | development: {
9 | host: "127.0.0.1", // Localhost (default: none)
10 | port: 8545, // Standard Ethereum port (default: none)
11 | network_id: "*", // Any network (default: none)
12 | },
13 | bscTestnet: {
14 | provider: () => new HDWalletProvider(mnemonic, `https://data-seed-prebsc-2-s1.binance.org:8545`),
15 | network_id: 97,
16 | confirmations: 2,
17 | //timeoutBlocks: 200,
18 | skipDryRun: true,
19 | },
20 | bscMainnet: {
21 | provider: () => new HDWalletProvider(mnemonic, `https://bsc-dataseed1.binance.org`),
22 | network_id: 56,
23 | confirmations: 10,
24 | timeoutBlocks: 200,
25 | skipDryRun: true
26 | },
27 | },
28 |
29 | // Set default mocha options here, use special reporters, etc.
30 | mocha: {
31 | // timeout: 100000
32 | },
33 |
34 | // Configure your compilers
35 | compilers: {
36 | solc: {
37 | version: "^0.8.0", // Fetch exact version from solc-bin (default: truffle's version)
38 | }
39 | },
40 | };
41 |
--------------------------------------------------------------------------------
/01- Hello World Full Stack dApp on BSC/webpack.config.js:
--------------------------------------------------------------------------------
1 | require('dotenv').config();
2 | const webpack = require('webpack');
3 | const path = require('path');
4 |
5 | module.exports = {
6 | resolve: {
7 | alias: {
8 | 'node_modules': path.join(__dirname, 'node_modules')
9 | }
10 | },
11 | entry: './client/app.js',
12 | mode: process.env.MODE,
13 | output: {
14 | filename: 'bundle.js',
15 | path: path.resolve(__dirname, 'client/dist')
16 | },
17 | plugins: [
18 | new webpack.DefinePlugin({
19 | 'process.env': {
20 | 'LOCAL_NODE': JSON.stringify(process.env.LOCAL_NODE),
21 | 'MODE':JSON.stringify(process.env.MODE),
22 | }
23 | })
24 | ],
25 | node: {
26 | net: 'empty',
27 | tls: 'empty',
28 | dns: 'empty'
29 | },
30 | externals:[{
31 | xmlhttprequest: '{XMLHttpRequest:XMLHttpRequest}'
32 | }]
33 | };
--------------------------------------------------------------------------------
/02-BSC-Block-Explorer/README.md:
--------------------------------------------------------------------------------
1 | # BSC Block Explorer Tutorial
2 |
3 | ## Overview
4 | Designed for anyone wanting to learn development on the BNB Smart Chain, this tutorial provides a step-by-step guide on how to develop a block explorer that uses the Nodereal API to fetch details from the BNB Smart Chain blockchain for the given transaction hash. The technology stack used in this tutorial includes Web3.js, Nodereal MegaNode, and http-server.
5 |
6 | ## What You Will Learn
7 | Through this tutorial, you will learn
8 | - How to use the Web3js library to fetch blockchain data;
9 | - How to use Nodereal’s Meganode API;
10 | - How to deploy static pages onto localhost using http-server
11 |
12 | ## Target audience
13 | This tutorial aims to provide adequate information to anyone who wants to learn dApp development on BNB Smart Chain.
14 |
15 | ## Prerequisites
16 | - node --version
17 | - v16.13.0
18 | - npm --version
19 | - 8.1.0
20 | - http-server --version
21 | - v14.1.1
22 |
23 | ## Setup
24 |
25 | 1. **Clone the repository** ```gh repo clone https://github.com/bnb-chain/bnb-chain-tutorial```
26 | 2. **Change the current directory** ```cd 02-BSC-Block-Explorer```
27 | 3. **Install all the dependencies (node modules)** ```npm install```
28 | 4. **Include Nodereal Meganode API Key** make sure to include the HTTP link for the Nodereal Meganode API in the ```index.html``` as shown in the figure below.
29 |
30 | 
31 |
32 | 5. For this project we have used the BSC Testnet public API key as shown in the figure below. For a complete list of Nodereal Meganode Public API keys, refer [here](https://docs.nodereal.io/nodereal/meganode/meganode-api-overview/public-api-key).
33 |
34 | 
35 |
36 | 5. **Install htpp-server** ```npm install -g http-server```
37 | 6. **Run the application** ```http-server```
38 |
39 | ## Available Scripts
40 | ```sh
41 | $ http-server
42 | ```
43 |
44 | ## Structure
45 | ```
46 | 02-BSC-Block-Explorer.
47 | | index.html
48 | | list.txt
49 | | README.md
50 | | screenshot.png
51 | |
52 | +---img
53 | | favicon.ico
54 | | logo.png
55 | | screenshot.png
56 | |
57 | \---js
58 | web3.min.js
59 | ```
60 |
61 | ## How it Works
62 | ### Checklist
63 | - Make sure you have installed all the dependences using the ```npm install``` command.
64 | - Make sure you have installed http-server using the ```npm install -g http-server``` command.
65 | - Before running the application, make sure that you have included the HTTP link for the Nodereal Meganode API in the ```index.html``` as shown in the figure below.
66 |
67 | 
68 |
69 | - For this project we have used the public API key for BSC Testnet. For a complete list of Nodereal Meganode Public API keys, refer [here](https://docs.nodereal.io/nodereal/meganode/meganode-api-overview/public-api-key).
70 |
71 | ### How to Use
72 | - Run the application using the command ```http-server``` from the root directory of the project.
73 | - Open browser and navigate to any of the URLs specified by running the above step, for e.g., ```localhost:8080```.
74 | - Since we have used the HTTP reference of Nodereal’s Meganode API for BSC testnet, open [BSCscan for Testnet](https://testnet.bscscan.com/), and copy the transaction hash of any transaction of your choice.
75 | - Paste this transaction hash into the input field in our block explorer.
76 | - Click on the _**Fetch Details**_ button to fetch details of the transaction.
77 |
78 | 
79 |
80 | ## Contact
81 | For more inquiries and conversations, feel free to contact us at our [Discord Channel](https://discord.com/channels/789402563035660308/912296662834241597)
82 |
--------------------------------------------------------------------------------
/02-BSC-Block-Explorer/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bnb-chain/bnb-chain-tutorial/6626670d651dc8dd95f2fa5531c18b418d1b8507/02-BSC-Block-Explorer/img/favicon.ico
--------------------------------------------------------------------------------
/02-BSC-Block-Explorer/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bnb-chain/bnb-chain-tutorial/6626670d651dc8dd95f2fa5531c18b418d1b8507/02-BSC-Block-Explorer/img/logo.png
--------------------------------------------------------------------------------
/02-BSC-Block-Explorer/img/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bnb-chain/bnb-chain-tutorial/6626670d651dc8dd95f2fa5531c18b418d1b8507/02-BSC-Block-Explorer/img/screenshot.png
--------------------------------------------------------------------------------
/02-BSC-Block-Explorer/img/screenshot2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bnb-chain/bnb-chain-tutorial/6626670d651dc8dd95f2fa5531c18b418d1b8507/02-BSC-Block-Explorer/img/screenshot2.png
--------------------------------------------------------------------------------
/02-BSC-Block-Explorer/img/screenshot3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bnb-chain/bnb-chain-tutorial/6626670d651dc8dd95f2fa5531c18b418d1b8507/02-BSC-Block-Explorer/img/screenshot3.png
--------------------------------------------------------------------------------
/02-BSC-Block-Explorer/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | BSC Block Explorer
9 |
10 |
11 |
12 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
Block Explorer
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
Block Hash
36 |
Block Number
37 |
From
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/02-BSC-Block-Explorer/list.txt:
--------------------------------------------------------------------------------
1 | Folder PATH listing
2 | Volume serial number is 309C-F577
3 | F:.
4 | | index.html
5 | | list.txt
6 | | README.md
7 | | screenshot.png
8 | |
9 | +---img
10 | | favicon.ico
11 | | logo.png
12 | | screenshot.png
13 | |
14 | \---js
15 | web3.min.js
16 |
17 |
--------------------------------------------------------------------------------
/02-BSC-Block-Explorer/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bnb-chain/bnb-chain-tutorial/6626670d651dc8dd95f2fa5531c18b418d1b8507/02-BSC-Block-Explorer/screenshot.png
--------------------------------------------------------------------------------
/03-Using-BlackIDE-for-Deploying-NFTs/ERC721_NFT.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.4;
3 |
4 | import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
5 | import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
6 | import "@openzeppelin/contracts/security/Pausable.sol";
7 | import "@openzeppelin/contracts/access/Ownable.sol";
8 | import "@openzeppelin/contracts/utils/Counters.sol";
9 |
10 | /** @title BSCNFT */
11 | contract BSCNFT is ERC721, ERC721Enumerable, Pausable, Ownable {
12 |
13 | /* Property Variables */
14 |
15 | using Counters for Counters.Counter;
16 |
17 | Counters.Counter private _tokenIdCounter;
18 |
19 | uint256 public MINT_PRICE = 0.05 ether; //Change this value as per your requirement
20 | uint public MAX_SUPPLY = 100; //Change this value as per your requirement
21 |
22 | /** @dev Constructor to set Name and Initials for NFT
23 | and increment token counter
24 | */
25 | constructor() ERC721("HappyMonkey", "HM") {
26 | // Start token ID at 1. By default is starts at 0.
27 | _tokenIdCounter.increment();
28 | }
29 |
30 | /** @dev Withdraw Tokens
31 | */
32 | function withdraw() public onlyOwner() {
33 | require(address(this).balance > 0, "Balance is zero");
34 | payable(owner()).transfer(address(this).balance);
35 | }
36 |
37 | /** @dev Pause NFT Function
38 | */
39 | function pause() public onlyOwner {
40 | _pause();
41 | }
42 | /** @dev Unpause NFT Function
43 | */
44 | function unpause() public onlyOwner {
45 | _unpause();
46 | }
47 |
48 | /** @dev Function to Mint NFTs
49 | */
50 |
51 | function safeMint(address to) public payable {
52 | // Check that totalSupply is less than MAX_SUPPLY
53 | require(totalSupply() < MAX_SUPPLY, "Can't mint anymore tokens.");
54 |
55 | // Check if enough amount of Ethers are passed
56 | require(msg.value >= MINT_PRICE, "Not enough ether sent.");
57 | uint256 tokenId = _tokenIdCounter.current();
58 | _tokenIdCounter.increment();
59 | _safeMint(to, tokenId);
60 | }
61 |
62 | /** @dev Function to set the URI of the NFT
63 | */
64 | function _baseURI() internal pure override returns (string memory) {
65 | return "ipfs://happyMonkeyBaseURI/"; //change this for your token
66 | }
67 |
68 | /** @dev Sanity Checks before the token is transferrred
69 | */
70 | function _beforeTokenTransfer(address from, address to, uint256 tokenId)
71 | internal
72 | whenNotPaused
73 | override(ERC721, ERC721Enumerable)
74 | {
75 | super._beforeTokenTransfer(from, to, tokenId);
76 | }
77 |
78 | /** @dev The following functions are overrides required by Solidity.
79 | */
80 | function supportsInterface(bytes4 interfaceId)
81 | public
82 | view
83 | override(ERC721, ERC721Enumerable)
84 | returns (bool)
85 | {
86 | return super.supportsInterface(interfaceId);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/03-Using-BlackIDE-for-Deploying-NFTs/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Using Black IDE to Deploy NFTs on BSC
3 |
4 | In this tutorial, we provide a step-by-step guide to the readers on how to issue Non-fungible tokens (NFTs) (ERC721/1155) on the BNB Smart Chain (BSC) Testnet using the Black IDE. This is a detailed guide to learning how to issue, mint and transfer NFTs on the BSC Testnet. The technology stack used in this tutorial includes Solidity , Truffle, MetaMask, and BlackIDE.
5 |
6 | ## Learning Takeaways:
7 | This tutorial will help you gain knowledge on the following learning points:
8 | - Using BlackIDE for smart contract development;
9 | - Managing Keypairs and Funding BNB Tokens to your account on BlackIDE;
10 | - MetaMask Wallet connectivity to BSC Testnet;
11 | - Smart-contract development;
12 | - Issuing, minting, and transferring NFTs;
13 |
14 | ## Technology Stack Details
15 | - BlackIDE v0.15.4
16 | - Truffle v5.5.19 (core: 5.5.19)
17 | - MetaMask Wallet v10.16.1
18 | - Docker v20.10.14
19 |
20 | ## Brief Introduction Tech Stack
21 | 1. **Solidity:** one of the most popular object-oriented high-level smart contract programming languages. For more details on Solidity, refer here.
22 | 2. **MetaMask Wallet Browser Extension:** we recommend using the Metamask Chrome extension. It is a web wallet that allows connecting the chrome browser to any valid blockchain network.
23 | 3. **Black IDE:** Black IDE is an integrated development environment (IDE), making developing EVM-compatible smart contracts faster and easier. Black IDE offers both desktop and web (Black IDE Web) applications.
24 |
25 | ## Setting up the Environment
26 | We aim to keep this tutorial as simple as possible and hence tend to use as minimal resources as possible and have used the following tools in this tutorial.
27 | * Metamask Wallet
28 | * Ensure that you have the Metamask Wallet extension installed and running on our browser.
29 | * Configure the Metamask wallet for use with the BSC Testnet. Use the following details to add the BSC Testnet. For further details, refer here.
30 | * Network Name: BSC Testnet
31 | * RPC URL: https://data-seed-prebsc-1-s1.binance.org:8545/
32 | * Chain ID: 97
33 | * Currency Symbol: BNB
34 | * Block Explorer URL: https://testnet.bscscan.com
35 | * Black IDE: both desktop app and web app are available and it is up to your convenience to choose from. For this tutorial, we used the desktop app as the web app lacks support for importing OpenZeppelin Contracts.
36 | * Download/Install any dependencies required by BlackIDE
37 |
38 | 
39 |
40 | ## Login into Black IDE
41 | 1. Open the Black IDE desktop application. We will be using it for compiling and deploying our smart contract for NFTs on the BSC Testnet.
42 | 2. Click on the Login button and authorize using your GitHub account.
43 |
44 | 
45 |
46 | ## Create New Project
47 | 3. Click on the New button next to the projects to create a new project.
48 |
49 | 
50 |
51 | 4. Specify the location where you want to save your project on your device, the project name, e.g. “BSC-NFT”, and select the project type from the dropdown list as “Basics- ERC20, ERC721, & ERC1155 (v31+)”. Then click the Create button to create the project.
52 |
53 | 
54 |
55 | 5. Remember the smart contract in this tutorial is just a sample, you can always modify and be innovative.
56 |
57 | ## Smart Contract Creation
58 | 6. Expand the contracts menu and delete the default files.
59 |
60 | 
61 |
62 | 7. Right-click on the contracts menu and select New File. Specify a name for your file, e.g., BSC-NFT.sol, and then click Create button.
63 |
64 | 
65 |
66 | ## Write your smart contract code
67 | 8. Copy the following code into your smart contract file. We have used the contract code from the [ERC721_NFT.sol](ERC721_NFT.sol) file in this repo.
68 | 9. Remember to change the ```MINT_PRICE```, ```MAX_SUPPLY```, ```name```, and ```symbol``` of the token as per your need. Also, remember to change the ```_baseURI``` as per your token.
69 | 10.
70 | 
71 |
72 | ## Edit default project settings
73 | 10. Click on the config.json file to change the default setting. Change the main file name to the name of your contract, BSC-NFT.sol in our case. Similarly, change the name of the smart contract to deploy, BSCNFT.json in our case.
74 |
75 | 
76 |
77 | ## Connect the Black IDE to the BSC Testnet
78 | 11. In order to connect the Black IDE to the BSC Testnet, click on the dropdown icon on the network menu in the top right corner and then select Testnet under the BNB Chain label.
79 |
80 | 
81 |
82 | 12. Click on the  icon in the bottom left corner of the IDE to generate new keypair to perform transactions. You can skip this step if you already have generated a keypair. On the Keypair Manager, click on the CREATE button to generate new keypair.
83 |
84 | 
85 |
86 | 13. Specify your desired name for the keypair, in our case BSC-Testnet-Key. Then click on the CREATE button. Remember to keep your private keys securely and not share them with anyone.
87 |
88 | 
89 |
90 | ## Acquire BNB Test Tokens
91 | * Initially, the balance of a newly created key pair is 0.0 ETH. To get BNB test tokens, you can use the [BSC Testnet Faucet](https://testnet.binance.org/faucet-smart/).
92 | * Copy your public address from the keypair manager
93 |
94 | 
95 |
96 | * Paste this on the facet and acquire test tokens as required, as shown below. A green pop-up is displayed on the successful transfer of test tokens.
97 |
98 | 
99 |
100 | * Close and re-open keypair manager to verify that the balance has been updated. Wait for approx. 1-2 mins for balance to get updated.
101 |
102 | 
103 |
104 | ## Deploy Smart Contract on BSC Testnet
105 | 1. Select the appropriate Solidity compiler version from the bottom right corner of the IDE, Solc (0.8.4), 
106 | in our case.
107 | 2. Click on the Build icon  to build your smart contract. Upon successful build, the project navigation pane reflects a new folder named build. This folder contains contracts folder that has json files of the contracts built. All of the contracts imported in our BSCNFT contract are also built and imported as json files.
108 |
109 | 
110 |
111 | 3. After successfully building your contract, it’s time to deploy the contract. Click on the Deploy icon  for deploying your smart contract. Specify the details for your contract, as shown below, then click on the Estimate & Deploy button. The wizard will auto-estimate and fill the gas limit for your contract. Then click the Deploy button.
112 |
113 | 
114 | 
115 |
116 | 4. Deployment details will pop-up, as shown in the figure below.
117 |
118 | 
119 |
120 | 5. The status of the transaction will be updated to confirmed after the transaction is confirmed as shown in the figure below
121 |
122 | 
123 |
124 | 6. You can also view this transaction by clicking on the transaction icon in the bottom left on the IDE.
125 |
126 | 
127 |
128 | ## Interact with deployed smart contract and Mint NFTs
129 | 1. You can also interact with the contract using the different functions. Click on the Transactions Icon on the bottom-left corner of the IDE and then transaction of deployment of your smart contract. On the transaction details, click on the contract address to access the functions to interact with the smart contract. The left most column has all the Write Functions. The middle column has the View Functions and the right most column has the Events details.
130 |
131 | 
132 |
133 | ## Mint NFTs
134 | 1. As per our smart contract, when the contract is deployed, unless the NFTs are minted they won’t be visible in the wallet.
135 | 2. Create another keypair as defined previously. We will be issuing i.e. minting NFTs to the public address of this new keypair.
136 | 3. To mint i.e. issue an NFT to a specific user we use the “safeMint” function of the deployed smart contract. As shown in Steps 1 and 2 in the figure below, navigate to the deployed contracts, then in the left-most column click the drop-down menu to view the list of write functions available for use with the deployed contract. Select the “safeMint” function.
137 | 4. Use the safeMint function to mint new NFTs to a specific user address. As shown in figure above, steps 3 to 6, enter the “ETH to send” as the minting price of NFT, as per our smart contract the minting price is 50000000000000000 Wei, i.e., 0.05 ETH. We entered 0.06 ETH to cover the transaction charges as well. Then select the address to whom you want to issue (mint) an NFT to. Here, for the To address use the newly generated keypair in the section above. After this, click the transact button to execute the safeMint function. For the Signer, ensure that you are using the account that was used to deploy the smart contract.
138 |
139 | 
140 |
141 | 5. To confirm what transfers have occurred, execute the Transfer event from the right most column. This will display the list of NFT transfers along with NFT token id, as shown in the figure below.
142 |
143 | 
144 |
145 | 6. To confirm owner of an NFT, use the ownerOf function. Pass the token id as input to the function, as illustrated in the figure below.
146 |
147 | 
148 |
149 | ## View Your NFTs in Metamask Wallet
150 | 1. On the receiving end, the user can import the NFT token details into their Metamask wallet to view the assets. Please note that currently, Metamask Web Extension does not support the use of NFTs however, the mobile app version does support it. For the next steps to view the owned NFTs in your Metamask wallet, we will be using the Metamask Mobile Application.
151 | 2. Open Keypair manager on the Black IDE and copy the private key of the keypair that you minted i.e., transfer NFT.
152 |
153 | 
154 |
155 | 3. On the Metamask wallet mobile app, import an account using this key pair. Enter the private key copied in the previous step and click import.
156 |
157 | 
158 |
159 | 4. After importing account, the next step is to add the BSC Testnet configuration to the wallet. Ensure that you are using the same account whose pubic address was issued the NFT.
160 |
161 | 
162 |
163 | 5. Ensure that your account is connected to the BSC Testnet. Also, ensure that you have enough BNB test tokens in your account. If not, you can use the BSC Testnet Faucet to acquire some, as mentioned earlier.
164 |
165 | 
166 |
167 | 6. To view the owned NFT assets your Metamask Mobile Wallet, click on the NFTs tab and then on the Import Tokens. Fill in the NFT details. In the address field, pass the address of the deployed contract and in the Id field pass the tokenID. Then click the Import button.
168 |
169 | 
170 |
171 | ## Conclusion
172 | In this tutorial, we provided a step-to-step guide on how to issue, mint and transfer NFTs on the BSC Testnet using the BlackIDE from Obsidian Labs.. The technology stack used in this tutorial includes Solidity, Truffle, MetaMask, and BlackIDE. Check out our [GitHub](https://github.com/bnb-chain/bnb-chain-tutorial) for more tutorials on how to develop on BSC. If you have any questions or are stuck, reach out to us on our [Discord Channel](https://discord.com/channels/789402563035660308/912296662834241597).
173 |
174 |
--------------------------------------------------------------------------------
/04-Deploying-Smart-Contracts-Using-IDEs/README.md:
--------------------------------------------------------------------------------
1 | # Deploying Smart Contracts Using IDEs
2 |
3 | This repository contains step-by-step guides on how to deploy smart contracts on the BNB Smart Chain network using different IDEs.
4 |
5 | - [Tutorial on How to Deploy Smart Contract on BSC using Chainlink IDE](https://github.com/bnb-chain/bnb-chain-tutorial/blob/main/04-Deploying-Smart-Contracts-Using-IDEs/chainide.md).
6 |
7 | - [Tutorial on How to Deploy Smart Contract on BSC using Remix IDE](https://github.com/bnb-chain/bnb-chain-tutorial/blob/main/04-Deploying-Smart-Contracts-Using-IDEs/remixide.md).
8 |
9 | - [Tutorial on How to Deploy Smart Contract on BSC using Truffle IDE](https://github.com/bnb-chain/bnb-chain-tutorial/blob/main/04-Deploying-Smart-Contracts-Using-IDEs/truffle.md).
10 |
11 | - [Tutorial on How to Deploy Smart Contract on BSC using Hardhat IDE](https://github.com/bnb-chain/bnb-chain-tutorial/blob/main/04-Deploying-Smart-Contracts-Using-IDEs/hardhat.md).
12 |
13 | - [Tutorial on How to Deploy Smart Contract on BSC using Replit IDE](https://github.com/bnb-chain/bnb-chain-tutorial/blob/main/04-Deploying-Smart-Contracts-Using-IDEs/replit.md/).
14 |
--------------------------------------------------------------------------------
/04-Deploying-Smart-Contracts-Using-IDEs/chainide.md:
--------------------------------------------------------------------------------
1 |
2 | # Using Chain IDE for Deploying Smart Contracts on BSC
3 |
4 | In this tutorial, we explain step-by-step how to create, compile and deploy a simple smart contract on the BSC Testnet using Chain IDE.
5 |
6 | ## What is Chain IDE?
7 |
8 | [ChainIDE](https://chainide.com/) is a chain agnostic, cloud-based IDE for creating decentralized applications. It enhances the development cycle through pre-configured plugins that save users' time and effort. This is a beginner guide on creating a simple smart contract and deploying it to the BNB Smart Chain. If you have any questions, feel free to ask them in the [ChainIDE Discord](https://discord.gg/QpGq4hjWrh).
9 |
10 | ## Pre-requisites
11 |
12 | 1. ChainIDE
13 | 2. Web3 Wallet
14 | 3. Solidity
15 |
16 | ## What You'll Do
17 |
18 | The following are general steps for deploying a storage smart contract
19 |
20 | 1. Setting up a Wallet
21 | 2. Write down a Storage Smart Contract
22 | 3. Compile a Storage Smart Contract
23 | 4. Deploy a Storage Smart Contract
24 | 5. Create a Flattened File using Flattener Library
25 | 6. Verify a Storage Smart Contract
26 | 7. Contract Interaction
27 |
28 | ## Setting up a Wallet
29 |
30 | ### Install Binance Wallet/MetaMask
31 |
32 | When deploying a smart contract to a blockchain or when making a transaction to a deployed smart contract, a gas fee must be paid, and for that, we need to use a crypto wallet which can be Binance Wallet or MetaMask. If you want to use Binance Wallet, click [here](https://chrome.google.com/webstore/detail/binance-wallet/fhbohimaelbohpjbbldcngcnapndodjp) to get Binance Wallet and if you want to continue with MetaMask Wallet, click [here](https://metamask.io/) to install MetaMask.
33 |
34 | ### Adding BNB Smart Chain Test Network to MetaMask Wallet
35 |
36 | Visit [ChainIDE](https://chainide.com/), create a project, and click on the "unconnected button" in the upper right corner, select the "Injected Web3 Provider" button, and then click the "MetaMask" to connect to the MetaMask wallet ("BNB Chain Mainnet" is the main network, and "BNB Chain Testnet" is the test network, click on the "BNB Chain Testnet" and it will be added to your MetaMask wallet.
37 | ![]()
38 |
39 | ### Enabling the BNB Smart Chain Test Network to Binance Wallet
40 |
41 | If you want to continue with Binance Wallet, install Binance Wallet, and After installing Binance Wallet, you need to enable "Show Test Networks" and switch to the "BNB Smart Chain Test Network".
42 |
43 |
44 |
45 | ### Obtaining Test BNB tokens
46 |
47 | Once BNB Smart Chain Test Network has been added to MetaMask, navigate to the [BNB Smart Chain Faucet](https://testnet.binance.org/faucet-smart) to receive test tokens. Tokens are needed to pay for gas fees to deploy and interact with the smart contract. On the faucet page, paste your MetaMask wallet address. Then, click submit and the faucet will send you some test BNBs.
48 | 
49 |
50 | ## Write down a Storage Smart Contract
51 |
52 | You need to write down all the required functions that you want to implement in your storage smart contract. A general storage smart contract has the following functions:
53 |
54 | - `Store()`: store value in variables
55 | - `retrieve()`: returns the stored value
56 |
57 | The ChainIDE team has prepared a simple storage smart contract that includes all the required functions; you may use this built-in template and add/delete functions according to your requirements.
58 |
59 | Visit the [ChainIDE site](https://chainide.com/) and click on "Try Now".
60 |
61 | 
62 |
63 | Then, click on "New Project" and select "BNB Chain", and "Storage".
64 |
65 | 
66 |
67 | Now, you can see the template contract, **Storage.sol**, that includes all the required functions.
68 |
69 | ## Compile a Storage Smart Contract
70 |
71 | After you have completed your smart contract, it is time to compile it. To compile, navigate to the "Compile", module, choose an appropriate compiler version according to your source code, and press the "Compile" button. An ABI and bytecode for the source code generate upon successful compilation. If there are some errors in your source code, they will be displayed under the output panel in the "Logger module". You may need to carefully read the error, resolve it accordingly and compile the contract again.
72 |
73 | Note down the compiler version and the license for your source code as it would be needed when you verify your smart contract on the BNB Smart Chain Test Network.
74 |
75 | 
76 |
77 | ## Deploy a Storage Smart Contract
78 |
79 | After successful compilation, it's time to deploy your compiled storage smart contract to the BNB Smart Chain Test Network. For that, you need to have a MetaMask installed, the BNB Smart Chain Test Network added to your wallet, and some testnet tokens to pay for the transaction fee.
80 |
81 | Navigate to the "Deploy & Interaction" module and choose the smart contract that you want to deploy among the compiled smart contracts and click the "deploy" button. For this tutorial, the `Storage` smart contract will be deployed.
82 |
83 | 
84 |
85 | ## Create a Flattened File using Flattener Library
86 |
87 | To verify a smart contract that imports other smart contracts, we need to create a flattened file, a flattened file including all the source code of imported contracts in a single file. To create a flattened file, you need to add a "Flattener" plug-in.
88 |
89 | 
90 |
91 | Once the Flatterner plug-in is activated, you'll be able to access it as a separate module as shown in the figure below. Choose the compiled file, and click on the flatten button to create a flattened file, once the flattened file is created, it will be automatically copied to the clipboard, you may paste it to a file and save it for later usage.
92 |
93 | 
94 |
95 | If you want to save the flattened file, click the save button, and a flattened file will be saved in the current repository.
96 |
97 | 
98 |
99 | The saved flattened file can be accessed under the explorer module.
100 |
101 | 
102 |
103 | ## Verify a Smart Contract
104 |
105 | To verify a smart contract, you need to visit [BNB Smart Chain Explorer](https://bscscan.com/) and search for the deployed smart contract using the contract address.
106 |
107 | 
108 |
109 | Click on the "verify and publish" link shown under the contract section.
110 |
111 | 
112 |
113 | Once you click on the verify and publish link, you will be asked for the following:
114 |
115 | - Contract Address: The address of a deployed smart contract that you want to verify
116 | - Compiler Type: Either you want to verify a single file or multiple files
117 | - Compiler Version: The compiler version that you used to compile the smart contract
118 | - License: Open-source license type that you used for your source code
119 |
120 | 
121 |
122 | After that, you need to paste the flattened file that you created in step 5, and your smart contract will be verified.
123 |
124 | 
125 |
126 | If there are no issues with your smart contract, it would be verified, and you'll be able to see an image similar to the one that is shown below.
127 |
128 | 
129 |
130 | 
131 | Congratulations, you have successfully deployed your smart contract to the blockchain and verified it, now it's time to interact with your deployed smart contract.
132 |
133 | ## Contract Interaction
134 |
135 | After successful deployment and verification. All the functions in the deployed smart contract can be seen in the "INTERACT" panel. In our scenario, we have two functions, `Store()` that is used to store the value to the blockchain, and `Retrieve()` to retrieve stored data from the blockchain.
136 |
137 | 
138 |
139 |
140 | ## Conclusion
141 | This tutorial guided you through the basics of creating and deploying a simple smart contract using the Chain IDE. It also provides step-by-step guide on how to verify your deployed smart contract. This tutorial uses testnet, however, the exact same instructions and sequence will work on the mainnet as well.
142 |
--------------------------------------------------------------------------------
/04-Deploying-Smart-Contracts-Using-IDEs/hardhat.md:
--------------------------------------------------------------------------------
1 |
2 | # Using Hardhat for Deploying Smart Contracts on BSC
3 |
4 | In this tutorial, we explain step-by-step how to create, compile and deploy a simple smart contract on the BSC Testnet using Hardhat.
5 |
6 | ## What is Hardhat
7 |
8 | Hardhat is a development environment to compile, deploy, test, and debug your smart contract.
9 |
10 | ## Setting up the development environment
11 |
12 | There are a few technical requirements before we start.
13 |
14 | ### Pre-requisites
15 |
16 | There are a few technical requirements before we start as listed below:
17 |
18 | - [Node.js v10+ LTS and npm](https://nodejs.org/en/) (comes with Node)
19 | - [Git](https://git-scm.com/)
20 | - Create an empty project ```npm init --yes```
21 | - Once your project is ready, run ```npm install --save-dev hardhat``` to install Hardhat.
22 | - Install hardhat toolbox ```npm install @nomicfoundation/hardhat-toolbox```
23 | - To use your local installation of Hardhat, you need to use `npx` to run it (i.e. `npx hardhat`).
24 |
25 | ## Create A Project
26 |
27 | - To create your Hardhat project run ```npx hardhat``` in your project folder to intialize your project.
28 | - Select ```Create an empty hardhat.config.js``` with your keyboard and hit enter.
29 |
30 | ```
31 | $ npx hardhat
32 | 888 888 888 888 888
33 | 888 888 888 888 888
34 | 888 888 888 888 888
35 | 8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
36 | 888 888 "88b 888P" d88" 888 888 "88b "88b 888
37 | 888 888 .d888888 888 888 888 888 888 .d888888 888
38 | 888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
39 | 888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888
40 |
41 | Welcome to Hardhat v2.10.1
42 |
43 | √ What do you want to do? · Create a JavaScript project
44 | √ Hardhat project root: · Project-Directory
45 | √ Do you want to add a .gitignore? (Y/n) · y
46 |
47 | You need to install these dependencies to run the sample project:
48 | npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.
49 | npm install --save-dev "hardhat@^2.10.1" "@nomicfoundation/hardhat-toolbox@^1.0.1"
50 |
51 | Project created
52 |
53 | See the README.md file for some example tasks you can run
54 |
55 | Give Hardhat a star on Github if you're enjoying it!
56 |
57 | https://github.com/NomicFoundation/hardhat
58 | ```
59 |
60 | When Hardhat is run, it searches for the closest ```hardhat.config.js``` file starting from the current working directory. This file normally lives in the root of your project and an empty ```hardhat.config.js``` is enough for Hardhat to work. The entirety of your setup is contained in this file.
61 |
62 |
63 | ## Create Smart Contract
64 |
65 | You can write your own smart contract or download the [BEP20 token smart contract template](https://github.com/bnb-chain/bsc-genesis-contract/blob/master/contracts/bep20_template/BEP20Token.template), place it in the ```contracts``` directory of your project and remane it as ```BEP20Token.sol```.
66 |
67 | ## Configure Hardhat for BSC
68 |
69 | - Go to ```hardhat.config.js```
70 | - Update the config with bsc-network-crendentials.
71 |
72 | ```js
73 | require("@nomicfoundation/hardhat-toolbox");
74 |
75 | const { mnemonic } = require('./secrets.json');
76 |
77 | // This is a sample Hardhat task. To learn how to create your own go to
78 | // https://hardhat.org/guides/create-task.html
79 | task("accounts", "Prints the list of accounts", async () => {
80 | const accounts = await ethers.getSigners();
81 |
82 | for (const account of accounts) {
83 | console.log(account.address);
84 | }
85 | });
86 |
87 | // You need to export an object to set up your config
88 | // Go to https://hardhat.org/config/ to learn more
89 |
90 | /**
91 | * @type import('hardhat/config').HardhatUserConfig
92 | */
93 | module.exports = {
94 | defaultNetwork: "mainnet",
95 | networks: {
96 | localhost: {
97 | url: "http://127.0.0.1:8545"
98 | },
99 | hardhat: {
100 | },
101 | testnet: {
102 | url: "https://data-seed-prebsc-1-s1.binance.org:8545",
103 | chainId: 97,
104 | gasPrice: 20000000000,
105 | accounts: {mnemonic: mnemonic}
106 | },
107 | mainnet: {
108 | url: "https://bsc-dataseed.binance.org/",
109 | chainId: 56,
110 | gasPrice: 20000000000,
111 | accounts: {mnemonic: mnemonic}
112 | }
113 | },
114 | solidity: {
115 | version: "0.8.9",
116 | settings: {
117 | optimizer: {
118 | enabled: true
119 | }
120 | }
121 | },
122 | paths: {
123 | sources: "./contracts",
124 | tests: "./test",
125 | cache: "./cache",
126 | artifacts: "./artifacts"
127 | },
128 | mocha: {
129 | timeout: 20000
130 | }
131 | };
132 |
133 | ```
134 |
135 | :::note
136 | It requires mnemonic to be passed in for Provider, this is the seed phrase for the account you'd like to deploy from. Create a new `secrets.json` file in root directory and enter your 12 word mnemonic seed phrase to get started. To get the seedwords from metamask wallet you can go to Metamask Settings, then from the menu choose Security and Privacy where you will see a button that says reveal seed words.
137 | ```
138 | Sample secrets.json
139 |
140 | {
141 | "mnemonic": "Your_12_Word_MetaMask_Seed_Phrase"
142 | }
143 | ```
144 | :::
145 |
146 | ## Compile Smart Contract
147 |
148 | To compile a Hardhat project, change to the root of the directory where the project is located and then type the following into a terminal:
149 |
150 | ```
151 | npx hardhat compile
152 | ```
153 |
154 | ## Deploy Smart Contract on BSC Network
155 |
156 | - Copy and paste the following content into the ```scripts/deploy.js``` file.
157 |
158 | ```js
159 | async function main() {
160 | const [deployer] = await ethers.getSigners();
161 |
162 | console.log("Deploying contracts with the account:", deployer.address);
163 |
164 | console.log("Account balance:", (await deployer.getBalance()).toString());
165 |
166 | const Token = await ethers.getContractFactory("BEP20Token");
167 | const token = await Token.deploy();
168 |
169 | console.log("Token address:", token.address);
170 | }
171 |
172 | main()
173 | .then(() => process.exit(0))
174 | .catch((error) => {
175 | console.error(error);
176 | process.exit(1);
177 | });
178 |
179 | ```
180 |
181 | - Run this command in root of the project directory:
182 |
183 | ```js
184 | $ npx hardhat run --network testnet scripts/deploy.js
185 | ```
186 | - Sample Output
187 |
188 | ```
189 | $ npx hardhat run --network testnet scripts/deploy.js
190 | Deploying contracts with the account: 0x27cf2CEAcdedce834f1673005Ed1C60efA63c081
191 | Account balance: 100721709119999208161
192 | Token address: 0xbF39886B4F91F5170934191b0d96Dd277147FBB2
193 | ```
194 | > Remember your address, transaction_hash and other details provided would differ, Above is just to provide an idea of structure.
195 |
196 | **Congratulations!** You have successfully deployed BEP20 Smart Contract. Now you can interact with the Smart Contract.
197 |
198 | You can check the deployment status here: or
199 |
200 | ## Verify with Hardhat
201 |
202 | Hardhat has an Etherscan plugin: [Hardhat Etherscan plugin](https://hardhat.org/plugins/nomiclabs-hardhat-etherscan.html)
203 |
204 | > Note: Hardhat was previously Buidler.
205 |
206 | ### Install the plugin
207 |
208 | ```
209 | npm install --save-dev @nomiclabs/hardhat-etherscan
210 | ```
211 |
212 | ### Configure the EthereScan plugin in hardhat.config.js
213 |
214 | - Step1: Add ```require("@nomiclabs/hardhat-etherscan");```
215 | - Step2: Add your Bscscan API key. Register and obtain your API key from .
216 | - Step3: Always remember to set the solidity compiler version to match what was used for deploying the smart contract.
217 |
218 | !!! warning
219 | Keep your API key as secret and never it commit to version control
220 |
221 |
222 | ```js
223 | // hardhat.config.js
224 | const { mnemonic, bscscanApiKey } = require('./secrets.json');
225 |
226 | require('@nomiclabs/hardhat-ethers');
227 | require("@nomiclabs/hardhat-etherscan");
228 | /**
229 | * @type import('hardhat/config').HardhatUserConfig
230 | */
231 | module.exports = {
232 |
233 | networks: {
234 | testnet: {
235 | url: `https://data-seed-prebsc-1-s1.binance.org:8545`,
236 | accounts: {mnemonic: mnemonic}
237 | },
238 | mainnet: {
239 | url: `https://bsc-dataseed.binance.org/`,
240 | accounts: {mnemonic: mnemonic}
241 | }
242 | },
243 |
244 | etherscan: {
245 | // Your API key for Etherscan
246 | // Obtain one at https://bscscan.com/
247 | apiKey: bscscanApiKey
248 | },
249 | solidity: "0.8.9"
250 | };
251 | ```
252 | ### Verify Command
253 | !!! warning
254 | Remove any unnecessary contracts and clear the artifacts otherwise these will also be part of the verified contract.
255 |
256 | Run the following command:
257 |
258 | ```
259 | npx buidler verify --network mainnet DEPLOYED_CONTRACT_ADDRESS "Constructor argument 1"
260 | ```
261 |
262 | * Example
263 |
264 | ```shell
265 | $ npx hardhat verify --network testnet 0xbF39886B4F91F5170934191b0d96Dd277147FBB2
266 | Nothing to compile
267 | Compiling 1 file with 0.5.16
268 | Successfully submitted source code for contract
269 | contracts/BEP20Token.sol:BEP20Token at 0xbF39886B4F91F5170934191b0d96Dd277147FBB2
270 | for verification on Etherscan. Waiting for verification result...
271 |
272 | Successfully verified contract BEP20Token on Etherscan.
273 | https://testnet.bscscan.com/address/0xbF39886B4F91F5170934191b0d96Dd277147FBB2#code
274 | ```
275 |
276 | ## Conclusion
277 | This tutorial guided you through the basics of creating and deploying a simple smart contract using the Hardhat IDE. It also provides step-by-step guide on how to verify your deployed smart contract. This tutorial uses testnet, however, the exact same instructions and sequence will work on the mainnet as well.
--------------------------------------------------------------------------------
/04-Deploying-Smart-Contracts-Using-IDEs/remixide.md:
--------------------------------------------------------------------------------
1 |
2 | # Using Remix IDE for Deploying Smart Contracts on BSC
3 |
4 | In this tutorial, we provide guidelines on how to create, compile, and deploy a simple Hello World smart contract on BSC using the [Remix IDE](https://remix.ethereum.org/).
5 |
6 | ### Pre-requisites
7 | There is no need for any local environment settings for deploying solidity smart contracts on BSC using the Remix IDE.
8 |
9 | All you require is a browser-based Web3 wallet (e.g. MetaMask) to interact with the BSC Testnet and deployed contracts. If you are already using MetaMask, it is recommended to create a new account for testing with Replit. You can do this from the account menu, which appears when you click on the account avatar in the top right corner of MetaMask interface.
10 |
11 | You must set up all of the following Pre-requisites to be able to deploy your solidity smart contract on BSC:
12 |
13 | * [Download Metamask wallet](https://metamask.io/)
14 | * [Configure BNB Smart Chain Testnet on Metamask](https://academy.binance.com/en/articles/connecting-metamask-to-binance-smart-chain)
15 | * [Get BNB testnet tokens](https://testnet.binance.org/faucet-smart)
16 |
17 | ### Setting Up Remix IDE
18 |
19 | - Remix is an online IDE to develop smart contracts.
20 | - You need to choose Solidity Compiler, Choose the appropriate compiler version. We used 0.8.15 for this tutorial.
21 |
22 |
23 |
24 | ## Writing the Smart Contract
25 |
26 | - Create a new file, name it ```HelloWorld.sol```, and copy the contract code given below
27 |
28 | ```
29 | // SPDX-License-Identifier: MIT
30 | pragma solidity ^0.8.15;
31 | contract HelloWorld {
32 | function sayHelloWorld() public pure returns (string memory) {
33 | return "Hello World";
34 | }
35 | }
36 | ```
37 |
38 | The first line, `pragma solidity ^0.8.15` specifies that the source code is for a Solidity version greater than 0.8.15. [Pragmas](https://solidity.readthedocs.io/en/latest/layout-of-source-files.html#pragma) are common instructions for compilers about how to treat the source code (e.g., pragma once).
39 |
40 | A contract in the sense of Solidity is a collection of code (its functions) and data (its state) that resides at a specific address on the Ethereum blockchain. Learn more about the [constructor](https://solidity.readthedocs.io/en/latest/contracts.html#constructor) and [memory](https://solidity.readthedocs.io/en/latest/introduction-to-smart-contracts.html#storage-memory-and-the-stack) in the docs.
41 |
42 | ## Compile Smart Contract
43 |
44 | - Step1: Click button to switch to compile page.
45 |
46 | - Step2: Select the appropriate compiler version, 0.8.15 in our case.
47 |
48 | - Step3: Enable "Auto compile" and "Optimization" from Advanced Configurations,
49 |
50 | - Step4: Select "HelloWorld" from the contract drop-down menu.
51 |
52 | - Step5: Click "ABI" to copy the contract ABI and save it.
53 |
54 |
55 |
56 | ## Configure MetaMask and Fund Your Account
57 |
58 | Now, We have to deploy our smart contract on BNB Smart Chain Network. For that, we have to connect to Web3 world, this can be done by many services like MetaMask, Brave, Portis etc. We will be using MetaMask. Please follow this [tutorial to setup a Metamask Account](wallet/metamask.md) for configuring the MetaMask wallet to use with BSC.
59 |
60 |
61 | - Open Metamask and select Custom RPC from the networks dropdown
62 |
63 | - Go to setting page
64 |
65 |
66 |
67 | - Add a new network
68 |
69 |
70 |
71 | * Testnet
72 | * [RPC URLs](./rpc.md)
73 | * ChainID: 97
74 | * Symbol: BNB
75 | * Block Explorer: https://testnet.bscscan.com
76 |
77 | * Mainnet
78 | * [RPC URLs](./rpc.md)
79 | * ChainID: 56
80 | * Symbol: BNB
81 | * Block Explorer: https://bscscan.com
82 |
83 | - Go ahead and click save
84 | - Copy your address from Metamask
85 |
86 | - Head over to [Faucet](https://testnet.binance.org/faucet-smart) and request test BNB
87 |
88 | ## Deploy Smart Contract
89 |
90 | Follow the following steps to deploy the HelloWorld smart contract on the BNB Smart Chain Testnet.
91 |
92 |
93 |
94 | - Step1: Navigate to the Deployment Page.
95 | - Step2: Select Injected Provider in the Environment dropdown
96 | - Step3: Confirm the Connection Request on the MetaMask notification.
97 |
98 |
99 |
100 | - Step4: Once Metamask is connected to Remix, click on the "Deploy" button which would generate another metamask popup that requires transaction confirmation.
101 |
102 |
103 |
104 | **Congratulations!** You have successfully deployed a simple Smart Contract on the BSC Testnet. Now you can interact with the Smart Contract. Check the deployment status here:
105 |
106 | # Flatten and Verify the deployed contract on BscScan
107 |
108 | The first and foremost step is to flatten the solidity contract into a single file to be able to get it verified on [BscScan](https://testnet.bscscan.com/).
109 |
110 | ### Flatten the Smart Contract Code
111 |
112 | * Install [Truffle Flattener](https://github.com/nomiclabs/truffle-flattener) by running the command ```npm install truffle-flattener```
113 | * Flatten the contract by running the command in the ```npx truffle-flattener HelloWorld.sol > FlatHelloWorld.sol``` contracts directory
114 | * Clean up the licensing information.
115 | * The flattened contract will have the same licensing note imported from each of the files.
116 | * Multiple licensing notes in one file break the BscScan verification, so you have to leave one licensing note for the entirety of the flattened contract.
117 | * The easiest way to clean up is to search for the SPDX mentions in the file and remove all of them except for the very first one.
118 |
119 | ### Using Flattened Code to Verify
120 | At this point, you have your flattened and cleaned-up contract ready for the BscScan verification.
121 | * Go to [BscScan Testnet](https://testnet.bscscan.com/).
122 | * Find your deployed contract by searching it using its address.
123 | * On the main page of BscScan, on the header click **Misc > Verify Contract.**
124 | * In Compiler Type, select **Solidity (Single file)**.
125 | * In Compiler Version, select **v0.8.15**. This is the version this tutorial used to compile the contract.
126 | * In Open Source License Type, select **MIT License (MIT)**.
127 | * Click **Continue**.
128 | * Keep the **Optimization** option set to **No** as Remix does not use optimization by default.
129 | * Paste the entirety of your flattened .sol contract in the **Enter the Solidity Contract Code below** field.
130 | * Click **Verify and Publish**.
131 | * BscScan will take a few seconds to compile your contract, verify, and publish it.
132 |
133 |
134 | ## Conclusion
135 | This tutorial guided you through the basics of creating and deploying a simple smart contract using the Remix IDE and MetaMask Web Wallet. It also provides step-by-step guide on how to verify and publish your deployed smart contract. This tutorial uses testnet, however, the exact same instructions and sequence will work on the mainnet as well.
--------------------------------------------------------------------------------
/04-Deploying-Smart-Contracts-Using-IDEs/replit.md:
--------------------------------------------------------------------------------
1 | # Using Replit IDE for Deploying Smart Contracts on BSC
2 |
3 | [Replit](https://docs.replit.com/tutorials/01-introduction-to-the-repl-it-ide) is a coding platform that allows you to write code and host apps. Replit supports [Solidity programming language](https://replit.com/@replit/Solidity-starter-beta?v=1) and provides all of the features and functionality that are required by Web3 developers for creating and deploying smart contracts.
4 |
5 | In this tutorial, we explain how to build and deploy a solidity smart contract on the BSC Testnet using the [Replit IDE](https://replit.com/signup) and the [Replit Solidity Template (Solidity starter beta)](https://replit.com/@replit/Solidity-starter-beta?v=1)
6 |
7 | :::note
8 | For additional examples about Solidity with Replit, you can read the article **[Get started with Replit!](https://blog.replit.com/solidity)** or check **[Replit Solidity documentation and Escrow contract tutorial](https://docs.replit.com/tutorials/33-escrow-contract-with-solidity)**
9 | :::
10 |
11 | ## Pre-Requisites
12 |
13 | There is no need for any local environment settings for deploying solidity smart contracts on BSC using Replit.
14 |
15 | All you require is a browser-based Web3 wallet (e.g. MetaMask) to interact with the BSC Testnet and deployed contracts. If you are already using MetaMask, it is recommended to create a new account for testing with Replit. You can do this from the account menu, which appears when you click on the account avatar in the top right corner of MetaMask interface.
16 |
17 | You must set up all of the following Pre-requisites to be able to deploy your solidity smart contract on BSC:
18 |
19 | 1. [Create a Replit account](https://replit.com/signup)
20 | 2. [Download Metamask wallet](https://metamask.io/)
21 | 3. [Configure BNB Smart Chain Testnet on Metamask](https://academy.binance.com/en/articles/connecting-metamask-to-binance-smart-chain)
22 | 4. [Get BNB testnet tokens](https://testnet.binance.org/faucet-smart)
23 |
24 | ## Working with a Repl
25 |
26 | Every [Repl](https://docs.replit.com/getting-started/using-replit-free#repls) that you create is a fully functional development and production environment. Follow the steps to create a solidity starter Repl:
27 |
28 | 1. [Login](https://replit.com/login) or [create an account](https://replit.com/signup). After creating your [Replit account](https://docs.replit.com/tutorials/01-introduction-to-the-repl-it-ide), your home screen will include a dashboard where you can view, create projects, and manage your account.
29 | 2. Once logged in, create a Solidity starter repl, Select **+ Create Repl** from the left panel or **+** in the top right corner of the screen.
30 | 3. Select the [**Solidity starter (beta)**](https://replit.com/@replit/Solidity-starter-beta?v=1) template and specify a title for your project.
31 | 4. Click on **+ Create Repl** for creating your project.
32 |
33 | > **Note**
34 | The Solidity starter repl comes with a friendly web interface, built using the **[Web3 Ethereum JavaScript API](https://web3js.readthedocs.io/en/v1.5.2/)**, which you can use to deploy and interact with your smart contracts. For this tutorial, we will deploy smart contract on to BNB Smart Chain Testnet.
35 |
36 | ## Create Smart Contract
37 | Delete the contents of the contract.sol file and paste the following solidity code into this file.
38 |
39 | 
40 |
41 | ## Deploy on BSC
42 |
43 | Make sure that you have followed the list of Pre-requisites above so that you are ready to deploy and interact with your smart contract:
44 |
45 | 1. Click on **Run** (at the Top) to install all relevant packages and start up the contract deployment UI.
46 | 2. Click on  icon to open the web interface for deloyment in a new browser tab.
47 | 3. Connect your MetaMask wallet to the web interface and switch to the [BSC Testnet](https://academy.binance.com/en/articles/connecting-metamask-to-binance-smart-chain).
48 | 4. Click on **Connect wallet**, select your account, then choose Connect.
49 |
50 | 
51 |
52 | 
53 |
54 | 5. From the Drop-down list, Select the contract that you want to deploy. Click on **Deploy**.
55 |
56 | 
57 |
58 | 6. Approve the MetaMask notification that appears asking for confirmation of the transaction from your wallet to deploy the smart contract.
59 |
60 | 
61 |
62 | 7. Copy the address of the deployed contract.
63 |
64 | 
65 |
66 | 8. [Navigate to BscScan Testnet Explorer](https://testnet.bscscan.com/) to search and view your deployed contract. Using the contract address to search for it.
67 |
68 | 
69 |
70 | Once your contract has been deployed, it will show up as expandable boxes below the drop-down box. Expand it and take a look at all the different functions available. You can now interact with your contract using the provided user interface or from a sharable URL shown on the interface.
71 |
72 | 
73 |
74 | ## Publish to Replit
75 |
76 | Replit allows you to publish your projects to a personal profile. After publishing, projects will show up on your spotlight page for others to explore, interact with, clone, and collaborate.
77 |
78 | See [Publish your Repl](https://docs.replit.com/hosting/sharing-your-repl#publish-your-repl).
79 |
80 | ## Conclusion
81 | This tutorial guided you through the basics of creating and deploying a smart contract using the Replit IDE. We also provided steps on how to interact with the deployed contract online and publish your replit project. This tutorial uses testnet, however, the exact same instructions and sequence will work on the mainnet as well.
82 |
--------------------------------------------------------------------------------
/04-Deploying-Smart-Contracts-Using-IDEs/truffle.md:
--------------------------------------------------------------------------------
1 |
2 | # Using Remix IDE for Deploying Smart Contracts on BSC
3 |
4 | In this tutorial, we provide guidelines on how to create, compile, and deploy a simple Hello World smart contract on BSC using the [Remix IDE](https://remix.ethereum.org/).
5 |
6 | ### Pre-requisites
7 | There is no need for any local environment settings for deploying solidity smart contracts on BSC using the Remix IDE.
8 |
9 | All you require is a browser-based Web3 wallet (e.g. MetaMask) to interact with the BSC Testnet and deployed contracts. If you are already using MetaMask, it is recommended to create a new account for testing with Replit. You can do this from the account menu, which appears when you click on the account avatar in the top right corner of MetaMask interface.
10 |
11 | You must set up all of the following Pre-requisites to be able to deploy your solidity smart contract on BSC:
12 |
13 | * [Download Metamask wallet](https://metamask.io/)
14 | * [Configure BNB Smart Chain Testnet on Metamask](https://academy.binance.com/en/articles/connecting-metamask-to-binance-smart-chain)
15 | * [Get BNB testnet tokens](https://testnet.binance.org/faucet-smart)
16 |
17 | ### Setting Up Remix IDE
18 |
19 | - Remix is an online IDE to develop smart contracts.
20 | - You need to choose Solidity Compiler, Choose the appropriate compiler version. We used 0.8.15 for this tutorial.
21 |
22 |
23 |
24 | ## Writing the Smart Contract
25 |
26 | - Create a new file, name it ```HelloWorld.sol```, and copy the contract code given below
27 |
28 | ```
29 | // SPDX-License-Identifier: MIT
30 | pragma solidity ^0.8.15;
31 | contract HelloWorld {
32 | function sayHelloWorld() public pure returns (string memory) {
33 | return "Hello World";
34 | }
35 | }
36 | ```
37 |
38 | The first line, `pragma solidity ^0.8.15` specifies that the source code is for a Solidity version greater than 0.8.15. [Pragmas](https://solidity.readthedocs.io/en/latest/layout-of-source-files.html#pragma) are common instructions for compilers about how to treat the source code (e.g., pragma once).
39 |
40 | A contract in the sense of Solidity is a collection of code (its functions) and data (its state) that resides at a specific address on the Ethereum blockchain. Learn more about the [constructor](https://solidity.readthedocs.io/en/latest/contracts.html#constructor) and [memory](https://solidity.readthedocs.io/en/latest/introduction-to-smart-contracts.html#storage-memory-and-the-stack) in the docs.
41 |
42 | ## Compile Smart Contract
43 |
44 | - Step1: Click button to switch to compile page.
45 |
46 | - Step2: Select the appropriate compiler version, 0.8.15 in our case.
47 |
48 | - Step3: Enable "Auto compile" and "Optimization" from Advanced Configurations,
49 |
50 | - Step4: Select "HelloWorld" from the contract drop-down menu.
51 |
52 | - Step5: Click "ABI" to copy the contract ABI and save it.
53 |
54 |
55 |
56 | ## Configure MetaMask and Fund Your Account
57 |
58 | Now, We have to deploy our smart contract on BNB Smart Chain Network. For that, we have to connect to Web3 world, this can be done by many services like MetaMask, Brave, Portis etc. We will be using MetaMask. Please follow this [tutorial to setup a Metamask Account](wallet/metamask.md) for configuring the MetaMask wallet to use with BSC.
59 |
60 |
61 | - Open Metamask and select Custom RPC from the networks dropdown
62 |
63 | - Go to setting page
64 |
65 |
66 |
67 | - Add a new network
68 |
69 |
70 |
71 | * Testnet
72 | * [RPC URLs](./rpc.md)
73 | * ChainID: 97
74 | * Symbol: BNB
75 | * Block Explorer: https://testnet.bscscan.com
76 |
77 | * Mainnet
78 | * [RPC URLs](./rpc.md)
79 | * ChainID: 56
80 | * Symbol: BNB
81 | * Block Explorer: https://bscscan.com
82 |
83 | - Go ahead and click save
84 | - Copy your address from Metamask
85 |
86 | - Head over to [Faucet](https://testnet.binance.org/faucet-smart) and request test BNB
87 |
88 | ## Deploy Smart Contract
89 |
90 | Follow the following steps to deploy the HelloWorld smart contract on the BNB Smart Chain Testnet.
91 |
92 |
93 |
94 | - Step1: Navigate to the Deployment Page.
95 | - Step2: Select Injected Provider in the Environment dropdown
96 | - Step3: Confirm the Connection Request on the MetaMask notification.
97 |
98 |
99 |
100 | - Step4: Once Metamask is connected to Remix, click on the "Deploy" button which would generate another metamask popup that requires transaction confirmation.
101 |
102 |
103 |
104 | **Congratulations!** You have successfully deployed a simple Smart Contract on the BSC Testnet. Now you can interact with the Smart Contract. Check the deployment status here:
105 |
106 | # Flatten and Verify the deployed contract on BscScan
107 |
108 | The first and foremost step is to flatten the solidity contract into a single file to be able to get it verified on [BscScan](https://testnet.bscscan.com/).
109 |
110 | ### Flatten the Smart Contract Code
111 |
112 | * Install [Truffle Flattener](https://github.com/nomiclabs/truffle-flattener) by running the command ```npm install truffle-flattener```
113 | * Flatten the contract by running the command in the ```npx truffle-flattener HelloWorld.sol > FlatHelloWorld.sol``` contracts directory
114 | * Clean up the licensing information.
115 | * The flattened contract will have the same licensing note imported from each of the files.
116 | * Multiple licensing notes in one file break the BscScan verification, so you have to leave one licensing note for the entirety of the flattened contract.
117 | * The easiest way to clean up is to search for the SPDX mentions in the file and remove all of them except for the very first one.
118 |
119 | ### Using Flattened Code to Verify
120 | At this point, you have your flattened and cleaned-up contract ready for the BscScan verification.
121 | * Go to [BscScan Testnet](https://testnet.bscscan.com/).
122 | * Find your deployed contract by searching it using its address.
123 | * On the main page of BscScan, on the header click **Misc > Verify Contract.**
124 | * In Compiler Type, select **Solidity (Single file)**.
125 | * In Compiler Version, select **v0.8.15**. This is the version this tutorial used to compile the contract.
126 | * In Open Source License Type, select **MIT License (MIT)**.
127 | * Click **Continue**.
128 | * Keep the **Optimization** option set to **No** as Remix does not use optimization by default.
129 | * Paste the entirety of your flattened .sol contract in the **Enter the Solidity Contract Code below** field.
130 | * Click **Verify and Publish**.
131 | * BscScan will take a few seconds to compile your contract, verify, and publish it.
132 |
133 |
134 | ## Conclusion
135 | This tutorial guided you through the basics of creating and deploying a simple smart contract using the Remix IDE and MetaMask Web Wallet. It also provides step-by-step guide on how to verify and publish your deployed smart contract. This tutorial uses testnet, however, the exact same instructions and sequence will work on the mainnet as well.
--------------------------------------------------------------------------------
/05-Estimate-L2-Transaction-Gas-Cost/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bnb-chain/bnb-chain-tutorial/6626670d651dc8dd95f2fa5531c18b418d1b8507/05-Estimate-L2-Transaction-Gas-Cost/.DS_Store
--------------------------------------------------------------------------------
/05-Estimate-L2-Transaction-Gas-Cost/sdk-estimate-gas/.env:
--------------------------------------------------------------------------------
1 | # Put the mnemonic for an account on opBNB here
2 | MNEMONIC=""
3 |
4 | # URL to access BNB smart chain testnet
5 | L1URL="https://data-seed-prebsc-1-s1.bnbchain.org:8545"
6 |
7 | # URL to access opBNB testnet
8 | L2URL="https://opbnb-testnet-rpc.bnbchain.org"
--------------------------------------------------------------------------------
/05-Estimate-L2-Transaction-Gas-Cost/sdk-estimate-gas/Greeter.json:
--------------------------------------------------------------------------------
1 | {
2 | "_format": "hh-sol-artifact-1",
3 | "contractName": "Greeter",
4 | "sourceName": "contracts/Greeter.sol",
5 | "abi": [
6 | {
7 | "inputs": [
8 | {
9 | "internalType": "string",
10 | "name": "_greeting",
11 | "type": "string"
12 | }
13 | ],
14 | "stateMutability": "nonpayable",
15 | "type": "constructor"
16 | },
17 | {
18 | "inputs": [],
19 | "name": "greet",
20 | "outputs": [
21 | {
22 | "internalType": "string",
23 | "name": "",
24 | "type": "string"
25 | }
26 | ],
27 | "stateMutability": "view",
28 | "type": "function"
29 | },
30 | {
31 | "inputs": [
32 | {
33 | "internalType": "string",
34 | "name": "_greeting",
35 | "type": "string"
36 | }
37 | ],
38 | "name": "setGreeting",
39 | "outputs": [],
40 | "stateMutability": "nonpayable",
41 | "type": "function"
42 | }
43 | ],
44 | "bytecode": "0x60806040523480156200001157600080fd5b5060405162000c3238038062000c32833981810160405281019062000037919062000278565b6200006760405180606001604052806022815260200162000c1060229139826200008760201b620001ce1760201c565b80600090805190602001906200007f92919062000156565b5050620004c5565b620001298282604051602401620000a0929190620002fe565b6040516020818303038152906040527f4b5c4277000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506200012d60201b60201c565b5050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b8280546200016490620003ea565b90600052602060002090601f016020900481019282620001885760008555620001d4565b82601f10620001a357805160ff1916838001178555620001d4565b82800160010185558215620001d4579182015b82811115620001d3578251825591602001919060010190620001b6565b5b509050620001e39190620001e7565b5090565b5b8082111562000202576000816000905550600101620001e8565b5090565b60006200021d620002178462000362565b62000339565b9050828152602081018484840111156200023657600080fd5b62000243848285620003b4565b509392505050565b600082601f8301126200025d57600080fd5b81516200026f84826020860162000206565b91505092915050565b6000602082840312156200028b57600080fd5b600082015167ffffffffffffffff811115620002a657600080fd5b620002b4848285016200024b565b91505092915050565b6000620002ca8262000398565b620002d68185620003a3565b9350620002e8818560208601620003b4565b620002f381620004b4565b840191505092915050565b600060408201905081810360008301526200031a8185620002bd565b90508181036020830152620003308184620002bd565b90509392505050565b60006200034562000358565b905062000353828262000420565b919050565b6000604051905090565b600067ffffffffffffffff82111562000380576200037f62000485565b5b6200038b82620004b4565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015620003d4578082015181840152602081019050620003b7565b83811115620003e4576000848401525b50505050565b600060028204905060018216806200040357607f821691505b602082108114156200041a576200041962000456565b5b50919050565b6200042b82620004b4565b810181811067ffffffffffffffff821117156200044d576200044c62000485565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b61073b80620004d56000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063a41368621461003b578063cfae321714610057575b600080fd5b6100556004803603810190610050919061043d565b610075565b005b61005f61013c565b60405161006c91906104b7565b60405180910390f35b6101226040518060600160405280602381526020016106e3602391396000805461009e90610610565b80601f01602080910402602001604051908101604052809291908181526020018280546100ca90610610565b80156101175780601f106100ec57610100808354040283529160200191610117565b820191906000526020600020905b8154815290600101906020018083116100fa57829003601f168201915b50505050508361026a565b8060009080519060200190610138929190610332565b5050565b60606000805461014b90610610565b80601f016020809104026020016040519081016040528092919081815260200182805461017790610610565b80156101c45780601f10610199576101008083540402835291602001916101c4565b820191906000526020600020905b8154815290600101906020018083116101a757829003601f168201915b5050505050905090565b61026682826040516024016101e49291906104d9565b6040516020818303038152906040527f4b5c4277000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610309565b5050565b61030483838360405160240161028293929190610510565b6040516020818303038152906040527f2ced7cef000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610309565b505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b82805461033e90610610565b90600052602060002090601f01602090048101928261036057600085556103a7565b82601f1061037957805160ff19168380011785556103a7565b828001600101855582156103a7579182015b828111156103a657825182559160200191906001019061038b565b5b5090506103b491906103b8565b5090565b5b808211156103d15760008160009055506001016103b9565b5090565b60006103e86103e384610581565b61055c565b90508281526020810184848401111561040057600080fd5b61040b8482856105ce565b509392505050565b600082601f83011261042457600080fd5b81356104348482602086016103d5565b91505092915050565b60006020828403121561044f57600080fd5b600082013567ffffffffffffffff81111561046957600080fd5b61047584828501610413565b91505092915050565b6000610489826105b2565b61049381856105bd565b93506104a38185602086016105dd565b6104ac816106d1565b840191505092915050565b600060208201905081810360008301526104d1818461047e565b905092915050565b600060408201905081810360008301526104f3818561047e565b90508181036020830152610507818461047e565b90509392505050565b6000606082019050818103600083015261052a818661047e565b9050818103602083015261053e818561047e565b90508181036040830152610552818461047e565b9050949350505050565b6000610566610577565b90506105728282610642565b919050565b6000604051905090565b600067ffffffffffffffff82111561059c5761059b6106a2565b5b6105a5826106d1565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b82818337600083830152505050565b60005b838110156105fb5780820151818401526020810190506105e0565b8381111561060a576000848401525b50505050565b6000600282049050600182168061062857607f821691505b6020821081141561063c5761063b610673565b5b50919050565b61064b826106d1565b810181811067ffffffffffffffff8211171561066a576106696106a2565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f830116905091905056fe4368616e67696e67206772656574696e672066726f6d202725732720746f2027257327a264697066735822122062b06e5bdee39e73f7ae7ef8606fe9f23da851629e4e297316ce7747f5074b1964736f6c634300080400334465706c6f79696e67206120477265657465722077697468206772656574696e673a",
45 | "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063a41368621461003b578063cfae321714610057575b600080fd5b6100556004803603810190610050919061043d565b610075565b005b61005f61013c565b60405161006c91906104b7565b60405180910390f35b6101226040518060600160405280602381526020016106e3602391396000805461009e90610610565b80601f01602080910402602001604051908101604052809291908181526020018280546100ca90610610565b80156101175780601f106100ec57610100808354040283529160200191610117565b820191906000526020600020905b8154815290600101906020018083116100fa57829003601f168201915b50505050508361026a565b8060009080519060200190610138929190610332565b5050565b60606000805461014b90610610565b80601f016020809104026020016040519081016040528092919081815260200182805461017790610610565b80156101c45780601f10610199576101008083540402835291602001916101c4565b820191906000526020600020905b8154815290600101906020018083116101a757829003601f168201915b5050505050905090565b61026682826040516024016101e49291906104d9565b6040516020818303038152906040527f4b5c4277000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610309565b5050565b61030483838360405160240161028293929190610510565b6040516020818303038152906040527f2ced7cef000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610309565b505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b82805461033e90610610565b90600052602060002090601f01602090048101928261036057600085556103a7565b82601f1061037957805160ff19168380011785556103a7565b828001600101855582156103a7579182015b828111156103a657825182559160200191906001019061038b565b5b5090506103b491906103b8565b5090565b5b808211156103d15760008160009055506001016103b9565b5090565b60006103e86103e384610581565b61055c565b90508281526020810184848401111561040057600080fd5b61040b8482856105ce565b509392505050565b600082601f83011261042457600080fd5b81356104348482602086016103d5565b91505092915050565b60006020828403121561044f57600080fd5b600082013567ffffffffffffffff81111561046957600080fd5b61047584828501610413565b91505092915050565b6000610489826105b2565b61049381856105bd565b93506104a38185602086016105dd565b6104ac816106d1565b840191505092915050565b600060208201905081810360008301526104d1818461047e565b905092915050565b600060408201905081810360008301526104f3818561047e565b90508181036020830152610507818461047e565b90509392505050565b6000606082019050818103600083015261052a818661047e565b9050818103602083015261053e818561047e565b90508181036040830152610552818461047e565b9050949350505050565b6000610566610577565b90506105728282610642565b919050565b6000604051905090565b600067ffffffffffffffff82111561059c5761059b6106a2565b5b6105a5826106d1565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b82818337600083830152505050565b60005b838110156105fb5780820151818401526020810190506105e0565b8381111561060a576000848401525b50505050565b6000600282049050600182168061062857607f821691505b6020821081141561063c5761063b610673565b5b50919050565b61064b826106d1565b810181811067ffffffffffffffff8211171561066a576106696106a2565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f830116905091905056fe4368616e67696e67206772656574696e672066726f6d202725732720746f2027257327a264697066735822122062b06e5bdee39e73f7ae7ef8606fe9f23da851629e4e297316ce7747f5074b1964736f6c63430008040033",
46 | "linkReferences": {},
47 | "deployedLinkReferences": {}
48 | }
49 |
--------------------------------------------------------------------------------
/05-Estimate-L2-Transaction-Gas-Cost/sdk-estimate-gas/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## How to estimate opBNB Layer 2 transaction gas and gas cost
4 |
5 | opBNB leverages the Optimism OP Stack to build the high performance and low cost Layer 2 solution.
6 |
7 | To develop and deploy your own Layer 2 applications on opBNB, you can use the [OP Stack SDK](https://sdk.optimism.io/), which provides a simple and intuitive interface for working with the OP Stack. The OP Stack SDK allows you to estimate the gas usage and gas cost of both the Layer 1 and Layer 2 components of your Layer 2 transactions, so you can optimize your code and minimize your fees.
8 |
9 | Estimate the Layer 1 gas of a particular Layer 2 transaction
10 |
11 | https://sdk.optimism.io/modules.html#estimateL1Gas
12 |
13 | Estimate the Layer 1 gas cost of a particular Layer 2 transaction in wei
14 |
15 | https://sdk.optimism.io/modules.html#estimateL1GasCost
16 |
17 | Similar it also supports the Layer 2 part gas cost
18 |
19 | https://sdk.optimism.io/modules.html#estimateL2GasCost
20 |
21 | And total cost of the Layer 2 transaction
22 |
23 | https://sdk.optimism.io/modules.html#estimateL2GasCost
24 |
25 | You only need to make minor changes to your existing codebase to use the OP Stack SDK.
26 |
27 |
28 | **ENV settings**
29 |
30 | Please configure your mnemonic in the .env file, and the URL is preconfigured to the opBNB testnet and BSC testnet.
31 |
32 |
33 | ```shell
34 | # Put the mnemonic for an account on opBNB here
35 |
36 | MNEMONIC=""
37 |
38 | # URL to access BNB smart chain testnet
39 |
40 | L1URL="https://data-seed-prebsc-1-s1.bnbchain.org:8545"
41 |
42 | # URL to access opBNB testnet
43 |
44 | L2URL="https://opbnb-testnet-rpc.bnbchain.org"
45 | ```
46 |
47 |
48 |
49 | **Steps to run**
50 |
51 | Go the directory of the sdk-estimate-gas
52 |
53 | ```shell
54 | cd sdk-estimate-gas
55 | yarn install
56 | node gas.js --network=testnet
57 | ```
58 |
59 |
--------------------------------------------------------------------------------
/05-Estimate-L2-Transaction-Gas-Cost/sdk-estimate-gas/gas.js:
--------------------------------------------------------------------------------
1 | #! /usr/local/bin/node
2 |
3 | // Estimate the costs of an opBNB
4 |
5 | const ethers = require("ethers")
6 | const optimismSDK = require("@eth-optimism/sdk")
7 | const fs = require("fs")
8 | require('dotenv').config()
9 | const yargs = require("yargs")
10 | const {
11 | boolean
12 | } = require("yargs")
13 |
14 |
15 | const argv = yargs
16 | .option('network', {
17 | // All of those choices are :
18 | // mainnet - opBNB Mainnet, the production network, not live yet
19 | // testnet - opBNB testnet
20 | choices: ["mainnet", "testnet"],
21 | description: 'L2 network to use'
22 | }).
23 | option('verify', {
24 | type: boolean,
25 | description: 'Run the transaction, compare to the estimate'
26 | })
27 | .help()
28 | .alias('help', 'h').argv;
29 |
30 |
31 | const words = process.env.MNEMONIC.match(/[a-zA-Z]+/g).length
32 | validLength = [12, 15, 18, 24]
33 | if (!validLength.includes(words)) {
34 | console.log(`The mnemonic (${process.env.MNEMONIC}) is the wrong number of words`)
35 | process.exit(-1)
36 | }
37 |
38 | const greeterJSON = JSON.parse(fs.readFileSync("Greeter.json"))
39 |
40 | const greeterAddrs = {
41 | "mainnet": "0xcf210488dad6da5fe54d260c45253afc3a9e708c",
42 | "testnet": "0x106941459a8768f5a92b770e280555faf817576f",
43 | }
44 |
45 |
46 | // Utilities
47 | const displayWei = x => x.toString().padStart(20, " ")
48 | const displayGas = x => x.toString().padStart(10, " ")
49 | const sleep = ms => new Promise(resp => setTimeout(resp, ms));
50 |
51 | // Get an L2 signer
52 | const getSigner = async () => {
53 | let endpointUrl;
54 |
55 | if (argv.network == 'testnet')
56 | endpointUrl = process.env.L2URL;
57 | if (argv.network == 'mainnet')
58 | endpointUrl = process.env.L2URL;
59 |
60 | const l2RpcProvider = optimismSDK.asL2Provider(
61 | new ethers.providers.JsonRpcProvider(endpointUrl)
62 | )
63 | const wallet = ethers.Wallet.fromMnemonic(process.env.MNEMONIC).
64 | connect(l2RpcProvider)
65 |
66 | return wallet
67 | } // getSigner
68 |
69 |
70 | // Get estimates from the SDK
71 | const getEstimates = async (provider, tx) => {
72 | return {
73 | totalCost: await provider.estimateTotalGasCost(tx),
74 | l1Cost: await provider.estimateL1GasCost(tx),
75 | l2Cost: await provider.estimateL2GasCost(tx),
76 | l1Gas: await provider.estimateL1Gas(tx)
77 | }
78 | } // getEstimates
79 |
80 |
81 |
82 | const displayResults = (estimated, real) => {
83 | console.log(`Estimates:`)
84 | console.log(` Total gas cost: ${displayWei(estimated.totalCost)} wei`)
85 | console.log(` L1 gas cost: ${displayWei(estimated.l1Cost)} wei`)
86 | console.log(` L2 gas cost: ${displayWei(estimated.l2Cost)} wei`)
87 |
88 | if (argv.verify) {
89 | console.log(`\nReal values:`)
90 | console.log(` Total gas cost: ${displayWei(real.totalCost)} wei`)
91 | console.log(` L1 gas cost: ${displayWei(real.l1Cost)} wei`)
92 | console.log(` L2 gas cost: ${displayWei(real.l2Cost)} wei`)
93 |
94 | console.log(`\nL1 Gas:`)
95 | console.log(` Estimate: ${displayGas(estimated.l1Gas)}`)
96 | console.log(` Real: ${displayGas(real.l1Gas)}`)
97 | console.log(` Difference: ${displayGas(real.l1Gas-estimated.l1Gas)}`)
98 |
99 | console.log(`\nL2 Gas:`)
100 | console.log(` Estimate: ${displayGas(estimated.l2Gas)}`)
101 | console.log(` Real: ${displayGas(real.l2Gas)}`)
102 | console.log(` Difference: ${displayGas(real.l2Gas-estimated.l2Gas)}`)
103 | } else { // if argv.verify
104 | console.log(` L1 gas: ${displayGas(estimated.l1Gas)}`)
105 | console.log(` L2 gas: ${displayGas(estimated.l2Gas)}`)
106 | } // if argv.verify
107 |
108 | } // displayResults
109 |
110 |
111 |
112 | const main = async () => {
113 |
114 | const signer = await getSigner()
115 |
116 | if (!greeterAddrs[argv.network]) {
117 | console.log(`I don't know the Greeter address on chain: ${argv.network}`)
118 | process.exit(-1)
119 | }
120 |
121 | const Greeter = new ethers.ContractFactory(greeterJSON.abi, greeterJSON.bytecode, signer)
122 | const greeter = Greeter.attach(greeterAddrs[argv.network])
123 |
124 | const greeting = "Hello!"
125 |
126 | let real = {}
127 |
128 | const fakeTxReq = await greeter.populateTransaction.setGreeting(greeting)
129 | const fakeTx = await signer.populateTransaction(fakeTxReq)
130 | console.log("About to get estimates")
131 | let estimated = await getEstimates(signer.provider, fakeTx)
132 | estimated.l2Gas = await greeter.estimateGas.setGreeting(greeting)
133 |
134 | if (argv.verify) {
135 | let realTx, realTxResp
136 | const weiB4 = await signer.getBalance()
137 |
138 | // If the transaction fails, error out with additional information
139 | try {
140 | console.log("About to create the transaction")
141 | realTx = await greeter.setGreeting(greeting)
142 | realTx.gasPrice = realTx.maxFeePerGas;
143 | console.log("Transaction created and submitted")
144 | realTxResp = await realTx.wait()
145 | console.log("Transaction processed")
146 | } catch (err) {
147 | console.log(`Error: ${err}`)
148 | console.log(`Coming from address: ${await signer.getAddress()} on Optimistic ${network}`)
149 | console.log(` balance: ${displayWei(await signer.getBalance())} wei`)
150 | process.exit(-1)
151 | }
152 |
153 | // If the balance hasn't been updated yet, wait 0.1 sec
154 | real.totalCost = 0
155 | while (real.totalCost === 0) {
156 | const weiAfter = await signer.getBalance()
157 | real.totalCost = weiB4 - weiAfter
158 | await sleep(100)
159 | }
160 |
161 | // Get the real information (cost, etc.) from the transaction response
162 | real.l1Gas = realTxResp.l1GasUsed
163 | real.l2Gas = realTxResp.gasUsed
164 | real.l1Cost = realTxResp.l1Fee
165 | real.l2Cost = real.totalCost - real.l1Cost
166 | } // if argv.verify
167 |
168 | displayResults(estimated, real)
169 |
170 | } // main
171 |
172 |
173 | main().then(() => process.exit(0))
174 | .catch((error) => {
175 | console.error(error)
176 | process.exit(1)
177 | })
--------------------------------------------------------------------------------
/05-Estimate-L2-Transaction-Gas-Cost/sdk-estimate-gas/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sdk-gas-estimate",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "dependencies": {
7 | "@eth-optimism/sdk": "^1.8.0",
8 | "dotenv": "^16.0.1",
9 | "yarg": "^1.0.8"
10 | },
11 | "scripts": {
12 | "estimate": "node gas.js"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BNB Chain Tutorials
2 | Blockchain tutorials using BNB Chain. Learn how to build Decentralized Applications (Dapps) on BNB Chain and Solidity Smart contracts.
3 |
4 | Covers:
5 | - BNB Chain
6 | - Solidity
7 | - Web3
8 | - Truffle
9 |
10 | ### Organization
11 | - **[01-BSC Hello World Full Stack dApp](https://github.com/bnb-chain/bnb-chain-tutorial/tree/main/01-%20Hello%20World%20Full%20Stack%20dApp%20on%20BSC):** Tutorial on how to develop a simple full-stack dapp with front-end integration on BSC Testnet.
12 | - **[02-BSC Block Explorer](https://github.com/bnb-chain/bnb-chain-tutorial/tree/main/02-BSC-Block-Explorer):** Tutorial on how to develop a simple full-stack dapp that can fetch transaction details from a user given transaction hash.
13 | - **[03-Using BlackIDE for Deploying NFTs](https://github.com/bnb-chain/bnb-chain-tutorial/tree/main/03-Using-BlackIDE-for-Deploying-NFTs):** Tutorial on how to use BlackIDE to deploy NFTs on the BSC testnet and view them in the MetaMask wallet.
14 | - **[04-Deploying Smart Contracts Using IDEs](https://github.com/bnb-chain/bnb-chain-tutorial/tree/main/04-Deploying-Smart-Contracts-Using-IDEs):** Tutorials on how to deploy smart contracts using different IDEs, such as, Chainlink, Hardhat, Truffle, and Remix.
15 |
16 |
--------------------------------------------------------------------------------
/greenfield-website-hosting/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bnb-chain/bnb-chain-tutorial/6626670d651dc8dd95f2fa5531c18b418d1b8507/greenfield-website-hosting/.DS_Store
--------------------------------------------------------------------------------
/greenfield-website-hosting/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Plato | Personal Website
6 |
7 |
8 |
9 |
10 |
Plato
11 |
19 |
20 |
21 |
22 |
23 |
Biography
24 |
25 |
Born around 427 BCE in Athens, Greece, Plato was one of the most important and enduring philosophers of the ancient world. His father, Ariston, was descended from Athenian nobility, while his mother, Perictione, came from a prominent and wealthy family. This aristocratic background undoubtedly influenced Plato's views on the role of the philosophers and the nature of the ideal society.
26 |
27 |
From an early age, Plato showed a deep interest in philosophy and the pursuit of knowledge. He was a pupil of the great philosopher Socrates, who had a profound impact on Plato's thinking. Socrates' method of questioning and exploring fundamental ideas was an important part of Plato's education and would later become a cornerstone of his own philosophical method.
28 |
29 |
After Socrates' execution in 399 BCE, Plato traveled around the Mediterranean, absorbing the teachings of other philosophers as well as engaging in political activities. In 387 BCE, he returned to Athens and founded the Academy, an institution dedicated to the study of philosophy, mathematics, and science. The Academy would become a center of learning that attracted some of the greatest philosophers and thinkers of the ancient world, including Aristotle, who would later become one of Plato's most famous pupils.
30 |
31 |
It was at the Academy that Plato wrote most of his philosophical works, which he composed in the form of dialogues. These dialogues explored a wide range of topics, including ethics, justice, and the nature of reality. Many of them feature Socrates as the main character, serving as a mouthpiece for Plato's ideas. Some of the most famous dialogues include The Republic, an exploration of the ideal society, and The Symposium, a meditation on love and desire.
32 |
33 |
Plato continued to lead the Academy and write dialogues until his death in 347 BCE. His influence on Western philosophy cannot be overstated. The works of Plato have been studied and analyzed for millennia, and his ideas on metaphysics, ethics, and the nature of reality continue to be debated by philosophers today.
34 |
35 |
36 |
37 |
Accomplishments
38 |
Plato's accomplishments include:
39 |
40 |
Establishing the Academy, one of the earliest known
41 | institutions of higher learning.
42 |
Contributing to the development of Western philosophy through
43 | his dialogues.
44 |
Formulating the theory of forms, which postulated that
45 | abstract ideas represent the true reality behind the physical world.
46 |
Influencing numerous philosophers and thinkers throughout
47 | history, shaping the course of philosophy and intellectual thought.
48 |
49 |
50 |
51 |
52 |
Famous Quotes
53 |
54 |
"Wise men speak because they have something to say; fools
55 | because they have to say something."
56 |
57 |
58 |
59 |
"Courage is knowing what not to fear."
60 |
61 |
62 |
63 |
64 |
65 |
Personal Story
66 |
Plato's personal story is one of intellectual pursuit and
67 | philosophical exploration. As a young man, he became a devoted disciple of
68 | Socrates and was greatly influenced by his mentor's teachings and ideas.
69 | Plato witnessed Socrates' trial and subsequent execution, which had a
70 | profound impact on his philosophical views and the nature of justice.
71 |
After Socrates' death, Plato founded the Academy, a center of
72 | learning and philosophical inquiry. The Academy attracted students from
73 | various backgrounds and became a hub for intellectual discussions and
74 | debates. Plato dedicated his life to the pursuit of truth, knowledge, and
75 | the betterment of society through philosophical contemplation and
76 | education.
77 |
78 |
79 |
80 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/greenfield-website-hosting/plato.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bnb-chain/bnb-chain-tutorial/6626670d651dc8dd95f2fa5531c18b418d1b8507/greenfield-website-hosting/plato.jpeg
--------------------------------------------------------------------------------
/greenfield-website-hosting/styles.css:
--------------------------------------------------------------------------------
1 | /* General Styles */
2 | body {
3 | font-family: "Times New Roman", serif;
4 | margin: 0;
5 | padding: 0;
6 | background-color: #F8F8F8;
7 | color: #333;
8 | }
9 |
10 | h1, h2 {
11 | font-family: "Georgia", serif;
12 | }
13 |
14 | /* Header Styles */
15 | header {
16 | background-color: #D3A625;
17 | padding: 20px;
18 | text-align: center;
19 | }
20 |
21 | nav ul {
22 | list-style: none;
23 | margin: 0;
24 | padding: 0;
25 | }
26 |
27 | nav ul li {
28 | display: inline;
29 | margin-right: 10px;
30 | }
31 |
32 | nav ul li a {
33 | text-decoration: none;
34 | color: #FFF;
35 | }
36 |
37 | /* Main Content Styles */
38 | main {
39 | padding: 20px;
40 | }
41 |
42 | section {
43 | margin-bottom: 40px;
44 | }
45 |
46 | h2 {
47 | color: #D3A625;
48 | }
49 |
50 | blockquote {
51 | margin: 0;
52 | padding: 10px;
53 | border-left: 5px solid #D3A625;
54 | }
55 |
56 | /* Footer Styles */
57 | footer {
58 | background-color: #D3A625;
59 | padding: 20px;
60 | text-align: center;
61 | font-size: 14px;
62 | color: #FFF;
63 | }
64 |
65 | /* Image Styles */
66 | .plato-image {
67 | width: 200px;
68 | height: auto;
69 | border-radius: 50%;
70 | margin-bottom: 20px;
71 | }
72 |
--------------------------------------------------------------------------------
/upload-folder.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | print_usage() {
4 | echo "Usage: $0 [OPTIONS] FOLDER_PATH BUCKET_NAME GNFD_CMD_FILEPATH"
5 | echo ""
6 | echo "Upload files from a folder to a bucket using gnfd-cmd."
7 | echo ""
8 | echo "Positional Arguments:"
9 | echo " FOLDER_PATH Path to the folder containing files to upload"
10 | echo " BUCKET_NAME Name of the bucket to upload files to"
11 | echo " GNFD_CMD_FILEPATH Path to the gnfd-cmd executable"
12 | echo ""
13 | echo "Options:"
14 | echo " -h, --help Show this help message and exit"
15 | echo " -v, --verbose Enable verbose mode, echoing execution of each file and progress"
16 | }
17 |
18 | if [[ "$1" == "-h" || "$1" == "--help" ]]; then
19 | print_usage
20 | exit 0
21 | fi
22 |
23 | verbose=false
24 |
25 | while [[ $# -gt 0 ]]; do
26 | key="$1"
27 |
28 | case $key in
29 | -v|--verbose)
30 | verbose=true
31 | shift
32 | ;;
33 | *)
34 | break
35 | ;;
36 | esac
37 | done
38 |
39 | if [ "$#" -ne 3 ]; then
40 | echo "Error: Invalid number of arguments."
41 | echo ""
42 | print_usage
43 | exit 1
44 | fi
45 |
46 | FOLDER_PATH="$1"
47 | BUCKET_NAME="$2"
48 | GNFD_CMD_FILEPATH="$3"
49 |
50 | # Function to get the content type based on file extension
51 | get_content_type() {
52 | case "$1" in
53 | *.html)
54 | echo "text/html"
55 | ;;
56 | *.css)
57 | echo "text/css"
58 | ;;
59 | *.js)
60 | echo "application/javascript"
61 | ;;
62 | *.jpg|*.jpeg)
63 | echo "image/jpeg"
64 | ;;
65 | *.png)
66 | echo "image/png"
67 | ;;
68 | # Add more file extensions and their corresponding content types if needed
69 | *)
70 | echo "application/octet-stream"
71 | ;;
72 | esac
73 | }
74 |
75 | # Function to calculate the total number of files
76 | count_files() {
77 | local folder="$1"
78 | local count=0
79 |
80 | # Iterate over files in the current folder
81 | for file in "$folder"/*; do
82 | if [ -f "$file" ]; then
83 | count=$((count + 1))
84 | elif [ -d "$file" ]; then
85 | # Recursively count files in subfolders
86 | count_subfolder=$(count_files "$file")
87 | count=$((count + count_subfolder))
88 | fi
89 | done
90 |
91 | echo "$count"
92 | }
93 |
94 | # Function to process files recursively
95 | process_files() {
96 | local folder="$1"
97 | local count="$2"
98 | local processed=0
99 |
100 | # Iterate over files in the current folder
101 | for file in "$folder"/*; do
102 | if [ -f "$file" ]; then
103 | filename=$(basename "$file")
104 | content_type=$(get_content_type "$filename")
105 | full_file_path=$(realpath "$file")
106 | gnfd_cmd="$GNFD_CMD_FILEPATH object put --visibility=public-read --contentType=$content_type $full_file_path gnfd://$BUCKET_NAME/$filename"
107 |
108 | if [ "$verbose" = true ]; then
109 | echo "Executing command: $gnfd_cmd"
110 | fi
111 |
112 | # Uncomment the line below to execute the command
113 | eval "$gnfd_cmd"
114 |
115 | processed=$((processed + 1))
116 | if [ "$verbose" = true ]; then
117 | progress=$((processed * 100 / count))
118 | echo "Progress: $progress% ($processed/$count)"
119 | fi
120 | elif [ -d "$file" ]; then
121 | # Recursively process subfolders
122 | process_files "$file" "$count"
123 | fi
124 | done
125 | }
126 |
127 | # Start processing files
128 | if [ "$verbose" = true ]; then
129 | echo "Verbose mode enabled."
130 | total_files=$(count_files "$FOLDER_PATH")
131 | echo "Total files to process: $total_files"
132 | fi
133 |
134 | process_files "$FOLDER_PATH" "$total_files"
135 |
136 |
--------------------------------------------------------------------------------