diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..611b4717 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,37 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..65a404a3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,19 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' +--- + +**Is your feature request related to a problem with the content or with the docs platform? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 00000000..e4f7e0a9 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,10 @@ +## What +* Specify new changes introduced within the docs repo... + +## Why +* Specify why this change is needed... +* Add/tag related issues, if available... + +## Refs +* Add related links (tasks, notion, or jira) +* Add NA if not applicable \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template_main.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template_main.md new file mode 100644 index 00000000..d760f997 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template_main.md @@ -0,0 +1,27 @@ +## Title +* Clear and concise description of the change + +## Description + +* Briefly explain the purpose of the change. +* If applicable, describe the issue that was resolved or the feature that was added. +* Highlight the specific changes made to the documentation. + +## Screenshots/GIFs + +* Include any relevant screenshots or GIFs to visually demonstrate the changes. + +## Testing + +* Describe how you tested the changes to ensure they are correct and do not introduce new issues. + +## Checklist + +[ ] I have read and understood the contributing guidelines. +[ ] I have followed the style guide and formatting guidelines. +[ ] I have added appropriate comments to explain the changes. +[ ] I have tested my changes thoroughly. + +## Additional Notes + +* If there are any specific considerations or concerns, please mention them here. \ No newline at end of file diff --git a/README.md b/README.md index c5308c9e..4068e873 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,11 @@ This repo contains the [Rootstock Developer Portal](https://dev.rootstock.io). The Developer Docs is the home for Rootstock documentation for end users and developers. Check out our quickstarts, tutorials, API reference, and code examples. -_Start your journey to building dApps on Rootstock, see the [quick start guide](./docs/02-developers/04-quickstart/index.md) or see the [setup](#set-up) instructions, or the [contributing](CONTRIBUTING_DOCS.md) guide for how to contribute to Rootstock Documentation._ +_Start your journey to building dApps on Rootstock, see the [Quick Start Guide](./docs/02-developers/04-quickstart/index.md) or see the [setup](#set-up) instructions, or the [contributing](CONTRIBUTING_DOCS.md) guide for how to contribute to Rootstock Documentation._ πŸš€ [Send us feedback](#issues) -πŸš€ Join the [Join the global Rootstock community on Discord](http://discord.gg/rootstock) +πŸš€ Join the [global Rootstock community on Discord](http://discord.gg/rootstock) > This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. For more information on how to use Docusaurus, please refer to the [Docusaurus Documentation](https://docusaurus.io/docs). @@ -61,7 +61,7 @@ Here's a simplified example of how it might look: The main navigation of the website is created based on the root directories in the `/docs` folder. Each directory has its own sidebar for easy navigation. -> Root directories name must contain only a character that is a letter, a number, a dash, or an underscore. If it doesn't, the directory is ignored and won't apear in main navigation. +> Root directories name must contain only a character that is a letter, a number, a dash, or an underscore. If it doesn't, the directory is ignored and won't appear in main navigation. In this case, the main navigation of the website would have two sections: "Guide" and "Tutorial". @@ -82,7 +82,7 @@ For more information on how to use images in Docusaurus, please refer to the [Co Steps: 1. Locate the `docs` folder 2. Create a markdown file in the section you wish to add the docs. -3. Add `title`, `aidebar_label`, `tags`, `description`, and `sidebar_position` attributes +3. Add `title`, `sidebar_label`, `tags`, `description`, and `sidebar_position` attributes to the front matter as appropriate - see below for more details. 4. If the new page is within a collection, and it is named `index.md`, add a `section_title`, `menu_title`. Ensure that you set a `permalink` attribute in the front matter, with a trailing `/`. @@ -266,4 +266,4 @@ Fill it in accordingly. Note that **What** and **Why** sections are compulsory, and the **Refs** section is optional. -> Note to run `yarn build` to test the build output of your branch prior to creating a new pull request, or pushing more commits to an existing one. Don't introduce any regressions! \ No newline at end of file +> Note to run `yarn build` to test the build output of your branch prior to creating a new pull request, or pushing more commits to an existing one. Don't introduce any regressions! diff --git a/docs/01-concepts/powpeg/index.md b/docs/01-concepts/powpeg/index.md index ef10bc21..28d165e4 100644 --- a/docs/01-concepts/powpeg/index.md +++ b/docs/01-concepts/powpeg/index.md @@ -13,6 +13,7 @@ Rootstock’s **PowPeg** protocol, has matured from its inception in 2018 as a f - The PowPeg App is available on [Testnet](https://powpeg.testnet.rootstock.io/) and [Mainnet](https://powpeg.rootstock.io/). - For general information about the design and architecture, how to perform a peg-in transaction using Ledger and Trezor, Frequently asked questions and advanced operations you can perform on the PowPeg, please refer to the [PowPeg user guide](/resources/guides/powpeg-app/). - Get information on the signatories and attestion in the [PowPeg HSM Firmware Attestation](/concepts/powpeg/hsm-firmware-attestation) section. +- Read [Introducing Fast Mode: Getting RBTC via the PowPeg, but Faster](https://blog.rootstock.io/noticia/get-rbtc-fast-mode/) to learn about the difference between Native Mode and Fast Modes when using the PowPeg. ::: ## The History of the PowPeg Protocol diff --git a/docs/01-concepts/rif-suite/rns/getting-started/index.md b/docs/01-concepts/rif-suite/rns/getting-started/index.md new file mode 100644 index 00000000..7a815518 --- /dev/null +++ b/docs/01-concepts/rif-suite/rns/getting-started/index.md @@ -0,0 +1,8 @@ +--- +sidebar_label: Getting Started +sidebar_position: 500 +title: "Getting Started" +tags: [rif, rns, Getting Started] +description: "" +--- + diff --git a/docs/01-concepts/rif-suite/rns/index.md b/docs/01-concepts/rif-suite/rns/index.md new file mode 100644 index 00000000..9aca5a8b --- /dev/null +++ b/docs/01-concepts/rif-suite/rns/index.md @@ -0,0 +1,125 @@ +--- +sidebar_label: RNS +sidebar_position: 400 +title: "RIF RNS: RIF Name Service | Rootstock (RSK)" +tags: [rif, rns, rif-name-service, rsk] +description: "Information about the RIF token, where to obtain it, how to transfer it, and technical details on its token standard" +--- + +RNS provides an architecture which enables the identification of blockchain addresses by human-readable names. + + + +
+
+
+
+ Try the service +
+
+

Register a domain in the Testnet, for free.

+
+
+
+
+ Integrate with RNS +
+
+

Easy guides on how to integrate RNS in your solution.

+
+
+
+
+
+
+ Develop on top of RNS +
+
+

Deploy RNS suite in your local development environment

+
+
+
+
+ Use the libraries +
+
+

Use simple libraries to interact with RNS service.

+
+
+
+
+ +## The stack + +![image](/img/rif/rns/theStack.png) + +## Motivation + +By adding a name resolution service, also known as β€œalias”, the probability of errors is significantly reduced. In addition, centralizing the access to multiple resources associated with a human-readable name improves the blockchain platform user experience. As resource names may change over time, the system needs to be flexible to support frequent changes. + +Currently over the World Wide Web, the Domain Name System (DNS) is responsible for mapping human-readable names to IP addresses. RNS is a decentralized and secure service that works over RSK's blockchain. + +Here’s a refined version of your text, maintaining the same tone and voice: + + +## Design + +RNS is a hierarchical namespace inspired by DNS, where the hierarchy roughly reflects organizational structure, with levels separated by the "." character. + +The design of the RIF Name Service is shaped by specific goals: + +- The primary objective is to establish a consistent namespace for referencing resources. +- Each piece of data associated with a name is tagged with a type, allowing queries to be limited to a specific type. +- To ensure the namespace is adaptable across different networks and applications, RNS supports the use of the same namespace with various protocol families or management systems. Data in RNS is tagged with both a class and a type, enabling the parallel use of different formats for data of type "address." +- There may be trade-offs between data acquisition costs, update speed, and cache accuracy. The domain owner, as the data source, should consider these trade-offs and decide what to store and how to cache it. + +> [RNS specs](./specs) + + +## Elements of the RNS + +RNS has four major components: + +| **Component** | **Description** | **Specs** | +|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------| +| **RNS Registry** | The RNS Registry is a specification for a tree-structured namespace and the data associated with the names. Conceptually, each node and leaf in the domain name space tree represents a set of information. Query operations attempt to extract specific types of information from a particular set. A query specifies the domain name of interest and the type of resource information desired. | [Specs](./specs/registry) | +| **RNS Resolvers** | RNS Resolvers are contracts that provide information from a name in response to client requests. Resolvers must answer a query directly or use referrals to other resolvers. Typically, a resolver is a contract's public function that is directly accessible to user programs or other contracts. No specific protocol is required between the resolver and the user program. | [Specs](./specs/resolver) | +| **RNS Registrar** | The RNS Registrar is a critical component within the RIF Name Service, managing the registration of `.rsk` domain names. This contract has the authority to register names in the RSK Owner contract, ensuring that new domain registrations are handled securely and efficiently. | [Specs](./specs/registrar) | +| **Renewer** | The Renewer is a contract designed to facilitate the renewal of names registered in the Node Owner. It is equipped with permissions to renew these names and provides flexibility in how the renewal is executed. + +These fours components roughly correspond to the four layers or views of the domain system: +- From the user's point of view, the domain system is accessed through a simple resolution operation. The domain space consists of a single tree and the user can request information from any section of the tree. +- From the resolver's point of view, the domain system is composed of an unknown number of names. Each name has a corresponding resolver that provides information for a set of resolution types directly. +- From the registry's point of view, the domain system consists of a hierarchical tree where each leaf has an owner (contract or account) and an associated resolver that provides information of the name. +- From the **renewal's point of view**, the domain system ensures continued ownership through renewal processes, facilitating the payment of fees for name renewals via supported methods like ERC-20 or ERC-677. + + +## Guidelines on use + +Before RNS can be used to hold naming information for some kind of object, two needs must be met: +- A convention for mapping between object names and domain names. This describes how information about an object is accessed. Find specs [here](specs#name-mapping-convention) +- Resource record types and data formats for describing the object. Find specs. + +The guideline for finding a specific record for a name is as follows: +1. Calculate the name identifier with [`namehash` function](specs#name-mapping-convention). +2. Get the name's resolver address via [`resolver(bytes32)`](specs/registry#AcessFunctions). +3. Determine if resolver supports desired resource record via [ERC-165 interface detection](https://eips.ethereum.org/EIPS/eip-165). +4. Get the desired resource record. Find currently standardized [resolvers](./specs/resolver). + +> Guidelines on integration + +### Resource records + +A domain name identifies a node. Each node has a set of resource information, which may be empty. The set of resource information associated with a particular name is composed of separate resource records (RRs). The order of RRs in a set is not significant. Resource records associated with a name are found in the domain's resolver diff --git a/docs/01-concepts/rif-suite/rns/specs/index.md b/docs/01-concepts/rif-suite/rns/specs/index.md new file mode 100644 index 00000000..34f349b3 --- /dev/null +++ b/docs/01-concepts/rif-suite/rns/specs/index.md @@ -0,0 +1,66 @@ +--- +sidebar_label: Spec +sidebar_position: 400 +title: "Specification" +tags: [rif, rns, spec] +description: "The domain name space is a tree structure. Each node and leaf on the tree corresponds to a resource set (which may be empty)." +--- + +The domain name space is a tree structure. Each node and leaf on the tree corresponds to a resource set (which may be empty). + +The domain system makes no distinctions between the uses of the interior nodes and leaves, and this memo uses the term "node" to refer to both. + +The domain name of a node is the list of the labels on the path from the node to the root of the tree. By convention, the labels that compose a domain name are printed or read left to right, from the most specific (lowest, farthest from the root) to the least specific (highest, closest to the root). + +When a user needs to type a domain name, the length of each label is omitted and the labels are separated by dots `(.)`. + +Since a complete domain name ends with the root label, this leads to a printed form which ends in a dot, that is omitted. For example, a valid domain name is `wallet.alice.rsk`. + +## Valid names +For simplicity, a valid RNS domain is defined as follows: + +- TLD is one of the predefined TLDs, which currently may only be `rsk` +- The first label is compulsory +- Any second and subsequent labels are optional +- All labels must be alphanumeric and lower case +- All labels and the TLD are delimited by `.` + +The reference implementation for RNS domain validation can be found in [RNS SDK](https://www.npmjs.com/package/@rsksmart/rns-sdk) + +- AVAILABLE_TLDS in src/constants.ts +- isValidDomain and isValidLabel in src/utils.ts + + +Example #1: uno2tres.rsk is valid: + +βœ”οΈ TLD is rsk +βœ”οΈ First label is uno2tres; which is present and lowercase alphanumeric +βœ”οΈ Second and subsequent labels are not present + +Example #2: rss.website.alice.rsk is valid: + +- βœ”οΈ TLD is rsk +- βœ”οΈ First label is alice; which is present and lowercase alphanumeric +- βœ”οΈ Second label is website; which is present and lowercase alphanumeric +- βœ”οΈ Third label is rss; which is present and lowercase alphanumeric + +Example #3: my_illegal_domain.com is invalid: + +- ❌ TLD is com +- ❌ First label is my_illegal_domain; which is present, however contains non-alphanumeric characters +- βœ”οΈ Second and subsequent labels are not present + +## Name mapping convention +Each domain name has a node identifier in the RNS Registry, that is obtained via `namehash` functions, that is as follows: + +```python +def namehash(name): + if name == '': + return '\0' * 32 + else: + label, _, remainder = name.partition('.') + return sha3(namehash(remainder) + sha3(label)) +``` + +Given a `node`, a `subnode` can be identified by using its label: `sha3(namehash(node) + sha3(label))` + diff --git a/docs/01-concepts/rif-suite/rns/specs/registrar.md b/docs/01-concepts/rif-suite/rns/specs/registrar.md new file mode 100644 index 00000000..56092afd --- /dev/null +++ b/docs/01-concepts/rif-suite/rns/specs/registrar.md @@ -0,0 +1,88 @@ +--- +sidebar_label: Registrar Specs +sidebar_position: 400 +title: "Registry Specs" +tags: [rif, rns, rif-name-service, Registrar Specs] +description: "The registry contract provides a simple mapping between a domain and its resolver. " +--- + +### FIFSRegistrarBase.sol Contract Specification + +The `FIFSRegistrarBase` contract implements a First-In-First-Served (FIFS) registration mechanism for domain names within the RNS system. The contract follows a structured process to ensure secure and fair registration of domain names. Below is a detailed breakdown of the registration process and key functions: + +#### Registration Steps + +1. **Calculate Commitment Hash (Off-chain)** + - The first step in registering a domain name is to calculate a commitment hash off-chain using the `makeCommitment` function. This hash ensures that the registration process remains secure by preventing front-running attacks. + - **Function: `makeCommitment`** + - **Parameters**: + - `label`: The keccak256 hash of the domain name to be registered. + - `nameOwner`: The address of the owner of the domain name. + - `secret`: A secret value to protect the name registration. + - **Returns**: The commitment hash (`bytes32`). + - **Usage Note**: This function should be used off-chain and not on-chain when committing. + + ```solidity + function makeCommitment(bytes32 label, address nameOwner, bytes32 secret) public pure returns (bytes32) { + return keccak256(abi.encodePacked(label, nameOwner, secret)); + } + ``` + +2. **Commit the Calculated Hash** + - Once the commitment hash is calculated, it must be submitted to the contract to initiate the registration process. + - **Function: `commit`** + - **Parameters**: + - `commitment`: The valid commitment hash obtained from `makeCommitment`. + - **Usage Note**: The commitment must be unique, and the function ensures that no duplicate commitments are made. + + ```solidity + function commit(bytes32 commitment) external { + require(commitmentRevealTime[commitment] < 1, "Existent commitment"); + commitmentRevealTime[commitment] = now.add(minCommitmentAge); + } + ``` + +3. **Wait for the Commitment to Mature** + - After committing, there is a mandatory waiting period (`minCommitmentAge`) to ensure the commitment is valid and secure. During this time, the commitment cannot be revealed or used to register the domain. + - **Function: `canReveal`** + - **Parameters**: + - `commitment`: The commitment hash to be queried. + - **Returns**: `true` if the commitment can be revealed, `false` otherwise. + + ```solidity + function canReveal(bytes32 commitment) public view returns (bool) { + uint revealTime = commitmentRevealTime[commitment]; + return 0 < revealTime && revealTime <= now; + } + ``` + +4. **Execute Registration** + - Once the commitment is ready to be revealed, the actual registration of the domain can be performed. The `FIFSRegistrarBase` contract supports multiple ways to execute this registration, such as using ERC-20 or ERC-677 tokens. + - **Function: `register`** + - **Parameters**: + - `name`: The domain name to register. + - `nameOwner`: The owner of the domain. + - `secret`: The secret used in the commitment process. + - `duration`: The registration duration in years. + - **Usage Note**: The registration cost is calculated based on the domain name and is transferred using RIF tokens. + + ```solidity + function register(string calldata name, address nameOwner, bytes32 secret, uint duration) external { + uint cost = executeRegistration(name, nameOwner, secret, duration); + require(rif.transferFrom(msg.sender, pool, cost), "Token transfer failed"); + } + ``` + + - **Function: `tokenFallback`** + - **Parameters**: + - `from`: The address sending the tokens. + - `value`: The amount of tokens sent. + - `data`: Additional data for the registration process. + - **Returns**: `true` if the transaction is successful. + + ```solidity + function tokenFallback(address from, uint value, bytes calldata data) external returns (bool) { + require(msg.sender == address(rif), "Only RIF token"); + require(data.length > 88, "Invalid data"); + } + ``` \ No newline at end of file diff --git a/docs/01-concepts/rif-suite/rns/specs/registry.md b/docs/01-concepts/rif-suite/rns/specs/registry.md new file mode 100644 index 00000000..1a2b5ba9 --- /dev/null +++ b/docs/01-concepts/rif-suite/rns/specs/registry.md @@ -0,0 +1,68 @@ +--- +sidebar_label: Registry Specs +sidebar_position: 400 +title: "Registry Specs" +tags: [rif, rns, rif-name-service, Registry Specs] +description: "The registry contract provides a simple mapping between a domain and its resolver. " +--- + +The registry contract provides a simple mapping between a domain and its resolver. + +This contract manages all aspects of domain ownership, including transferring ownership and creating subdomains. + +Each entry in the registry points to a resolver, which handles the resolution between the name domain and the desired resource. + +The RNS Registry contract provides both data access and modification capabilities through the following functions: + + +## Access Functions + +- Ownership + ``` + function owner(bytes32 node) constant returns (address); + ``` + + Retrieves the owner (registrar) of the specified node. + +- Resolution + ``` + function resolver(bytes32 node) constant returns (address); + ``` + + Returns the resolver for the specified node. + +- Caching + ``` + function ttl(bytes32 node) constant returns (uint64); + ``` + Retrieves the time-to-live (TTL) of the specified node. The TTL defines the maximum period during which the node's information can be cached. + +## Modify Functions +The RNS Registry contract also allows for the modification of node data through the following functions: + +- Ownership + ``` + function setOwner(bytes32 node, address owner); + ``` + + Transfers ownership of a node to another registrar. This function may only be called by the current owner of node. A successful call to this function logs the `Transfer(bytes32 indexed, address)` event. + + ``` + function setSubnodeOwner(bytes32 node, bytes32 label, address owner); + ``` + + Creates a new node `label.node` and sets its owner to owner, or updates the node with a new owner if it already exists. This function may only be called by the current owner of node. A successful call to this function logs the `NewOwner(bytes32 indexed, bytes32 indexed, address)` event. + +- Resolution + ``` + function setResolver(bytes32 node, address resolver); + ``` + + Sets the Resolver address for node, the contract that handles the desired resolutions. This function may only be called by the owner of node. A successful call to this function logs the `NewResolver(bytes32 indexed, address)` event. + +- Caching + ``` + function setTTL(bytes32 node, uint64 ttl); + ``` + Sets the TTL for a node. A node's TTL applies to the 'owner' and 'resolver' records in the Registry, as well as to any information returned by the associated resolver. + diff --git a/docs/01-concepts/rif-suite/rns/specs/resolver.md b/docs/01-concepts/rif-suite/rns/specs/resolver.md new file mode 100644 index 00000000..ad0a9514 --- /dev/null +++ b/docs/01-concepts/rif-suite/rns/specs/resolver.md @@ -0,0 +1,252 @@ +--- +sidebar_label: Resolver Specs +sidebar_position: 400 +title: "Resolver Specs" +tags: [rif, rns, rif-name-service, Resolver Specs] +description: "Resolvers may implement any subset of the record types specified here. Where a record types specification requires a resolver to provide multiple functions." +--- + +Resolvers may implement any subset of the record types specified here. Where a record types specification requires a resolver to provide multiple functions, the resolver MUST implement either all or none of them. + +Resolvers MUST specify a fallback function that throws. + +Resolvers must implement ERC-165 interface detection standard. supportsInterface method must return if the interfaceID queried is simply equal to the signature hash of the function that resolves the desired resource record. + +Currently standardized resolver interfaces are specified below. + +> Check out [definitive resolver](/rif/rns/architecture/definitive-resolver) for implementation details. + + +### Contract address + +Provides the contract address for the specified domain. + +```solidity +function addr(bytes32 node) returns (address); +``` + +- `node`: the namehash of the domain to query for. +- Returns the contract address of the specified domain. A zero address is returned if the node has no address specified. + +When updated emits + +```solidity +event AddrChanged(bytes32 indexed node, address a); +``` + +Interface ID: `0x3b3b57de` + +Specification: [EIP-137](https://eips.ethereum.org/EIPS/eip-137#resolver-specification) + +Resolution protocol: + +1. Query the resolver address to the registry. +2. Query `addr` to the resolver contract. +3. Check for non zero-address response. + +> No modifications to the adoption of this protocol. + +### Multicoin address + +Add multiple `addr` fields for resolvers, which permit resolution of addresses across multiple blockchains. + +```solidity +function addr(bytes32 node, uint coinType) external view returns(bytes memory); +``` + +- `node`: The name hash of the domain to query for. +- `coinType`: The cryptocurrency coin type index from [SLIP44](https://github.com/satoshilabs/slips/blob/master/slip-0044.md). +- Returns the cryptocurency address in its native binary format. A zero-length string is returned if the specified coin ID does not exist on the specified node. + +> Detailed descriptions of the binary encodings for several popular chains are provided in the [Address Encoding section](https://eips.ethereum.org/EIPS/eip-2304#address-encoding) of EIP-2304. + +When updated emits + +```solidity +event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress); +``` + +Specification: [EIP-2304](https://eips.ethereum.org/EIPS/eip-2304) + +Interface ID: `0xf1cb7e06` + +Deprecates: [RNSIP-03](https://github.com/rnsdomains/RNSIPs/blob/master/IPs/RNSIP03.md) + +Resolution protocol: + +1. Query the resolver address to the registry. +2. Query `addr` to the resolver contract with the specified coin type. +3. Check for non zero-length string response. + +Resolvers implementing this interface may utilise a fallback strategy regarding backward compatibility. + +1. Query the resolver address to the registry. +2. Query `addr` to the resolver contract with the specified coin type. +3. If zero-length string is returned, query `chainAddr` to the resolver contract. +4. Check for non zero-length string response. + +### Contenthash + +System of mapping names to network and content addresses. + +```solidity +function contenthash(bytes32 node) external view returns (bytes memory); +``` + +- `node`: the namehash of the domain to query for. +- Returns a machine-readable multicodec representation of the content address. The format is specified as follows: ``. + +> `protoCode`s and their meanings are specified in the [multiformats/multicodec](https://github.com/multiformats/multicodec) repository. + +When updated emits: + +```solidity +event ContenthashChanged(bytes32 indexed node, bytes hash); +``` + +Interface ID: `0xbc1c58d1` + +Specification: [EIP-1577](https://eips.ethereum.org/EIPS/eip-1577) + +Deprecates: `content` and [`multihash`](https://eips.ethereum.org/EIPS/eip-1577) fields. + +Resolution protocol: + +1. Query the resolver address to the registry. +2. Query `contenthash` to the resolver contract. +3. Check for non zero-length string response. + +Resolvers implementing this interface may utilise a fallback strategy regarding backward compatibility. + +1. Query the resolver address to the registry. +2. Query `contenthash` to the resolver contract. +3. If zero-length string is returned, query `multihash` to the resolver contract. +4. If zero-length string is returned, query `content` to the resolver contract. +5. Check for non zero-length string response. + + +### Contract ABI + +Easy lookup of contract interfaces by callers + +```solidity +function ABI(bytes32 node, uint256 contentType) constant returns (uint256, bytes memory); +``` + +- `node`: the namehash of the domain to query for. +- `contentType`: a bitwise OR of the ABI formats accepted by the caller. +- Returns the content type of the return value and the ABI data. `(0, "")` is returned if the domain has no ABI specified, or does not support any of the requested formats. + +> The currently recognised encodings are described in [ABI encodings section](https://eips.ethereum.org/EIPS/eip-205#abi-encodings) EIP-205. + +When updated emits: + +```solidity +event ABIChanged(bytes32 indexed node, uint256 indexed contentType); +``` + +> Notice that the updated content is not emitted. It requires an extra query to get the resource record when logged, but saves gas setting it. + +Interface ID: `0x2203ab56` + +Specification: [EIP-205](https://eips.ethereum.org/EIPS/eip-205) + +Resolution protocol: + +1. Query the resolver address to the registry. +2. Query `ABI` to the resolver contract with a bitwise OR of the ABI formats accepted by the caller. +3. Check for a response that is not `(0, "")`. + +### SECP256k1 public keys + +Permits the lookup of SECP256k1 public keys. + +```solidity +function pubkey(bytes32 node) constant returns (bytes32 x, bytes32 y); +``` + +- `node`: the namehash of the domain to query for. +- Returns the coordinates of an uncompressed SECP256k1 curve point comprising the public key. A `(0, 0)` value is returned if the domain has no pubkey specified. + +When updated emits: + +```solidity +event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y); +``` + +Interface ID: `0xc8690233` + +Specification: [EIP-619](https://github.com/ethereum/EIPs/pull/619) + +Resolution protocol: + +1. Query the resolver address to the registry. +2. Query `pubkey` to the resolver contract. +3. Check for non `(0, 0)` response. + +### Text records + +Permits the lookup of arbitrary key-value text data. + +```solidity +function text(bytes32 node, string key) constant returns (string text); +``` + +- `node`: the namehash of the domain to query for. +- `key`: the text data key to query. +- Returns the associated text data. If the key is not present, the zero-length string is returned. + +> For supported keys refer to the [initial recommended keys section of EIP-634](https://eips.ethereum.org/EIPS/eip-634#initial-recommended-keys). + +When updated emits: + +```solidity +event TextChanged(bytes32 indexed node, string indexed indexedKey, string key); +``` + +Interface ID: `0x59d1d43c` + +Specification: [EIP-634](https://eips.ethereum.org/EIPS/eip-634) + + +Resolution protocol: + +1. Query the resolver address to the registry. +2. Query `text` to the resolver contract with the specified key. +3. Check for non zero-length string response. + +### Interface discovery + +Defines a method of associating contract interfaces with domains and addresses, and of discovering those interfaces. + +```solidity +function interfaceImplementer(bytes32 node, bytes4 interfaceID) external view returns (address); +``` + +- `node`: the namehash of the domain to query for. +- `interfaceID`: The EIP 165 interface ID to query for. +- Returns the address of a contract that implements the specified interface for the given domain. A zero-address value is returned if there is no interface matching that interface ID for that node. + +When updated emits: + +```solidity +event InterfaceChanged(bytes32 indexed node, bytes4 indexed interfaceID, address implementer); +``` + +Interface ID: `0xb8f2bbb4` + +Specifitcation: [EIP-1844](https://eips.ethereum.org/EIPS/eip-1844) + +Resolution protocol: + + +1. Query the resolver address to the registry. +2. Query `interfaceImplementer` to the resolver contract with the specified interface ID. +4. Check for non zero-address response. + +Resolvers implementing this interface may utilise a fallback strategy. This strategy has nothing to do with backward compatibility. + +1. Query the resolver address to the registry. +2. Query `interfaceImplementer` to the resolver contract with the specified interface ID. +3. If zero-address string is returned, query `addr` to the resolver contract and query `supportsInterface` to the given contract address. +4. Check for non zero-address response. diff --git a/docs/01-concepts/rif-suite/token/index.md b/docs/01-concepts/rif-suite/token/index.md index 93c46a80..dd246044 100644 --- a/docs/01-concepts/rif-suite/token/index.md +++ b/docs/01-concepts/rif-suite/token/index.md @@ -70,9 +70,9 @@ The Rootstock Infrastructure Framework (RIF) Token allows any token holder to co -## stRIF (RIF Token in DAO) +## stRIF (Staked RIF Token in the RootstockCollective DAO) -The stRIF tokens give you voting rights and participation in the DAO's governance and decision-making process. To acquire stRIF tokens, you need to stake RIF tokens in the governance system dApp. RIF tokens can be purchased through [various exchanges](https://wiki.rootstockcollective.xyz/Token-Resources-e3f89008a96e4dcab3037ff7861d9d8a), and once staked, an equivalent amount of stRIF is issued for governance participation. +The stRIF tokens give you voting rights and participation in the RootstockCollective DAO's governance and decision-making process they are pegged 1:1 with RIF. To acquire stRIF tokens, you need to stake RIF tokens in the [governance system dApp](https://app.rootstockcollective.xyz). RIF tokens can be purchased through [various exchanges](https://wiki.rootstockcollective.xyz/Token-Resources-e3f89008a96e4dcab3037ff7861d9d8a), and once staked, an equivalent amount of stRIF is issued for governance participation. @@ -82,29 +82,21 @@ The stRIF tokens give you voting rights and participation in the DAO's governanc - + - - + + - - - - diff --git a/docs/02-developers/02-requirements/index.md b/docs/02-developers/02-requirements/index.md index 80e72e6d..d69aa283 100644 --- a/docs/02-developers/02-requirements/index.md +++ b/docs/02-developers/02-requirements/index.md @@ -15,13 +15,13 @@ Participating in a Rootstock hackathon or Workshop? View the [Hackathon Resource ::: ## Solidity Version -- Supported solc version: `0.8.20` +- Supported solc version: `0.8.19` ## Node RPC - Interact with Rootstock using the [RPC API](https://rpc.rootstock.io/) :::tip[Get an API Key] -See how to setup the RPC API and get an [API Key](/developers/rpc-api/setup). +See how to setup the RPC API and get an [API Key](/developers/rpc-api/rootstock/setup/). ::: ## Connecting to a Wallet @@ -67,6 +67,23 @@ npm i -g hardhat-shorthand ::: +## Install Foundry +:::note[Development Environments] +You don't need to use both development environments (Hardhat and Foundry) together, you can use your favorite one. +::: + +To install Foundry in your system, run the following command: +```bash +curl -L https://foundry.paradigm.xyz | bash +``` +This will install Foundryup. Simply follow the on-screen instructions, and the ```foundryup``` command will become available in your CLI. + +Running ```foundryup``` will automatically install the latest (nightly) versions of the ```precompiled binaries```: ```forge```, ```cast```, ```anvil```, and ```chisel```. For additional options, such as installing a specific version or commit, run ```foundryup --help```. + +:::note[Windows Users] +If you’re using Windows, you’ll need to install and use [Git BASH](https://gitforwindows.org/) or [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) as your terminal, since Foundryup currently doesn’t support Powershell or Command Prompt (Cmd). +::: + ## Command Line Tools ### POSIX Compliant Shell diff --git a/docs/02-developers/04-quickstart/ape.md b/docs/02-developers/04-quickstart/ape.md new file mode 100644 index 00000000..3fa19230 --- /dev/null +++ b/docs/02-developers/04-quickstart/ape.md @@ -0,0 +1,331 @@ +--- +section_position: 400 +sidebar_label: Getting Started with Ape +title: Getting Started with Ape +description: 'How to compile, deploy, and intereact with smart contracts with Ape on Rootstock' +tags: [rsk, ape, apeworx, developers, developer tools, tRBTC, rootstock, testing, dApps, smart contracts] +--- + +The [Ape Framework](https://apeworx.io/framework/) is an easy-to-use Web3 development tool. Developers can compile, test, and interact with smart contracts all in one command line session. With its [modular plugin system](https://github.com/ApeWorX/ape?tab=readme-ov-file#plugin-system), Ape supports multiple contract languages and chains including Rootstock. + +In this guide, we will learn about the [Ape Framework](https://apeworx.io/framework/) and its benefits for smart contract development, how to setup your development environment, create a Ape project and execute a deployment script for Rootstock. + +## Prerequisites +To get started with Ape, ensure the following tools are installed: +- Linux or macOS +- Python 3.9 up to 3.12 +- Windows: Install Windows Subsystem Linux [(WSL](https://learn.microsoft.com/en-us/windows/wsl/install)) +- Check the python version in a terminal with python3 --version. + +## Create a Ape project +To start a new project with Ape, install Ape and then create a new one: + +1. Create a directory for the project + ```bash + mkdir ape && cd ape + ``` + +2. Install pipx + +> Only neccessary if you don't have [pipx](https://github.com/pypa/pipx) installed: + ```bash + python3 -m pip install --user pipx + python3 -m pipx ensurepath + ``` + +3. Install Ape using pipx + ```bash + pipx install eth-ape + ``` + +4. Create an empty project + ```bash + ape init + ``` +5. Enter a name for your project + ```bash + ape init + Please enter project name: ape-rootstock-demo + + SUCCESS: ape-rootstock-demo is written in ape-config.yaml + + ls + ape-config.yaml contracts scripts tests + ``` + +A common project structure looks like this: + +``` +project # The root project directory +β”œβ”€β”€ contracts/ # Project source files, such as '.sol' or '.vy' files +β”‚ └── smart_contract_example.sol # Sample of a smart contract +β”œβ”€β”€ tests/ # Project tests, ran using the 'ape test' command +β”‚ └── test_sample.py # Sample of a test to run against your sample contract +β”œβ”€β”€ scripts/ # Project scripts, such as deploy scripts, ran using the 'ape run <`name>' command +β”‚ └── deploy.py # Sample script to automate a deployment of an ape project +└── ape-config.yaml # The ape project configuration file +``` + +:::tip[Tip] + +You can configure the ape project using the `ape-config.yaml` file. See the [configuration guide](https://docs.apeworx.io/ape/stable/userguides/config.html) for a more detailed explanation of the settings to adjust. + +::: + +## Create an Account + +We will create an account and send funds to it before we can deploy a smart contract or interact with previously deployed contracts from the Ape project. Run the following command to generate an account. + +```bash +ape accounts generate +``` + +> Use `dev` to replace ALIAS. + +You will be prompted to add random input to enhance the security and add a password to encrypt the account. + +```bash +ape accounts generate dev +Enhance the security of your account by adding additional random input: +Show mnemonic? [Y/n]: n +Create Passphrase to encrypt account: +Repeat for confirmation: +SUCCESS: A new account '0x260C915483943bf65596c298D2b46b8D67fF2FE5' with HDPath m/44'/60'/0'/0/0 has been added with the id 'dev' +``` + +:::tip[Tip] +If you do not want to see your mnemonic, select `n`. Alternatively, use the `--hide-mnemonic` option to skip the prompt. +::: + +:::warning[Warning] + +Don't forget to add funds to the account generated. To get tRBTC, use the [Rootstock Faucet](https://faucet.rootstock.io/). + +To import an existing account check [Importing Existing Accounts](https://docs.apeworx.io/ape/stable/userguides/accounts.html#importing-existing-accounts) documentation. + +::: + +## Write your first contract + +As an example, You can use the following Box contract to store and retrieve a value. + +Fist create a file named `Box.sol`inside the contracts directory: + +```bash +touch contracts/Box.sol +``` + +Open the file and add the following contract to it: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.1; + +contract Box { + uint256 private value; + + event ValueChanged(uint256 newValue); + + function store(uint256 newValue) public { + value = newValue; + emit ValueChanged(newValue); + } + + function retrieve() public view returns (uint256) { + return value; + } +} +``` + +## Compile the contract + +Before compiling the Solidity, ensure to install the Solidity compiler plugin. Running the following command will install the latest version of the plugin: + +```bash +ape plugins install solidity +``` + +To use a specific version of Solidity or a specific EVM version, modify the `ape-config.yaml` file as follows: + +```text +solidity: + version: INSERT_VERSION + evm_version: INSERT_VERSION +``` + +> For more information about the Solidity plugin, check [ape-solidity](https://github.com/ApeWorX/ape-solidity/blob/main/README.md) + +After installation, compile the contract using the following command: + +```bash +ape compile +``` + +Result: + +```bash +ape compile +INFO: Compiling using Solidity compiler '0.8.25+commit.b61c2a91'. +Input: + contracts/Box.sol +SUCCESS: 'local project' compiled. +``` + +After compilation, you can find the bytecode and ABI for your contracts in the `.build` directory. + +## Deploy contract on Rootstock + +To deploy the box contract on Rootstock mainnet or testnet, install [ape-rootstock](https://pypi.org/project/ape-rootstock/) plugin. This will allow for connection to Rootstock networks. + +```bash +ape plugins install ape-rootstock +``` + +Result: + +```text +Install the 'rootstock' plugin? [y/N]: y +INFO: Installing 'rootstock' plugin ... +SUCCESS: Plugin 'rootstock' has been installed. +``` + +Then, create a deployment script named `deploy.py` inside of the `scripts`directory + +```bash +touch scripts/deploy.py +``` + +Next, we'll need to write the deployment script. We will need to load the account needed to be used to deploy the contract and access it by its name using the project manager. + +Add the following into `deploy.py` file: + +```python +from ape import project, accounts + + +def main(): + # Load your account by its name + account = accounts.load("dev") + # Deploy the contract using your account + return account.deploy(project.Box) +``` + +Now you're ready to deploy the Box contract! Follow the next steps: + +1. Run the deployment script using the ape run deploy command + ```bash + ape run deploy --network rootstock:testnet + ``` + + > For mainnet deployment, use `--network rootstock:mainnet` + +2. Review the transaction details and enter y to sign the transaction +3. Enter the passphrase for your account +4. Enter y to exit your account unlocked or n to lock it + +After following the prompts and submitting the transaction, the transaction hash, total fees paid, and contract address will be displayed in the terminal. + +```python +ape run deploy --network rootstock:testnet +INFO: Connecting to a 'rskj' node. +StaticFeeTransaction: + chainId: 31 + from: 0x260C915483943bf65596c298D2b46b8D67fF2FE5 + gas: 101643 + nonce: 0 + value: 0 + data: 0x307836...303333 + gasPrice: 65164000 + +Sign: [y/N]: y +Enter passphrase to unlock 'dev' []: +Leave 'dev' unlocked? [y/N]: y +INFO: Submitted 0xf837d08ac7bab308b9ae3276e15b1dfd69a0888725a779363cfe2939c6b5be5f +Confirmations (1/1): 100%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 1/1 [00:30<00:00, 30.63s/it] +INFO: Confirmed 0xf837d08ac7bab308b9ae3276e15b1dfd69a0888725a779363cfe2939c6b5be5f (total fees paid = 6623464452000) +INFO: Confirmed 0xf837d08ac7bab308b9ae3276e15b1dfd69a0888725a779363cfe2939c6b5be5f (total fees paid = 6623464452000) +SUCCESS: Contract 'Box' deployed to: 0x3F64cFe812c342069e510CBF581A30BEfd5897F8 +``` + +**Congratulations! Your contract is now active. Please ensure you save the address to facilitate interaction with it in the following section.** + +:::tip[Tip] + +If you get the error: `ERROR: (VirtualMachineError) (-32010) the sender account doesn't exist` + +Ensure to have [tRBTC](https://faucet.rootstock.io/) in the address generated in [create an account](#create-an-account). +::: + +### Using The Ape Console + +To interact with the newly deployed contract, launch the Ape console by running: + +```bash +ape console --network rootstock:testnet +``` +Next, we have to create a contract instance using the contract's address: +```bash +box = Contract("INSERT_CONTRACT_ADDRESS") +``` + +**Enter the values below in the shell:** + +```python +ape console --network rootstock:testnet +INFO: Connecting to a 'rskj' node. + +In [1]: dev = accounts.load("dev") +In [2]: box = Contract("0xA183c4DB0Fe974244F506069B09953119667505c") +``` + +Now, you can interact with the contract instance! For example, set the variable to be stored in the Box contract using the following commands: + +- Call the store method by passing in a value to store, and the account to send the transaction: + +```text +box.store(2, sender=dev) +``` +- Press enter, and review the transaction details and type "y" to sign the transaction. +- If your account is currently locked, enter the passphrase to unlock it. Otherwise, Ape will use the cached key from your account. +- If you unlocked your account in the previous step, you'll be asked whether you'd like to keep it unlocked. Enter "y" to keep it unlocked or "n" to lock it. + +After completing these steps and submitting the transaction, the transaction hash and total fees will be shown in the terminal. + +``` +In [3]: box.store(2, sender=dev) +StaticFeeTransaction: + chainId: 31 + to: 0x3F64cFe812c342069e510CBF581A30BEfd5897F8 + from: 0x260C915483943bf65596c298D2b46b8D67fF2FE5 + gas: 42490 + nonce: 1 + value: 0 + data: 0x307836...303032 + gasPrice: 65164000 + +Sign: [y/N]: y +Enter passphrase to unlock 'dev' []: +Leave 'dev' unlocked? [y/N]: y +INFO: Submitted 0x9224a7958c89272c3d41147b2e96df33d205ad5632c07fe40016be012721cf00 +Confirmations (1/1): 100%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 1/1 [00:15<00:00, 15.38s/it] +INFO: Confirmed 0x9224a7958c89272c3d41147b2e96df33d205ad5632c07fe40016be012721cf00 (total fees paid = 2768818360000) +INFO: Confirmed 0x9224a7958c89272c3d41147b2e96df33d205ad5632c07fe40016be012721cf00 (total fees paid = 2768818360000) +Out[3]: +``` + +You can retrive the stored value by calling the retrieve method: + +```bash +box.retrieve() +``` + +Enter the values in the shell: + +```bash +In [5]: box.retrieve() +Out[5]: 2 +``` +**Well done! We have successfully deployed and interacted with a contract on the Rootstock network using Ape!** + +## Resources +- See the [Ape Documenetation](https://docs.apeworx.io/). \ No newline at end of file diff --git a/docs/02-developers/04-quickstart/foundry.md b/docs/02-developers/04-quickstart/foundry.md new file mode 100644 index 00000000..63aa30ee --- /dev/null +++ b/docs/02-developers/04-quickstart/foundry.md @@ -0,0 +1,174 @@ +--- +sidebar_label: Rootstock Foundry Starter kit +sidebar_position: 500 +title: Rootstock Foundry Starter kit +description: 'Whether you are a seasoned developer or just starting your journey into smart contract development, the foundry starter kit provides a solid foundation for building decentralized applications (dApps) on the Rootstock network.' +tags: [rsk, rootstock, tutorials, developers, foundry, quick starts, dApps, smart contracts] +--- + +Whether you’re a seasoned developer or just starting your journey into smart contract development, the foundry starter kit provides a solid foundation for building decentralized applications (dApps) on the Rootstock network. + +Rootstock is fully EVM (Ethereum Virtual Machine) compatible. It brings the power of smart contracts to Bitcoin, allowing developers to leverage Bitcoin’s security while benefiting from Ethereum’s ecosystem. + +In this tutorial, you'll learn how to set up your Foundry development environment, connect to a Rootstock network, write and test smart contracts, deploy them to the Rootstock blockchain, and interact with them. We'll guide you through every step, from installation to minting your first token. + +## Prerequisites + +Before starting the dApp, make sure to have the following prerequisites: + +1. **Familiarity with Smart Contracts:** + - If you’re new to smart contracts, consider learning the basics. Understanding how smart contracts work will enhance your experience with Rootstock development. + +2. **Foundry installation using [Foundryup](https://book.getfoundry.sh/getting-started/installation#using-foundryup):** +- To install, visit the official [Foundry documentation](https://book.getfoundry.sh/getting-started/installation#using-foundryup), for more information. +- Foundryup is the official installer for the Foundry toolchain. You can learn more about it in the [Foundryup README](https://github.com/foundry-rs/foundry/blob/master/foundryup/README.md). +- If you encounter any issues during installation, refer to the Foundryup [FAQ](https://book.getfoundry.sh/faq.html) for assistance. +- Precompiled binaries can be downloaded from the Foundry [GitHub releases page](https://github.com/foundry-rs/foundry/releases). For easier management, we recommend using Foundryup. + +To install Foundry in your system, run the following command: +```bash +curl -L https://foundry.paradigm.xyz | bash +``` +This will install Foundryup. Follow the on-screen instructions, and the `foundryup` command will be available via the CLI. + +Running `foundryup` automatically installs the latest (nightly) versions of the precompiled binaries: `forge`, `cast`, `anvil`, and `chisel`. For additional options, such as installing a specific version or commit, run `foundryup --help`. + +:::info[Using Windows] +If you’re using Windows, you’ll need to install and use [Git BASH](https://gitforwindows.org/) or [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) as your terminal, since Foundryup currently doesn’t support Powershell or Command Prompt (Cmd). +::: + +3. **Basic Knowledge of Foundry:** +- Familiarity with Foundry's core concepts and functionalities is recommended. If you're new to Foundry, refer to the [Rootstock Foundry Guide](/developers/smart-contracts/foundry/). + +:::tip[Rootstock Blockchain Developer Course] + +Learn how to write, test, secure, deploy and verify smart contracts on the Rootstock blockchain network. Enroll for the [Rootstock Blockchain Developer Course](/resources/courses/). +::: + +## Setting Up the Sample dApp + +### Clone the Repository + +Open your terminal or command prompt and run the following command to clone the repository from GitHub: + +```bash +git clone https://github.com/rsksmart/rootstock-foundry-starterkit.git +``` + +### Install Dependencies + +Navigate to the cloned repository folder: + +```bash +cd rootstock-foundry-starterkit +``` + +Install all required dependencies using forge: + +```bash +forge install openzeppelin-contracts-05=OpenZeppelin/openzeppelin-contracts@v2.5.0 openzeppelin-contracts-06=OpenZeppelin/openzeppelin-contracts@v3.4.0 openzeppelin-contracts-08=OpenZeppelin/openzeppelin-contracts@v4.8.3 --no-commit +``` + +### Add Rootstock Testnet and Mainnet RPC URLs + +This section will walk you through adding Rootstock Testnet and Mainnet RPC URLs to your development environment. These URLs are essential for connecting your application to the Rootstock network and interacting with smart contracts. + +There are two ways to obtain RPC URLs: + +#### Using Public RPC URLs + +- Visit the [MetaMask Integration on the Rootstock DevPortal](/dev-tools/wallets/metamask/). This guide provides instructions on setting up MetaMask for Rootstock. While following these steps, pay close attention to the sections on adding custom networks. You'll find the RPC URLs for Rootstock Testnet and Mainnet listed. + +#### Using RPC API +- Create an account on the [Rootstock RPC API](https://rpc.rootstock.io/). Once logged in, navigate to your dashboard and copy the API Key. + + +### Adding environment variables to your project + +After obtaining the RPC URLs, create a file named `.env` in your project's root directory `/.env` at the same level of `.env.example` file (important: this file should not be committed to version control). Add the next environment variable to the `.env` file: +``` +PRIVATE_KEY: Your private key (e.g., from your Metamask account details). +``` +:::tip[Tip] +Ensure the private key copied starts with `0x...` +::: + + +## Running tests on an ERC20 Token Contract +This section runs tests on an ERC20 token contract (fungible token), this is done according to the script located at `test/Erc20Token.t.sol`. It does test deployment, minting, and transfer of tokens. + +For this, run the next forge command: + +```bash +forge test +``` + +It should return an output similar to the following: + +```bash +Compiler run successful! + +Ran 2 tests for test/Erc20Token.t.sol:ERC20TokenTest +[PASS] testInitialSupply() (gas: 9849) +[PASS] testTransfer() (gas: 43809) +Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 8.73ms (1.51ms CPU time) + +Ran 1 test suite in 143.90ms (8.73ms CPU time): 2 tests passed, 0 failed, 0 skipped (2 total tests) +``` +**_NOTE: If you need additional tests, or want to go deep on this step, visit the [Foundry Tests Documentation](https://book.getfoundry.sh/forge/tests)._** + +## Deploying an ERC20 Token Contract +This section deploys an ERC20 token contract (fungible token) on the Rootstock network. This contract is located at `src/Erc20Token.sol` file, it uses the script located at `script/Deploy.s.sol` for this operation. + +Run the following command, replacing `https://public-node.testnet.rsk.co` with either `rskTestnet` or `rskMainnet` rpc url if you have the testnet and mainnet environments configured for your desired deployment environment, for this guide, we will use the public node url: + +```bash +forge script script/Deploy.s.sol --rpc-url https://public-node.testnet.rsk.co --broadcast --legacy --evm-version london +``` +:::info[Info] + +- [EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md) is not supported or not activated on the Rootstock RPC url. +- To avoid Foundry's compatibility issues, we are using the `--evm-version london` flag. +- The `--legacy` flag is passed to use legacy transactions instead of `EIP-1559`. +- You can remove the `--broadcast` flag if you want to simulate the transaction without broadcasting it. +::: + +> If you encounter an error such as `Transaction dropped from the mempool: ` or `transaction not completed`, check the `tx-id` in the explorer. The transaction may have been successful but the error is still within the logs. See the [mainnet](https://explorer.rootstock.io/) and [testnet](https://explorer.testnet.rootstock.io/) explorers for more info. + +> Also you can see the transaction registry locally, by checking the folder `broadcast/Deploy.s.sol/` and opening the file called `run-latest.json`. See the field called `contractAddress` which contains the new address deployed for the ERC20 smart contract. + +The result should look like this: +```bash +Sending transactions [0 - 0]. +⠁ [00:00:00] [###############################################################################################################################################] 1/1 txes (0.0s)## +Waiting for receipts. +β ‰ [00:00:25] [###########################################################################################################################################] 1/1 receipts (0.0s) +##### 31 +βœ… [Success]Hash: 0x48ea2b06b39cd436a2d7564e20ea5bb598ddc2769e6b18c855170f0e9e4d5687 +Contract Address: 0x499e802a6825d30482582d9b9dd669ba82ba8ba4 +Block: 5071408 +Gas Used: 106719 + +========================== + +ONCHAIN EXECUTION COMPLETE & SUCCESSFUL. +Total Paid: 0. ETH (106719 gas * avg 0 gwei) +``` + +## Interacting with the Contract - Minting a Token +If the contract is already deployed, then you can interact with it using `cast` this command allows you to interact with the contract, in this case, read the balance of an account. + +### Reading the Balance of an Account +In your terminal, run the following command, replacing the placeholders with actual values: + +```bash +cast call "balanceOf(address)(uint256)" --rpc-url +``` +The result should look like this: +```bash +1000000000000000000000 [1e21] +``` + +## Final Comments + +You can explore the folders and files within the starter kit and customize the kit to suit your project’s needs. You can also learn how to import `.env` variables for deploying smart contracts, test smart contracts with solidity, etc. \ No newline at end of file diff --git a/docs/02-developers/04-quickstart/hardhat.md b/docs/02-developers/04-quickstart/hardhat.md index 1cf88b74..22606ccd 100644 --- a/docs/02-developers/04-quickstart/hardhat.md +++ b/docs/02-developers/04-quickstart/hardhat.md @@ -1,14 +1,14 @@ --- -sidebar_label: Using Hardhat +sidebar_label: Rootstock Hardhat Starter Kit sidebar_position: 400 -title: Rootstock Hardhat Starter dApp +title: Rootstock Hardhat Starter Kit description: 'Whether you are a seasoned developer or just starting your journey into smart contract development, the hardhat starter kit provides a solid foundation for building decentralized applications (dApps) on the Rootstock network.' tags: [rsk, rootstock, tutorials, developers, hardhat, quick starts, dApps, smart contracts] --- Whether you’re a seasoned developer or just starting your journey into smart contract development, the hardhat starter kit provides a solid foundation for building decentralized applications (dApps) on the Rootstock network. -Rootstock is fully compatible with Ethereum. It brings the power of smart contracts to Bitcoin, allowing developers to leverage Bitcoin’s security while benefiting from Ethereum’s ecosystem. +Rootstock is fully EVM (Ethereum Virtual Machine) compatible. It brings the power of smart contracts to Bitcoin, allowing developers to leverage Bitcoin’s security while benefiting from Ethereum’s ecosystem. ## Prerequisites diff --git a/docs/02-developers/04-quickstart/index.md b/docs/02-developers/04-quickstart/index.md index 65ce84b8..ef603a89 100644 --- a/docs/02-developers/04-quickstart/index.md +++ b/docs/02-developers/04-quickstart/index.md @@ -11,13 +11,15 @@ values={[ {label: 'Beginner', value: 'beginner'}, {label: 'Advanced', value: 'advanced'}, {label: 'Hardhat', value: 'hardhat'}, +{label: 'Remix', value: 'remix'}, {label: 'Wagmi', value: 'wagmi'}, -{label: 'Smart Contracts', value: 'sc'}, {label: 'On-chain data', value: 'data'}, +{label: 'RPC API', value: 'rpc'}, +{label: 'Ape', value: 'ape'}, {label: 'Port to Rootstock', value: 'port-dapps'} ]}> + + + + + diff --git a/docs/02-developers/04-quickstart/remix.md b/docs/02-developers/04-quickstart/remix.md new file mode 100644 index 00000000..fa930fe0 --- /dev/null +++ b/docs/02-developers/04-quickstart/remix.md @@ -0,0 +1,194 @@ +--- +sidebar_label: Deploy, Interact and Verify Smart Contracts using Remix and Rootstock Explorer +sidebar_position: 600 +title: Deploy, Interact and Verify Smart Contracts using Remix and Rootstock Explorer +description: 'In this guide, we will use the Remix IDE to write, compile, deploy, interact and verify a smart contract on the Rootstock Explorer.' +tags: [rsk, rootstock, developers, quick starts, rootstock explorer, dApps, remix] +--- + +The process of writing, compiling and deploying Solidity contracts can be tedious or a bit obscure at the beginning, if you try to do it programmatically or using terminals. Get started writing, compiling, and deploying Solidity contracts quickly with Remix. Remix offers an [online IDE](https://remix.ethereum.org/) that allows for writing, compiling, interacting and deploying smart contracts to any network. + +In this guide, we will use the Remix online IDE to write, compile, deploy, interact and verify a smart contract on the [Rootstock Testnet Explorer](https://explorer.testnet.rootstock.io/). + +## Prerequisites +1. Remix online IDE, go to the [Remix online IDE](https://remix.ethereum.org/) +2. MetaMask Wallet. See how to [Configure MetaMask Wallet for Rootstock](https://dev.rootstock.io/dev-tools/wallets/metamask/) +3. Rootstock Testnet Explorer + +## Setting up Remix +In the left menu, click on **Deploy and run transactions**, and under **Environment** select **Injected provider - MetaMask**, this will trigger the MetaMask Wallet, confirm connection, and ensure you are logged in to Metamask and connected to the Testnet or Mainnet Rootstock network. + +Once selected, under Account, select the account you want to deploy the contract with. + +![Remix - Injected Provider MetaMask](/img/developers/quickstart/1-remix.png) + +## Writing a Smart Contract + +In the left menu, click on **File explorer**, and under **Workspaces**, you can create separate workspaces with different templates, like `ERC20`, `ERC1155`, an empty one, or use the default one that comes with a simple set of example contracts. + +![Remix - Workspaces](/img/developers/quickstart/2-remix.png) + +Inside the **contracts** folder, put all the contracts you want that satisfy the dependencies of the main contract you want to deploy, if any. + +In this guide, we’ll use one of the example contracts that Remix provides in the default workspace, `1_Storage.sol`. + +> ⚠️ Note: for the sake of the verification process some steps after, ensure the `.sol` filename of the main contract matches exactly its declared name. So we’ll rename it to `Storage.sol`. + +![Remix - Solidity file](/img/developers/quickstart/3-remix.png) + +## Compiling the Contract + +In the left menu, click on **Solidity compiler** and set the compilation parameters: + +* Compiler: ensure the commit version is accurate for what you defined in the pragma of the contract. +* Under Advanced Configurations you can specify the EVM version and the optimization runs. You can also disregard this form and use a custom JSON with the configuration options. + +:::tip[Tip] + +Current [supported solidity version](https://dev.rootstock.io/developers/requirements/) for Rootstock is `0.8.19`. + +::: + +![Remix - Solidity Compiler](/img/developers/quickstart/4-remix.png) + +Return to File explorer and right click on the contract you want to deploy, and click on **Compile Storage.sol**. Note that you can also compile the contract by clicking the Compiler Options button in the left menu, and clicking `Compile (currentFileOpenInEditor).sol` + +![Compile Solidity Contract](/img/developers/quickstart/5-remix.png) + +If successful, you will see a green checkmark (highlighted as selected), this is necessary so that in the next step the compiled contracts can be detected for deployment. + +![Compile Solidity Contract Button](/img/developers/quickstart/5a-remix.png) + +## Deploying the Contract + +In the left menu, click on **Deploy and run transactions**. Under Contract, ensure the contract is selected. Click on Deploy and MetaMask will then prompt you to sign the deploy transaction. + +> Ensure the Environment and Account are correctly set as explained in the previous step. If the contract had any constructor arguments, those inputs would appear next to the Deploy button for you to fill them. + +![Deploy and Run Transactions](/img/developers/quickstart/6-remix.png) + +Confirm the transaction in MetaMask: + +![Confirm transaction deployment in MetaMask](/img/developers/quickstart/7-remix.png) + +If deployment is successful, it will appear under **Deployed/Unpinned Contracts** section + +![View deployed/unpinned contract](/img/developers/quickstart/8-remix.png) + +## Interacting with the Contract + +As shown in the previous step after deploying the contract, you can expand the desired contract and interact with it, calling the available functions by entering the required arguments, if any. Once entered the arguments, click on the method name and, in the event that it’s a writing method, Metamask will prompt you to sign the transaction. If the method is read only, it will show the return value under the method name. + +## Verifying the Contract on Rootstock Explorer + +To verify the deployed contract on the explorer, go back to Remix file explorer and go to `contracts -> artifacts -> build-info`. In this folder there will be a json file containing the information of the compilation process. You’ll need this in order to verify the contract on the [Rootstock Testnet Explorer](https://explorer.testnet.rootstock.io/). Copy the value of the input attribute and save it as a json file in your computer. + +![deployed contract artifact](/img/developers/quickstart/9-remix.png) + +Copy the contract's address from the Remix deployment output, you can find the contract address under the **Deployed/Unpinned** Contracts. + +![Copy contract address](/img/developers/quickstart/10-remix.png) + +Visit the [Rootstock Testnet Explorer](https://explorer.testnet.rootstock.io/) and paste the Contract Address in the search field. + +![Paste Contract Address - Rootstock Testnet Explorer](/img/developers/quickstart/11-remix.png) + +Click on the Code tab and click the button to **Verify Contract**. + +![View Contract Address - Rootstock Testnet Explorer](/img/developers/quickstart/12-remix.png) + +![View Verify Explorer Details](/img/developers/quickstart/18-remix.png) + +Select **Standard JSON Input** as the verification method and fill the form: + +1. Standard JSON input: In the standard JSON input, upload the file you created from the build info of the contract. +2. Contract name: The name of the contract which you declared it with. Remember that it’s important the file of the contract has the same matching name as the standard-json-input.json. Now, click on add file to upload. +3. Compiler: This is the compiler version the contract has been compiled with. For example +Constructor arguments: The constructor arguments of the contract, if any. If you don’t know the arguments at first, continue with the process and the explorer will attempt to identify the constructor arguments from the bytecode and suggest them, if possible. +4. ABI encoded arguments: if the arguments provided are ABI encoded, check this option. + +Copy only the input value (curly braces included), see [verifying contract on the explorer](#verifying-the-contract-on-rootstock-explorer) and paste the code into a file named `standard-json-input.json`, then click on add file: + +![Input Block - Rootstock Testnet Explorer](/img/developers/quickstart/13-remix.png) + +Here’s the example code of an input value: + +```solidity +{ + "language": "Solidity", + "sources": { + "contracts/Storage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.2 <0.9.0;\n\n/**\n * @title Storage\n * @dev Store & retrieve value in a variable\n * @custom:dev-run-script ./scripts/deploy_with_ethers.ts\n */\ncontract Storage {\n\n uint256 number;\n\n /**\n * @dev Store value in variable\n * @param num value to store\n */\n function store(uint256 num) public {\n number = num;\n }\n\n /**\n * @dev Return value \n * @return value of 'number'\n */\n function retrieve() public view returns (uint256){\n return number;\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "": [ + "ast" + ], + "*": [ + "abi", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.legacyAssembly", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "evm.gasEstimates", + "evm.assembly" + ] + } + }, + "remappings": [], + "evmVersion": "paris" + } +} +``` + +* Enter the Contract name, this can be found in the Contract declaration. + +```solidity +contract Storage { + // code +} +``` +* Select the compiler version, note to use the same compiler version used when compiling the contracts on Remix. + +At the bottom, below the form, click on the **verify** button and wait for the verification attempt to finish. If successfull, you’ll see a success screen. + +![Verify Contract - Rootstock Testnet Explorer](/img/developers/quickstart/14-remix.png) + +![Verify Contract Success - Rootstock Testnet Explorer](/img/developers/quickstart/15-remix.png) + +You can view all the solidity code of the contract and its dependencies. + +![View Verified Contract - Rootstock Testnet Explorer](/img/developers/quickstart/16-remix.png) + +Congratulations, we have successfully compiled, deployed, interacted and verified a smart contract using Remix and the Rootstock Explorer. + +## Troubleshooting + + + + Error: Missing contract verifier data + + FIX: Ensure to refresh your tab and verify the contract again. + ![Missing Contract Verifier Data - Rootstock Testnet Explorer](/img/developers/quickstart/17-remix.png) + + + + +## Resources +* [Getting Started with Wagmi](/developers/quickstart/wagmi/) +* [Getting Started with Hardhat](/developers/quickstart/hardhat/) +* [Verify a Smart Contract using the Hardhat Verification Plugin](/developers/smart-contracts/verify-smart-contracts/) + + + diff --git a/docs/02-developers/04-quickstart/rootstock-etherspot.md b/docs/02-developers/04-quickstart/rootstock-etherspot.md index eb7557a3..9282fe8c 100644 --- a/docs/02-developers/04-quickstart/rootstock-etherspot.md +++ b/docs/02-developers/04-quickstart/rootstock-etherspot.md @@ -1,6 +1,6 @@ --- -sidebar_label: Account Abstraction -sidebar_position: 500 +sidebar_label: Account Abstraction using Etherspot Prime SDK +sidebar_position: 600 title: Account Abstraction using Etherspot Prime SDK description: 'In this guide, you will learn how to use the Etherspot Prime SDK to deploy an Account Abstraction dApp on the Rootstock network. By following these steps, you will empower your users to interact with your dApp without managing private keys directly.' tags: [rsk, rootstock, developers, quick starts, etherspot, dApps, account abstraction] diff --git a/docs/02-developers/04-quickstart/wagmi.md b/docs/02-developers/04-quickstart/wagmi.md index d574ace2..7254f70c 100644 --- a/docs/02-developers/04-quickstart/wagmi.md +++ b/docs/02-developers/04-quickstart/wagmi.md @@ -1,7 +1,7 @@ --- -sidebar_label: Using Wagmi and React Hooks +sidebar_label: Rootstock Wagmi Starter Kit sidebar_position: 300 -title: Rootstock Wagmi Starter dApp +title: Rootstock Wagmi Starter Kit description: 'The Rootstock Wagmi Starter Kit provides a solid foundation for developing decentralized applications (dApps) on the Rootstock blockchain. It streamlines development by leveraging the React, Wagmi, and Shadcn libraries.' tags: [rsk, rootstock, developers, wagmi, quickstart, dApps, Smart Contracts] --- diff --git a/docs/02-developers/04-quickstart/web3-python.md b/docs/02-developers/04-quickstart/web3-python.md index fca4f7d0..a2a974f7 100644 --- a/docs/02-developers/04-quickstart/web3-python.md +++ b/docs/02-developers/04-quickstart/web3-python.md @@ -1,5 +1,5 @@ --- -sidebar_label: Using Web3.py +sidebar_label: Deploy and Interact with a Smart Contract using Web3.py sidebar_position: 200 title: Deploy and Interact with a Smart Contract using Web3.py description: 'Deploy and Interact with a Smart Contract Using Web3.py.' diff --git a/docs/02-developers/05-smart-contracts/02-hardhat/configure-hardhat-rootstock.md b/docs/02-developers/05-smart-contracts/02-hardhat/configure-hardhat-rootstock.md index 92c6c18f..12ef9d4c 100644 --- a/docs/02-developers/05-smart-contracts/02-hardhat/configure-hardhat-rootstock.md +++ b/docs/02-developers/05-smart-contracts/02-hardhat/configure-hardhat-rootstock.md @@ -66,7 +66,7 @@ To configure your `rskMainnet` and `rskTestnet` private keys, you'll need to upd }; ``` -> See how to [Get an API Key from the RPC API](/developers/rpc-api/setup/) +> See how to [Get an API Key from the RPC API](/developers/rpc-api/rootstock/setup/) > Replace `"your_mainnet_private_key"` and `"your_testnet_private_key"` with your private keys. For information on how to retrieve your private keys, see [How to export an account's private key](https://support.metamask.io/hc/en-us/articles/360015289632-How-to-export-an-account-s-private-key). diff --git a/docs/02-developers/05-smart-contracts/02-hardhat/deploy-smart-contracts.md b/docs/02-developers/05-smart-contracts/02-hardhat/deploy-smart-contracts.md index 7f542e51..b66d2423 100644 --- a/docs/02-developers/05-smart-contracts/02-hardhat/deploy-smart-contracts.md +++ b/docs/02-developers/05-smart-contracts/02-hardhat/deploy-smart-contracts.md @@ -3,7 +3,8 @@ sidebar_label: Deploy Smart Contracts sidebar_position: 105 title: Deploy Smart Contracts description: "Learn how to deploy your Rootstock smart contract on your local environment and the Rootstock network." -tags: [guides, developers, smart contracts, rsk, rootstock, hardhat, dApps, ethers] +tags: + [guides, developers, smart contracts, rsk, rootstock, hardhat, dApps, ethers] --- In this section, we'll deploy your token contract to your local environment and also deploy and interact with the contract on the Rootstock network. @@ -19,25 +20,25 @@ To configure your deployment file: ``` - In the scripts directory, open the `deploy.js` deployment file: - + To deploy `myToken` contract, copy the deployment script below and paste it in your deployment file or see the [`deploy.js` file](https://raw.githubusercontent.com/rsksmart/rootstock-quick-start-guide/feat/complete/scripts/deploy.js) on GitHub. - + ```js - async function main() { - const [deployer] = await ethers.getSigners(); +async function main() { + const [deployer] = await ethers.getSigners(); - console.log("Deploying contracts with the account:", deployer.address); + console.log("Deploying contracts with the account:", deployer.address); - const MyToken = await ethers.getContractFactory("MyToken"); - const myToken = await MyToken.deploy(1000); + const MyToken = await ethers.getContractFactory("MyToken"); + const myToken = await MyToken.deploy(1000); - console.log("Token address:", myToken.address); - } + console.log("Token address:", myToken.address); +} - main().catch((error) => { - console.error(error); - process.exitCode = 1; - }); +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); ``` ## Step 2: Run the Hardhat Network Locally @@ -47,26 +48,28 @@ To deploy `myToken` contract, copy the deployment script below and paste it in y To run the Hardhat network locally: - Start the Hardhat network - - Hardhat comes with a built-in Ethereum network for development. Run the following command in your project's root directory to start it. - ```shell - npx hardhat node - ``` - This command will start a local blockchain network and display a list of available accounts and private keys: - ![Rootstock Node Running](/img/guides/quickstart/hardhat/run-node.png) + - Hardhat comes with a built-in Ethereum network for development. Run the following command in your project's root directory to start it. + ```shell + npx hardhat node + ``` + This command will start a local blockchain network and display a list of available accounts and private keys: + ![Rootstock Node Running](/img/guides/quickstart/hardhat/run-node.png) - Deploy your contract to the local network - - Deploy your contract to the local Hardhat network, in another terminal or command prompt, run the command below in the root directory: - ```shell - npx hardhat run --network hardhat scripts/deploy.js - ``` - This should give a result similar to the following: - - ```shell - npx hardhat run --network hardhat scripts/deploy.js + - Deploy your contract to the local Hardhat network, in another terminal or command prompt, run the command below in the root directory: + + ```shell + npx hardhat run --network hardhat scripts/deploy.js + ``` + + This should give a result similar to the following: + + ```shell + npx hardhat run --network hardhat scripts/deploy.js - Deploying contracts with the account: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 - Token address: 0x5FbDB2315678afecb367f032d93F642f64180aa3 - ``` + Deploying contracts with the account: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + Token address: 0x5FbDB2315678afecb367f032d93F642f64180aa3 + ``` ## Step 3: Deploy Your Contract on Rootstock Network @@ -83,7 +86,7 @@ To deploy to the Rootstock Testnet, run: This should return the following: ```shell -% npx hardhat run --network rskTestnet scripts/deploy.js +% npx hardhat run --network rskTestnet scripts/deploy.js Deploying contracts with the account: 0xA210D04d707f6beBF914Cb1a57199Aebe7B40380 Token address: 0xc6EcBe0F6643825FD1AAfc03BEC999014759a279 ``` @@ -94,46 +97,70 @@ Token address: 0xc6EcBe0F6643825FD1AAfc03BEC999014759a279 npx hardhat run --network rskMainnet scripts/deploy.js ``` -### Configure MetaMask +### Configure MetaMask :::note[Install Metamask] -If you haven't already, you can use the [metamask-landing.rifos.org](https://metamask-landing.rifos.org/) tool to download/install Metamask, and add Rootstock custom network or follow the steps in [Configure Network and Token](/developers/blockchain-essentials/browser). +If you haven't already, you can use the [metamask-landing.rifos.org](https://metamask-landing.rifos.org/) tool to download/install Metamask, and add Rootstock custom network or follow the steps in [Configure Network and Token](/developers/blockchain-essentials/browser). ::: -## Step 4: Connect Remix to Rootstock Testnet (Optional) +## Step 4: Interact with your deployed contract -1. Open Remix IDE +To interact with your deployed contract, you can create an interaction script using JavaScript/TypeScript and the [Ethers.js](https://docs.ethers.org/v5/) library. - - Go to [Remix IDE](https://remix.ethereum.org/) in your browser. +- Create a `interact.js` file in the `scripts` directory: -2. Connect MetaMask to Remix: - - - In Remix, go to the **Deploy & run transactions** plugin. - - In the **Environment** dropdown, select **Injected Provider**. - - This will connect to MetaMask. Make sure MetaMask is on the `RSK Testnet` network that you configured earlier. - -### Interact with the Deployed Contract on Remix - -To interact with your deployed contract on Rootstock network: - -- Load Your Deployed Contract - - Import the `myToken.sol` file into remix and compile. +``` + touch scripts/interact.js +``` -![Import Solidity File and Compile](/img/guides/quickstart/hardhat/compile-contract-remix.png) +- Paste the following code in the `interact.js` file: -- Once compiled, you should see the checkmark and solidiity file loaded into Remix. +```js +const hre = require("hardhat"); + +async function main() { + try { + // Get the ContractFactory of your MyToken contract + const MyToken = await hre.ethers.getContractFactory("MyToken"); + + // Connect to the deployed contract + const contractAddress = "0x543ba9FC0ade6f222BD8C7Bf50a0CD9923Faf569"; // Replace with your deployed contract address + const contract = await MyToken.attach(contractAddress); + + // Retrieve the balance of an account + const account = "0x28eb8D29e4713E211D1dDab19dF3de16086BB8fa"; + const balance = await contract.balanceOf(account); + + // Retrieve the symbol of the token + const symbol = await contract.symbol(); + + console.log( + `Balance of ${account} account: ${balance.toString()} ${symbol}` + ); + } catch (error) { + console.error(error); + process.exit(1); + } +} + +main(); +``` -![Successful Compile](/img/guides/quickstart/hardhat/successful-compile-remix.png) +- And run the interaction script. This is how you can do it on testnet: -- Choose `Deploy and Run Transactions` and in `Environment`, Choose "Injected Provider - Metamask". +``` + npx hardhat run scripts/interact.js --network rskTestnet +``` -This loads the Metamask wallet. +- And this is how you can do it on mainnet: -![Deploy and Run Transactions](/img/guides/quickstart/hardhat/deploy-and-run-tx-remix.png) +``` + npx hardhat run scripts/interact.js --network rskMainnet +``` -Now click on `Transactions recorded` interact with the Smart Contract! Call its functions, send transactions, and observe the results. Ensure you have enough tRBTC in your MetaMask wallet for transaction fees. +- The expected output by running the interaction script is: -- Monitor Transactions - - Use Remix and MetaMask to monitor transaction confirmations and results. - - You can also use a [Rootstock Testnet Explorer](https://explorer.testnet.rootstock.io/) to view transactions and contract interactions. \ No newline at end of file +``` + Balance of 0x28eb8D29e4713E211D1dDab19dF3de16086BB8fa account: 1000 MTK +``` diff --git a/docs/02-developers/05-smart-contracts/02-hardhat/index.md b/docs/02-developers/05-smart-contracts/02-hardhat/index.md index cf527117..4b1dc5de 100644 --- a/docs/02-developers/05-smart-contracts/02-hardhat/index.md +++ b/docs/02-developers/05-smart-contracts/02-hardhat/index.md @@ -22,7 +22,7 @@ tags: [guides, developers, smart contracts, rsk, rootstock, hardhat, dApps, ethe | Resource | Description | | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | [Prerequisites](/developers/requirements/) | Learn about the tools you need to have in place to follow along with this guide.| -| [Create a Hardhat Project](/developers/smart-contracts/hardhat/) | Learn how to set up your environment for development using Hardhat.| +| [Create a Hardhat Project](/developers/smart-contracts/hardhat/create-hardhat-project) | Learn how to set up your environment for development using Hardhat.| | [Configure Hardhat for Rootstock](/developers/smart-contracts/hardhat/configure-hardhat-rootstock/) | Learn how to configure your Hardhat project for development on Rootstock testnet and mainnet.| | [Write Smart Contracts](/developers/smart-contracts/hardhat/write-smart-contracts/) | Learn how to write a smart contracts.| | [Test Smart Contracts](/developers/smart-contracts/hardhat/test-smart-contracts/) | Learn how to test your smart contract to ensure it's working as expected. | diff --git a/docs/02-developers/05-smart-contracts/02-hardhat/interact-with-frontend.md b/docs/02-developers/05-smart-contracts/02-hardhat/interact-with-frontend.md index 3f16624d..210982e2 100644 --- a/docs/02-developers/05-smart-contracts/02-hardhat/interact-with-frontend.md +++ b/docs/02-developers/05-smart-contracts/02-hardhat/interact-with-frontend.md @@ -1,327 +1,440 @@ --- -sidebar_label: Interact with the Front-end +sidebar_label: Interact with the Front-end sidebar_position: 106 -title: Interact with the Front-end +title: Interact with the Front-end description: "Learn how to integrate your Rootstock smart contract with front-end applications." -tags: [guides, developers, smart contracts, rsk, rootstock, hardhat, dApps, ethers] +tags: + [guides, developers, smart contracts, rsk, rootstock, hardhat, dApps, wagmi] --- -Creating a user-friendly web interface for smart contracts on the Rootstock network can enhance user interaction. Here, we'll focus on using `ethers.js`, a popular Ethereum library, for connecting your smart contracts to a web front-end. +Creating a user-friendly web interface for smart contracts on the Rootstock network enhances user interaction. Here, we'll focus on using [Wagmi](https://wagmi.sh/) and [RainbowKit](https://www.rainbowkit.com/), some popular libraries for connecting your smart contracts to a web front-end. ## Project Setup -1. Create a new folder called `frontend` and navigate to the directory: - -```shell - mkdir frontend - cd frontend -``` -> Note: If you use the quick start repo on `master`, there's already a frontend folder. You can `cd` into the frontend directory. - -2. In the frontend directory, initialize a Node.js Project: - -```shell - npm init -y -``` - -3. Install Ethers.js: - -```shell - npm install --save ethers -``` - -## Create HTML File - -- Update HTML File - - In the frontend directory, open the `index.html` file: - - Copy the code snippet below and paste it in your html file: - ```html - - - - - - - Web3 App with Ethers.js - - - - - - - ``` -- Import Ethers - - To import the Ethers library to interact with the wallet to the network, copy the code snippet below and paste it in the `` section of your html file: - ```html - - ``` -- Create HTML elements inside the body - 1. Create a button to trigger the function for connecting the wallet. - 2. Create a button to trigger the function to get balance. - 3. Create a div element to show the answer for the address connected. - 4. Create a div element to show the answer for wallet balance. - ```html - -
-

Connect to Rootstock Network

- - -
-
-
- - ``` -- Import javascript file - - Finally, to import the javascript library that we will create in a further step, copy the code snippet below and paste it in the `` section of your html file:: - ```html - - ``` - -Your `index.html` file should now look like the [`index.html` file](https://raw.githubusercontent.com/rsksmart/rootstock-quick-start-guide/feat/complete/frontend/index.html) on GitHub. - -## Create JavaScript Functions - -- Create basic javascript function - 1. In the frontend directory, open the `app.js` file. - 2. Copy the `MyToken.json` artifact file generated when building the contracts in `/artifacts/contracts/MyToken.sol/MyToken.json`. - 3. Copy the `networks.json` file. [You can get the file from this link](https://github.com/jesus-iov/rootstock-quick-start-guide/blob/5cf8c1d2e50d967be9cfc653a045ca614c3c32aa/frontend/networks.json). - 4. Create the function to wait until the DOM is loaded, instance the HTML elements (buttons and divs), and declare some variables: - ```js - document.addEventListener('DOMContentLoaded', function () { - // Instantiating HTML elements - const connectButton = document.getElementById('connectButton'); - const getBalanceButton = document.getElementById('getBalanceButton'); - const walletAddressDiv = document.getElementById('walletAddress'); - const walletBalanceDiv = document.getElementById('walletBalance'); - // Instantiating variables - let provider, account, myTokenContract; - let contractABI = []; - let networks = {}; - const contractAddress = 'Replace with your contract\'s address'; // E.g. 0xa6fb392538BaC56e03a900BFDE22e76C05fb5122 - }); - ``` -- Add a function that fetches the ABI and stores it in a variable - ```js - async function fetchExternalFiles() { - // Place MyToken.json generated in artifacts after compiling the contracts - let response = await fetch('MyToken.json'); - const data = await response.json(); - contractABI = data.abi; - // Place networks.json to set the network automatically with the checkNetwork() function - // You can set it manually instead following this guide https://dev.rootstock.io/resources/tutorials/rootstock-metamask/ - response = await fetch('networks.json'); - networks = await response.json(); - } - ``` -- Add a function that checks the wallet is connected to the Rootstock network - ```js - async function checkNetwork() { - try { - // Make sure Metamask is installed - if (!window.ethereum){ - alert('Please install Metamask!'); - return; - } - // Switch network - await window.ethereum.request({ - method: 'wallet_switchEthereumChain', - params: [{ chainId: networks.rskTestnet.chainId }], - }); - } catch (error) { - // This error code indicates that the chain has not been added to Metamask - if (error.code === 4902) { - // Trying to add new chain to Metamask - await window.ethereum.request({ - method: 'wallet_addEthereumChain', - params: [networks.rskTestnet], - }); - } else { - // Rethrow all other errors - throw error; - } - } - } - ``` -- Call the fetchABI function that loads the ABI and connects the wallet to the network - ```js - // Get the required data and set the events - fetchExternalFiles().then(() => { - // Connect button event - connectButton.addEventListener('click', async function () { - // Check the network is set properly - await checkNetwork(); - if (typeof window.ethereum !== 'undefined') { - try { - // Get the account from Metamask - const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' }); - account = accounts[0]; - // Update the front with the account address - walletAddressDiv.innerHTML = `Connected account: ${account}`; - // Get the network provider - provider = new ethers.providers.Web3Provider(window.ethereum); - // Get the signer for network interaction - signer = provider.getSigner(); - // Activates the getBalanceButton - connectButton.disabled = true; - getBalanceButton.disabled = false; - } catch (error) { - console.error("Error connecting to MetaMask", error); - walletAddressDiv.innerHTML = `Error: ${error.message}`; - } - } else { - walletAddressDiv.innerHTML = 'Please install MetaMask!'; - } - }); - ``` -- Add a function responding to the click event on the get balance button. - ```js - // Get balance button event - getBalanceButton.addEventListener('click', async function () { - // Verify contractAddress is a valid address - if (!ethers.utils.isAddress(contractAddress)){ - alert('Please verify that contractAddress is set'); - return; - } - // Instantiate the contract - myTokenContract = new ethers.Contract(contractAddress, contractABI, signer); - // Check if the contract is instatiated properly - if (myTokenContract) { - // Obtains the user balance - const balance = await myTokenContract.balanceOf(account); - // Show the user balance - walletBalanceDiv.innerHTML = `MyToken Balance: ${balance} MTK`; - } - }); - ``` -- View the Complete Code - - [GitHub Link](https://raw.githubusercontent.com/rsksmart/rootstock-quick-start-guide/feat/complete/frontend/app.js) - ```js - document.addEventListener('DOMContentLoaded', function () { - // Instantiating HTML elements - const connectButton = document.getElementById('connectButton'); - const getBalanceButton = document.getElementById('getBalanceButton'); - const walletAddressDiv = document.getElementById('walletAddress'); - const walletBalanceDiv = document.getElementById('walletBalance'); - // Instantiating variables - let provider, account, myTokenContract; - let contractABI = []; - let networks = {}; - const contractAddress = 'Replace with your contract\'s address'; // E.g. 0xa6fb392538BaC56e03a900BFDE22e76C05fb5122 - - /** - * Load data from external JSON files - */ - async function fetchExternalFiles() { - // Place MyToken.json generated in artifacts after compiling the contracts - let response = await fetch('MyToken.json'); - const data = await response.json(); - contractABI = data.abi; - // Place networks.json to set the network automatically with the checkNetwork() function - // You can set it manually instead following this guide https://dev.rootstock.io/resources/tutorials/rootstock-metamask/ - response = await fetch('networks.json'); - networks = await response.json(); - } - - /** - * Check and set network automatically in case it is not already done - */ - async function checkNetwork() { - try { - // Make sure Metamask is installed - if (!window.ethereum){ - alert('Please install Metamask!'); - return; - } - // Switch network - await window.ethereum.request({ - method: 'wallet_switchEthereumChain', - params: [{ chainId: networks.rskTestnet.chainId }], - }); - } catch (error) { - // This error code indicates that the chain has not been added to Metamask - if (error.code === 4902) { - // Trying to add new chain to Metamask - await window.ethereum.request({ - method: 'wallet_addEthereumChain', - params: [networks.rskTestnet], - }); - } else { - // Rethrow all other errors - throw error; - } - } - } - - // Get the required data and set the events - fetchExternalFiles().then(() => { - // Connect button event - connectButton.addEventListener('click', async function () { - // Check the network is set properly - await checkNetwork(); - if (typeof window.ethereum !== 'undefined') { - try { - // Get the account from Metamask - const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' }); - account = accounts[0]; - // Update the front with the account address - walletAddressDiv.innerHTML = `Connected account: ${account}`; - // Get the network provider - provider = new ethers.providers.Web3Provider(window.ethereum); - // Get the signer for network interaction - signer = provider.getSigner(); - // Activates the getBalanceButton - connectButton.disabled = true; - getBalanceButton.disabled = false; - } catch (error) { - console.error("Error connecting to MetaMask", error); - walletAddressDiv.innerHTML = `Error: ${error.message}`; - } - } else { - walletAddressDiv.innerHTML = 'Please install MetaMask!'; - } - }); - - // Get balance button event - getBalanceButton.addEventListener('click', async function () { - // Verify contractAddress is a valid address - if (!ethers.utils.isAddress(contractAddress)){ - alert('Please verify that contractAddress is set'); - return; - } - // Instantiate the contract - myTokenContract = new ethers.Contract(contractAddress, contractABI, signer); - // Check if the contract is instatiated properly - if (myTokenContract) { - // Obtains the user balance - const balance = await myTokenContract.balanceOf(account); - // Show the user balance - walletBalanceDiv.innerHTML = `MyToken Balance: ${balance} MTK`; - } - }); - }); - }); - ``` - -### Run the frontend - -To run the frontend, execute a local web server to test the HTML file using the following command: - -```shell -npx http-server -``` - -Navigate to the URL: `http://127.0.0.1:8080` to test the code in the browser and you should get a result similar to the image below: -![Smart Contract Frontend](/img/guides/quickstart/hardhat/frontend.png) - - -:::tip[Tip] -- Ensure the local hardhat network is running. Run `npx hardhat node` in the root directory to start the local network. See section on [Troubleshooting and Common Errors](/developers/smart-contracts/hardhat/troubleshooting/) to fix common errors. -- You can view and run the complete project from the [`feat/complete` branch](https://github.com/rsksmart/rootstock-quick-start-guide/tree/feat/complete). To do so, git checkout into the `feat/complete` branch, run `cd frontend`, run `npm install`, then run `npx http-server` to view and interact with the smart contract from the frontend. -::: +1. Create a new web project. In this case, we'll be using [Next.js](https://nextjs.org/) as our web framework. + + ```shell + npx create-next-app@latest + ``` + +2. Go to the root of your Next.js project and, using your preferred package manager, install these dependencies: + + ```shell + yarn add @rainbow-me/rainbowkit wagmi viem@2.x @tanstack/react-query + ``` + +3. Create an `.env` file at the root of your project and add the following content. You can get your Wallet Connet ID from [WalletConnect Dashboard](https://cloud.reown.com/sign-in). + + ```shell + touch .env.local + echo "NEXT_PUBLIC_WC_PROJECT_ID=" >> .env.local + ``` + +4. Create a `providers.tsx` file inside the `app` directory and add the following content: + + ```tsx + "use client"; + + import { + getDefaultConfig, + RainbowKitProvider, + } from "@rainbow-me/rainbowkit"; + import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; + import { WagmiProvider } from "wagmi"; + import { rootstock, rootstockTestnet } from "wagmi/chains"; + + const config = getDefaultConfig({ + appName: "Rootstock Wagmi Starter", + projectId: process.env.NEXT_PUBLIC_WC_PROJECT_ID as string, + chains: [rootstockTestnet, rootstock], + ssr: true, + }); + + const queryClient = new QueryClient(); + + export default function Providers({ + children, + }: { + children: React.ReactNode; + }) { + return ( + + + {children} + + + ); + } + ``` + +5. And now import and use the `Providers` component to wrap your application in the `layout.tsx` file inside the `app` directory: + + ```tsx + import type { Metadata } from "next"; + import "./globals.css"; + import localFont from "next/font/local"; + import Providers from "./providers"; + import "@rainbow-me/rainbowkit/styles.css"; + + export const metadata: Metadata = { + title: "Rootstock Wagmi Starter", + description: + "Interact with contracts on Rootstock Network with Wagmi and RainbowKit", + }; + + const geistSans = localFont({ + src: "./fonts/GeistVF.woff", + variable: "--font-geist-sans", + weight: "100 900", + }); + const geistMono = localFont({ + src: "./fonts/GeistMonoVF.woff", + variable: "--font-geist-mono", + weight: "100 900", + }); + + export default function RootLayout({ + children, + }: Readonly<{ + children: React.ReactNode; + }>) { + return ( + + + {children} + + + ); + } + ``` + +6. Finally, start the web server. + + ``` + yarn dev + ``` + +If everything went well, you should be able to access your web app by navigating to `http://localhost:3000` in your browser. + +### Congrats! + +You're all set up. Let's get to the smart contract interaction. + +## Call Smart Contract using Connect Button and Wagmi hooks + +We're going to be editing the `page.tsx` file inside the `app` directory. Follow these steps to interact with the smart contract: + +1. Delete the default content and add the `` component to check if it's working fine. + + ```tsx + import { ConnectButton } from "@rainbow-me/rainbowkit"; + + export default function Home() { + return ( +
+ +
+ ); + } + ``` + + And you should see something like this in the browser: + + ![Connect Button](/img/guides/quickstart/hardhat/connect-button.png) + + Please try connecting your wallet. + +2. Now we're going to use our first hook from Wagmi to check if a user wallet is connected and, if so, get the connected address. The hook is `useAccount` and is used like this: + + ```tsx + const { + address, // Connected address + isConnected, // true if a wallet is connected + } = useAccount(); + ``` + + > **Note:** As we're using react hooks in a Next.js project, don't forget to add the `'use client'` directive at the top of your `page.tsx` file. + + Now that we know if a wallet is connected, we can add some conditional rendering content and show the connected address. + + ```tsx + { + isConnected &&

Connected address: {address}

; + } + ``` + + So the full code on the `page.tsx` file should be something like this: + + ```tsx + "use client"; + + import { ConnectButton } from "@rainbow-me/rainbowkit"; + import { useAccount } from "wagmi"; + + export default function Home() { + const { isConnected, address } = useAccount(); + + return ( +
+ + + {isConnected &&

Connected address: {address}

} +
+ ); + } + ``` + + And the browser should look something like this: + + ![Connected Address](/img/guides/quickstart/hardhat/connect-button.png) + +3. We're now going to make our first read from the blockchain. The hook we're using for that is `useReadContract` and is used like this: + + ```tsx + const { + data: balance, // Retrieved data from the function + isLoading, // Check if the data is still being fetched + error, // Check if an error occurred + } = useReadContract({ + address: "", // Your deployed contract address + abi: [ + // Contract abi + ], + functionName: "balanceOf", // The name of the function you want to call + args: [address], // Function arguments if they are required + }); + ``` + + Given this, we need to bring the contract abi that should be available at the **Hardhat project** we've been working on. Once you compile a contract, a file is generated at `artifacts/contracts/YourContract.sol/YourContract.json` which contains the abi of the contract. + + In this case, we're going to copy the abi array and paste it in a new file called `MyContractAbi.ts` inside a new `assets` folder. the file should look like this: + + ```ts + // assets/MyContractAbi.ts + + export const abi = [ + { + inputs: [ + { + internalType: "uint256", + name: "initialSupply", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + ... + ]; + ``` + + Now, lets compose our `useReadContract` hook with our contract information and show the balance of the connected address: + + ```ts + "use client"; + + import { abi } from "@/assets/MyTokenAbi"; + import { ConnectButton } from "@rainbow-me/rainbowkit"; + import { useAccount, useReadContract } from "wagmi"; + + const CONTRACT_ADDRESS = "0x543ba9fc0ade6f222bd8c7bf50a0cd9923faf569"; // Replace with your contract address + + export default function Home() { + const { isConnected, address } = useAccount(); + const { + data: balance, + isLoading, + error, + } = useReadContract({ + // Once the component is mounted, useReadContract is called + address: CONTRACT_ADDRESS, + abi, + functionName: "balanceOf", + args: [address], // Replace with the address you want to check + }); + + return ( +
+ + + {isConnected && ( + <> +

Connected address: {address}

+

+ Balance:{" "} + { + isLoading // Check if the data is still being fetched + ? "Loading..." + : error // Check if there was an error + ? "Error retrieving balance" + : balance?.toString() // If the data is ready, display the balance + } +

+ + )} +
+ ); + } + ``` + + And the browser should look something like this: + + ![Balance of](/img/guides/quickstart/hardhat/balance-of.png) + + ### Well done! + + You made your first read from the Rootstock blockchain in a web application. Now let's move on to the writing. + +4. The hook we're using for calling a write function is `useWriteContract`. When calling write functions, I recommend mixing the hook with another wagmi tool called `waitForTransactionReceipt`. Later in the article we'll see why it is important and how to use it. For now, this is how you use `useWriteContract` hook. + + ```tsx + const { + writeContractAsync, // The callable asynchronous function + } = useWriteContract(); + ``` + + And the `writeContractAsync` function is called very similar to the `useReadContract` hook: + + ```tsx + const hash = await writeContractAsync({ + address: CONTRACT_ADDRESS, // Your deployed contract address + abi, // Contract abi + functionName: "mint", // The name of the function you want to call + args: [address, amount], // Function arguments if they are required + }); + ``` + + The `writeContractAsync` function returns a hash that enables the `waitForTransactionReceipt` power. The `waitForTransactionReceipt` function allows you to wait until the transaction is confirmed the number of times you specify. You can call it like this: + + ```tsx + await waitForTransactionReceipt( + config, // the wagmi config + { + hash, // the transaction hash + confirmations: 1, // the number of confirmations to wait for + } + ); + ``` + + > **Note:** Sometimes getting the wagmi config can be a bit tricky. You can get it very easily using the `useConfig` hook. In the next section we'll see how to do it. + + So, now that we have all things needed, we're creating a button that will allow us to transfer tokens. For now, we'll fix the token amount to 10 and the address, but you can modify this starter kit as you can, your imagination is the limit. Your code should look something like this: + + ```tsx + "use client"; + + import { abi } from "@/assets/MyTokenAbi"; + import { ConnectButton } from "@rainbow-me/rainbowkit"; + import { useState } from "react"; + import { + useAccount, + useConfig, + useReadContract, + useWriteContract, + } from "wagmi"; + import { waitForTransactionReceipt } from "wagmi/actions"; + + const CONTRACT_ADDRESS = "0x543ba9fc0ade6f222bd8c7bf50a0cd9923faf569"; + + export default function Home() { + const [loading, setLoading] = useState(false); // Add loading state + const config = useConfig(); // Get the wagmi config + const { isConnected, address } = useAccount(); + const { + data: balance, + isLoading, + error, + refetch, + } = useReadContract({ + address: CONTRACT_ADDRESS, + abi, + functionName: "balanceOf", + args: [address], + }); + + const { writeContractAsync } = useWriteContract(); // get the callable write contract function + + async function handleTransfer() { + try { + setLoading(true); + + const hash = await writeContractAsync({ + address: CONTRACT_ADDRESS, + abi, + functionName: "transfer", + args: ["0x4913AbCD40a9455a28134b4ccc37f4f95225e593", 10], // Replace with the address and amount you want to transfer + }); + + await waitForTransactionReceipt(config, { + hash, + confirmations: 1, + }); + + refetch(); // Refetch the balance after transfer + } catch (error) { + alert("Error transferring MTK. Look at the console."); + console.error(error); + } finally { + setLoading(false); + } + } + + return ( +
+ + + {isConnected && ( + <> +

Connected address: {address}

+

+ Balance:{" "} + {isLoading + ? "Loading..." + : error + ? "Error retrieving balance" + : balance?.toString()} +

+ + + )} +
+ ); + } + ``` + + > **Note:** Please make sure you have available tokens in your wallet before transferring. Otherwise, you'll get an error. + + Note that we retrieved the `refetch` function from the `useReadContract` hook. This allows us to refetch the balance after the transfer. Also, there is shown how to use the `useConfig` hook to get the wagmi config. + + By now, the page should look something like this: + + ![Write Contract](/img/guides/quickstart/hardhat/write-contract.png) + + When transferring, the button should look something like this: + + ![Transferring](/img/guides/quickstart/hardhat/transferring.png) + + And when the transfer is complete, the balace should update immediately: + + ![Transfer complete](/img/guides/quickstart/hardhat/transfer-complete.png) + + ### Well done! + + You just made created a dApp that allows you to send write/read transactions to the Rootstock blockchain! ## Resources -These tools are specifically tailored for Web3 development, and they can simplify the integration of blockchain functionaity into web interfaces. Here are a few recommended tools and libraries that are popular in the Web3 space, along with brief descriptions: +These tools are specifically designed to make Web3 development smoother, particularly for integrating blockchain functionalities into web applications. Below is a list of key libraries and tools that were used in the article, with brief explanations: @@ -332,31 +445,19 @@ These tools are specifically tailored for Web3 development, and they can simplif It is great for projects where you want a seamless and user-friendly wallet connection experience. It's easy to integrate and manage, especially in React-based applications. - - 2. Web3Modal - - - [Web3Modal](https://web3modal.com/) is a JavaScript library that provides a simple, unified wallet connection modal for Web3 applications. It supports various wallet providers and can be used with different Web3 libraries. - - **Why Use It:** If you need to start using React or want a framework-agnostic wallet connection solution, Web3Modal is an excellent choice. It’s customizable and works well with both web3.js and ethers.js. - - + - 3. Wagmi + 2. Wagmi - - [Wagmi](https://wagmi.sh/) is a React Hooks for Ethereum set that simplifies interactions with ethers.js. It provides hooks for wallet connection, contract interaction, balances, and more. + - [Wagmi](https://wagmi.sh/) is a set of React Hooks for Ethereum that simplifies interactions with ethers.js. It provides hooks for wallet connection, contract interaction, balances, and more. - **Why Use It:** For React developers who prefer a hooks-based approach, Wagmi offers an elegant way to integrate Ethereum functionality. It makes managing state and blockchain interactions more intuitive. - - 4. Moralis - - - [Moralis](https://moralis.io/) is a fully managed backend platform for Web3 and blockchain applications. It offers a suite of tools for authentication, real-time databases, cloud functions, and syncing blockchain data. - - **Why Use It:** It can be a time-saver to build a more comprehensive application with backend support. It handles much of the backend complexity and lets you focus on front-end development. - - - 5. Foundry + 3. Viem - - [Foundry](https://book.getfoundry.sh) is a smart contract development toolchain, and user-friendly development environment used for writing and advanced smart contracts testing in Solidity. + -[Viem](https://viem.sh/) is a TypeScript-first library built for working with Ethereum and other blockchain networks. It focuses on performance, developer experience, and extensibility, making it a powerful tool for interacting with smart contracts and building Web3 apps. + - **Why Use It:** Viem enhances development speed by providing efficient utilities and a modern approach to handling blockchain interactions. It pairs well with Wagmi and other Web3 libraries. - \ No newline at end of file + diff --git a/docs/02-developers/05-smart-contracts/02-hardhat/troubleshooting.md b/docs/02-developers/05-smart-contracts/02-hardhat/troubleshooting.md index 973aa448..6d48cd82 100644 --- a/docs/02-developers/05-smart-contracts/02-hardhat/troubleshooting.md +++ b/docs/02-developers/05-smart-contracts/02-hardhat/troubleshooting.md @@ -10,27 +10,45 @@ This section provides help on some potential issues you may run into and tips on ## Errors -- Error HH8: There's one or more errors in your config file - ```shell - % npx hardhat compile - Error HH8: There's one or more errors in your config file: + + + Error HH8: There's one or more errors in your config file + + ```shell + % npx hardhat compile + Error HH8: There's one or more errors in your config file: - * Invalid account: #0 for network: rskMainnet - Expected string, received undefined - * Invalid account: #0 for network: rskTestnet - Expected string, received undefined + * Invalid account: #0 for network: rskMainnet - Expected string, received undefined + * Invalid account: #0 for network: rskTestnet - Expected string, received undefined - To learn more about Hardhat's configuration, please go to https://hardhat.org/config/ + To learn more about Hardhat's configuration, please go to https://hardhat.org/config/ - For more info go to https://hardhat.org/HH8 or run Hardhat with --show-stack-traces - ``` - > - FIX 1: Ensure the values in the environment variables matches with the hardhat network configuration `hardhat.config.js` file. For bash, run `source .env` in the root directory for dotenv to enable the environment variables. -- Error: Nothing to Compile - ```shell - % npx hardhat compile - Nothing to compile - ``` - > - FIX 2: Delete artifacts folder and run the `npx hardhat compile` command to generate new artifacts. -- Error: "GET /MyToken.json" Error (404): "Not found" - - Check that contracts were compiled successfully, and artifacts folder was generated. - - Check that all the steps in [interacting with frontend](/developers/smart-contracts/hardhat/interact-with-frontend/) were followed sequentially. -- Error: HH601: Script scripts/deploy.js doesn't exist. - - Ensure that you're running the `npx hardhat run --network hardhat scripts/deploy.js` command from the root directory. \ No newline at end of file + For more info go to https://hardhat.org/HH8 or run Hardhat with --show-stack-traces + ``` + > - FIX 1: Ensure the values in the environment variables matches with the hardhat network configuration `hardhat.config.js` file. For bash, run `source .env` in the root directory for dotenv to enable the environment variables. + + + + Error: Nothing to Compile + + ```shell + % npx hardhat compile + Nothing to compile + ``` + > - FIX 2: Delete artifacts folder and run the `npx hardhat compile` command to generate new artifacts. + + + + Error: "GET /MyToken.json" Error (404): "Not found" + + - Check that contracts were compiled successfully, and artifacts folder was generated. + - Check that all the steps in [interacting with frontend](/developers/smart-contracts/hardhat/interact-with-frontend/) were followed sequentially. + + + + Error: HH601: Script scripts/deploy.js doesn't exist. + + - Ensure that you're running the `npx hardhat run --network hardhat scripts/deploy.js` command from the root directory. + + + \ No newline at end of file diff --git a/docs/02-developers/05-smart-contracts/03-interface-registry/index.md b/docs/02-developers/05-smart-contracts/03-interface-registry/index.md index 81cb8c4c..296001d4 100644 --- a/docs/02-developers/05-smart-contracts/03-interface-registry/index.md +++ b/docs/02-developers/05-smart-contracts/03-interface-registry/index.md @@ -1,6 +1,6 @@ --- sidebar_label: Interface Registry -sidebar_position: 300 +sidebar_position: 500 title: Universal Smart Contract Interface Registry description: "See the ERC1820 standard interface, address support and smart contract implementation" tags: [smart contracts, rsk, rootstock, developers, interface registry] diff --git a/docs/02-developers/05-smart-contracts/04-verify-smart-contracts/index.md b/docs/02-developers/05-smart-contracts/04-verify-smart-contracts/index.md index 28b3c306..e2a75fef 100644 --- a/docs/02-developers/05-smart-contracts/04-verify-smart-contracts/index.md +++ b/docs/02-developers/05-smart-contracts/04-verify-smart-contracts/index.md @@ -160,6 +160,7 @@ Successfully verified contract MockERC721 on the block explorer. https://rootstock-testnet.blockscout.com/address/0x33aC0cc41B11282085ff6db7E1F3C3c757143722#code ``` ## Resources +- [Deploy, Interact and Verify Smart Contracts using Remix and Rootstock Explorer](/developers/quickstart/remix/) - Visit [hardhat-verify](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-verify#hardhat-verify) - Visit [blockscout](https://docs.blockscout.com/for-users/verifying-a-smart-contract/hardhat-verification-plugin) - [Hardhat Starter Kit for Rootstock](https://github.com/rsksmart/rootstock-hardhat-starterkit) \ No newline at end of file diff --git a/docs/02-developers/05-smart-contracts/05-foundry/configure-foundry-rootstock.md b/docs/02-developers/05-smart-contracts/05-foundry/configure-foundry-rootstock.md new file mode 100644 index 00000000..77bbc9a1 --- /dev/null +++ b/docs/02-developers/05-smart-contracts/05-foundry/configure-foundry-rootstock.md @@ -0,0 +1,31 @@ +--- +sidebar_label: Configure Foundry for Rootstock +sidebar_position: 102 +title: Configure Foundry for Rootstock +description: "Learn how to configure your Foundry project for development on Rootstock testnet and mainnet" +tags: [guides, developers, smart contracts, rsk, rootstock, foundry, dApps, ethers] +--- + +### Environment Configuration + +Once you have an account with a private key, create a `.env` file in the root of the foundry project and add the variables. + +Foundry automatically loads a `.env` file present in the project directory. + +The `.env` file should follow this format: + +```bash +ROOTSTOCK_RPC_URL=https://rpc.testnet.rootstock.io/{YOUR_APIKEY} +PRIVATE_KEY=0x... +``` +:::info[Info] +* Your PRIVATE_KEY has to be formatted correctly, so it has to start with `0x`. +* To obtain a Rootstock Rpc Url, visit the [RPC API DASHBOARD](https://rpc.rootstock.io/), create an account and get your testnet or mainnet rpc url. +::: + +At the root of the project, run: + +```bash +# To load the variables in the .env file +source .env +``` \ No newline at end of file diff --git a/docs/02-developers/05-smart-contracts/05-foundry/create-foundry-project.md b/docs/02-developers/05-smart-contracts/05-foundry/create-foundry-project.md new file mode 100644 index 00000000..581c282f --- /dev/null +++ b/docs/02-developers/05-smart-contracts/05-foundry/create-foundry-project.md @@ -0,0 +1,36 @@ +--- +sidebar_label: Create a Foundry Project +sidebar_position: 101 +title: Create a Foundry Project +description: "Learn how to set up your environment for development using Foundry" +tags: [guides, developers, smart contracts, rsk, rootstock, foundry, dApps] +--- + + +In this guide, we will learn about Foundry and its benefits for smart contract development, how to setup your environment, create a Foundry project and execute a deployment script. + +## Installation + +To install, use Foundryup. Foundryup is the Foundry toolchain installer. You can find more information in the [Foundry README](https://github.com/foundry-rs/foundry/blob/master/foundryup/README.md). + +```bash +curl -L https://foundry.paradigm.xyz | bash +``` +:::note[Windows Users] +If you’re using Windows, you’ll need to install and use [Git BASH](https://gitforwindows.org/) or [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) as your terminal, since Foundryup currently doesn’t support Powershell or Command Prompt (Cmd). +::: + +Running foundryup by itself will install the latest (nightly) precompiled binaries: `forge`, `cast`, `anvil`, and `chisel`. + +> Visit the [installation guides](https://book.getfoundry.sh/getting-started/installation) for more information. + +## Create a foundry project + +To start a new project with Foundry, use [forge init](https://book.getfoundry.sh/reference/forge/forge-init.html). + +```bash +forge init hello_foundry +``` + +> See more details on how to [create a new project](https://book.getfoundry.sh/projects/creating-a-new-project) using the Foundry guide. + diff --git a/docs/02-developers/05-smart-contracts/05-foundry/deploy-smart-contracts.md b/docs/02-developers/05-smart-contracts/05-foundry/deploy-smart-contracts.md new file mode 100644 index 00000000..670226a1 --- /dev/null +++ b/docs/02-developers/05-smart-contracts/05-foundry/deploy-smart-contracts.md @@ -0,0 +1,69 @@ +--- +sidebar_label: Deploy Smart Contract +sidebar_position: 105 +title: Deploy Smart Contract +description: "Learn how to deploy your Rootstock smart contract using forge." +tags: [guides, developers, smart contracts, rsk, rootstock, foundry, dApps] +--- + +In this section, you'll deploy a `counter` smart contract to the Rootstock network using Foundry. + +## Step 1: Deployment Script +You will see a directory called `deploy` in the root of your project. This is where you can view/write your deployment scripts. The demo `counter.sol` comes with a deployment script `counter.s.sol`, please copy the following code into the file: + +```solidity +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Script, console} from "forge-std/Script.sol"; +import {Counter} from "../src/Counter.sol"; + +contract CounterScript is Script { + function setUp() public {} + + function run() public { + vm.startBroadcast(vm.envUint("PRIVATE_KEY")); + + new Counter(); + + vm.stopBroadcast(); + } +} +``` +:::info[Info] +- Demo comes with Foundry's default sender, in this script we are using the sender's private key to deploy the contract ```vm.envUint("PRIVATE_KEY")```. +::: +## Step 2: Deploy Your Contract on Rootstock Network +Run the following command, replacing `https://public-node.testnet.rsk.co` with either `rskTestnet` or `rskMainnet` rpc url if you have, depending on your desired deployment environment: + +```bash +forge script script/Counter.s.sol --rpc-url https://public-node.testnet.rsk.co --broadcast --legacy --evm-version london +``` +:::info[Info] +- [EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md) is not supported or not activated on the Rootstock RPC url +- To avoid Foundry's compatibility issues, we are using the `--evm-version london` flag. +- The `--legacy` flag is passed to use legacy transactions instead of `EIP-1559`. +- You can remove the `--broadcast` flag if you wan to simulate the transaction without broadcasting it. +::: + +> If you get an error like `Transaction dropped from the mempool: ` or the ```transaction not completed```, check the tx-id in the explorer. The tx may have went successful but the error is still in the logs. Here are the [mainnet](https://explorer.rootstock.io/) and [testnet](https://explorer.testnet.rootstock.io/) explorers. + +> Also you can see the transaction registry locally, by checking the folder ```broadcast/Counter.s.sol/``` and opening the file called ```run-latest.json```, if you check the fields, there is one called ```contractAddress``` which contains the new address deployed for our ERC20 smart contract. + +The result in the console should look like this: +```bash +Sending transactions [0 - 0]. +⠁ [00:00:00] [###############################################################################################################################################] 1/1 txes (0.0s)## +Waiting for receipts. +β ‰ [00:00:25] [###########################################################################################################################################] 1/1 receipts (0.0s) +##### 31 +βœ… [Success]Hash: 0x48ea2b06b39cd436a2d7564e20ea5bb598ddc2769e6b18c855170f0e9e4d5687 +Contract Address: 0x499e802a6825d30482582d9b9dd669ba82ba8ba4 +Block: 5071408 +Gas Used: 106719 + +========================== + +ONCHAIN EXECUTION COMPLETE & SUCCESSFUL. +Total Paid: 0. ETH (106719 gas * avg 0 gwei) +``` diff --git a/docs/02-developers/05-smart-contracts/05-foundry/index.md b/docs/02-developers/05-smart-contracts/05-foundry/index.md index 16f95160..4182699c 100644 --- a/docs/02-developers/05-smart-contracts/05-foundry/index.md +++ b/docs/02-developers/05-smart-contracts/05-foundry/index.md @@ -1,193 +1,27 @@ --- -section_position: 200 sidebar_label: Getting Started with Foundry +section_position: 200 title: Getting Started with Foundry description: 'How to write, test, and deploy smart contracts with Foundry' tags: [rsk, foundry, developers, developer tools, rootstock, testing, dApps, smart contracts] --- -In this guide, we will learn about Foundry and its benefits for smart contract development, how to setup your environment, create a Foundry project and execute a deployment script. - -## Prerequisites - -To get started with Foundry, ensure the following tools are installed: -- The [Rust](https://rust-lang.org/) Compiler -- Cargo Package Manager - -> For an easy installation of the above tools, use the [rustup installer](https://rustup.rs). - -## Installation - -To install, use Foundryup. Foundryup is the Foundry toolchain installer. You can find more information in the [Foundry README](https://github.com/foundry-rs/foundry/blob/master/foundryup/README.md). - -```bash -curl -L https://foundry.paradigm.xyz | bash -``` - -Running foundryup by itself will install the latest (nightly) precompiled binaries: `forge`, `cast`, `anvil`, and `chisel`. - -> Visit the [installation guides](https://book.getfoundry.sh/getting-started/installation) for more information. - -## Create a foundry project - -To start a new project with Foundry, use [forge init](https://book.getfoundry.sh/reference/forge/forge-init.html). - -```bash -forge init hello_foundry -``` - -> See more details on how to [create a new project](https://book.getfoundry.sh/projects/creating-a-new-project) using the Foundry guide. - -## Write your first contract - -Let’s view the file structure for a default foundry project: - -```bash -$ cd hello_foundry -$ tree . -d -L 1 -. -β”œβ”€β”€ lib -β”œβ”€β”€ script -β”œβ”€β”€ src -└── test - -4 directories -``` - -The `src` directory contains counter smart contract with test written in the `test` directory. Now, let's build the foundry project. - -```bash -forge build -``` - -And then run tests. - -```bash -forge test -``` - -## Deploy contract on the Rootstock - -To deploy the counter contract on Rootstock mainnet or testnet, further configure Foundry by setting up a Rootstock RPC url and a private key of an account that’s funded with tRBTC. - -### Environment Configuration - -Once you have an account with a private key, create a `.env` file in the root of the foundry project and add the variables. - -Foundry automatically loads a `.env` file present in the project directory. - -The `.env` file should follow this format: - -```bash -ROOTSTOCK_RPC_URL=https://rpc.testnet.rootstock.io/{YOUR_APIKEY} -PRIVATE_KEY=0x... -``` - -At the root of the project, run: - -```bash -# To load the variables in the .env file -source .env -``` - -### Modify Deployment Script - -Modify the deployment counter deploy script in the `scripts` directory to use the private key by modifying the run method, see below example: +:::note[Before you begin] -```solidity -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import {Script, console} from "forge-std/Script.sol"; - -import "../src/Counter.sol"; - - -contract CounterScript is Script { - function setUp() public {} - - function run() public { - vm.startBroadcast(vm.envUint("PRIVATE_KEY")); - - new Counter(); - - vm.stopBroadcast(); - - } -} - -``` - -By default, scripts are executed by calling the function named `run` at the entrypoint. - -```solidity -uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); -``` - -> - CAUTION: Be cautious when exposing private keys in a `.env` file and loading them into programs. - > - This is only recommended for use with non-privileged deployers or for local / test setups. - -When calling `vm.startBroadcast()`, the contract creation will be recorded by Forge, and we can broadcast the transaction to deploy the contract on-chain. - -### Execute the deployment script - -We will use Forge to run our script and broadcast the transactions - this can take a little while, since Forge also waits for the transaction receipts. - -```bash -forge script script/Counter.s.sol --rpc-url $ROOTSTOCK_RPC_URL --broadcast --legacy -``` - -:::info[Info] - -- [EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md) is not supported or not activated on the Rootstock RPC url -- The `--legacy` flag is passed to use legacy transactions instead of `EIP-1559`. +> If you're new to Web3 and Smart Contract Development, begin by exploring the [Rootstock network](/developers/blockchain-essentials/overview/). Then progress step by step to the [quick start Guide with Foundry](/developers/quickstart/foundry/) for a comprehensive understanding of the network and getting started with writing, testing, and deploying smart contracts on Rootstock. +> Note: This guide is optimized for Node.js version 18 or earlier. If you're using a later version, consider using a version manager like [NVM](https://github.com/nvm-sh/nvm/blob/master/README.md) to switch to a compatible version. ::: -The result should look like this: - -```bash -[β °] Compiling... -No files changed, compilation skipped -Script ran successfully. - -== Logs == - Counter: - -## Setting up 1 EVM. - -========================== - -Chain 31 - -Estimated gas price: 0.065164 gwei - -Estimated total gas used for script: 138734 - -Estimated amount required: 0.000009040462376 ETH - -========================== -## -Sending transactions [0 - 0]. -⠁ [00:00:00] [###############################################################################################################################################] 1/1 txes (0.0s)## -Waiting for receipts. -β ‰ [00:00:25] [###########################################################################################################################################] 1/1 receipts (0.0s) -##### 31 -βœ… [Success]Hash: 0x015de35ffae94f491d4630f2aec84c49ae8170d5ecf3f4c1cdc8718bc4a00052 -Contract Address: 0x64B24E046259042e16a337Be4648CeAAF8Eb72C6 -Block: 5071408 -Gas Used: 106719 - -========================== - -ONCHAIN EXECUTION COMPLETE & SUCCESSFUL. -Total Paid: 0. ETH (106719 gas * avg 0 gwei) - -Transactions saved to: /hello_foundry/broadcast/Counter.s.sol/31/run-latest.json - -Sensitive values saved to: /hello_foundry/cache/Counter.s.sol/31/run-latest.json -``` - -> The broadcast directory will be updated automatically with the latest output of the deployment. - -> See the [foundry deployment documentation](https://book.getfoundry.sh/tutorials/solidity-scripting#deploying-our-contract). \ No newline at end of file +## Navigating the Guide + +| Resource | Description | +| ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | +| [Prerequisites](/developers/requirements/) | Learn about the tools you need to have in place to follow along with this guide.| +| [Create a Foundry Project](/developers/smart-contracts/foundry/create-foundry-project/) | Learn how to set up your environment for development using Foundry.| +| [Configure Foundry for Rootstock](/developers/smart-contracts/foundry/configure-foundry-rootstock/) | Learn how to configure your Foundry project for development on Rootstock testnet and mainnet.| +| [Smart Contract](/developers/smart-contracts/foundry/smart-contracts/) | Check foundry demo smart contract.| +| [Test Smart Contract](/developers/smart-contracts/foundry/test-smart-contracts/) | Learn how to test your smart contract using `forge`. | +| [Deploy Smart Contract](/developers/smart-contracts/foundry/deploy-smart-contracts/) | Learn how to deploy your smart contract using `forge`. | +| [Interact with Smart Contract](/developers/smart-contracts/foundry/interact-with-contract/) | Learn how to interact with your smart contract using `cast`. | +| [Debugging and Troubleshooting Tips](/developers/smart-contracts/foundry/troubleshooting/) | Learn about the common issues you can come across while building following this guide and how you can solve them. | \ No newline at end of file diff --git a/docs/02-developers/05-smart-contracts/05-foundry/interact-with-contract.md b/docs/02-developers/05-smart-contracts/05-foundry/interact-with-contract.md new file mode 100644 index 00000000..aca596db --- /dev/null +++ b/docs/02-developers/05-smart-contracts/05-foundry/interact-with-contract.md @@ -0,0 +1,24 @@ +--- +sidebar_label: Interact with the Smart Contract +sidebar_position: 106 +title: Interact with the Smart Contract +description: "Learn how to interact with your smart contract using cast" +tags: [guides, developers, smart contracts, rsk, rootstock, hardhat, dApps, ethers] +--- + + +Interacting with a smart contract is a crucial part of the development process. Here, we'll focus on using `cast`, a command-line tool that allows you to interact with your smart contract. + +## Interacting with the Contract +If the contract is already deployed, then you can interact with it using ```cast``` this command allows you to interact with the contract, in this case, read the balance of an account. + +### Reading the Balance of an Account +In your terminal, run the following command, replacing the placeholders with actual values: + +```bash +cast call "balanceOf(address)(uint256)" --rpc-url +``` +The result should look like this: +```bash +1000000000000000000000 [1e21] +``` diff --git a/docs/02-developers/05-smart-contracts/05-foundry/smart-contracts.md b/docs/02-developers/05-smart-contracts/05-foundry/smart-contracts.md new file mode 100644 index 00000000..13cd3e6e --- /dev/null +++ b/docs/02-developers/05-smart-contracts/05-foundry/smart-contracts.md @@ -0,0 +1,60 @@ +--- +sidebar_label: Smart Contract +sidebar_position: 103 +title: Smart Contract +description: "Learn how to write a smart contract using Solidity and OpenZeppellin" +tags: [guides, developers, smart contracts, rsk, rootstock, hardhat, dApps, ethers] +--- + +## Folder Structure + +Let’s view the file structure for a default foundry project: + +```bash +$ cd hello_foundry +$ tree . -d -L 1 +. +β”œβ”€β”€ lib +β”œβ”€β”€ script +β”œβ”€β”€ src +└── test + +4 directories +``` + +## Demo smart contract +In the `src` folder, you will find a simple smart contract called `counter.sol`. Which contains a simple counter contract. + +```solidity +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Counter { + uint256 public number; + + function setNumber(uint256 newNumber) public { + number = newNumber; + } + + function increment() public { + number++; + } +} +``` + +## Compile the Contract +To build the contract, run the following command in the project's root directory. + +```bash +forge build +``` + +This will compile your smart contracts and generate `out` directory: + +```bash +forge build +[⠊] Compiling... +[β ’] Compiling 36 files with Solc 0.8.24 +[β ‘] Solc 0.8.24 finished in 1.56s +Compiler run successful! +``` diff --git a/docs/02-developers/05-smart-contracts/05-foundry/test-smart-contracts.md b/docs/02-developers/05-smart-contracts/05-foundry/test-smart-contracts.md new file mode 100644 index 00000000..be3ee4c4 --- /dev/null +++ b/docs/02-developers/05-smart-contracts/05-foundry/test-smart-contracts.md @@ -0,0 +1,64 @@ +--- +sidebar_label: Test Smart Contract +sidebar_position: 104 +title: Testing Smart Contracts using Foundry +description: "Learn how to test your Rootstock smart contract using Foundry" +tags: [guides, developers, smart contracts, rsk, rootstock, foundry, dApps, ethers] +--- + +In this section, you'll set up a smart contract test and test it using `forge`. + +### Step 1: Test Script +You will see a directory called `test` in the root of your project. This is where you can view/write your tests. The demo `counter.sol` comes with a test script `counter.t.sol`, which contains: + +```solidity +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Test, console} from "forge-std/Test.sol"; +import {Counter} from "../src/Counter.sol"; + +contract CounterTest is Test { + Counter public counter; + + function setUp() public { + counter = new Counter(); + counter.setNumber(0); + } + + function test_Increment() public { + counter.increment(); + assertEq(counter.number(), 1); + } + + function testFuzz_SetNumber(uint256 x) public { + counter.setNumber(x); + assertEq(counter.number(), x); + } +} +``` + +### Step 2: Run the Test +To run the test, execute the following command in the root of your project: + +```shell +forge test +``` + +This will run the test script and display the results in the terminal. +```shell +forge test +[⠊] Compiling... +[⠊] Compiling 33 files with Solc 0.8.24 +[β ’] Solc 0.8.24 finished in 947.64ms +Compiler run successful! +Ran 2 tests for test/Counter.t.sol:CounterTest +[PASS] testFuzz_SetNumber(uint256) (runs: 256, ΞΌ: 30899, ~: 31288) +[PASS] test_Increment() (gas: 31303) +Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 11.85ms (6.49ms CPU time) + +Ran 2 test suites in 137.32ms (19.93ms CPU time): 6 tests passed, 0 failed, 0 skipped (6 total tests) +``` +:::note[Additional tests] +If you need additional tests, or want to go deep on this step, visit the [Foundry Tests Documentation](https://book.getfoundry.sh/forge/tests).. +::: \ No newline at end of file diff --git a/docs/02-developers/05-smart-contracts/05-foundry/troubleshooting.md b/docs/02-developers/05-smart-contracts/05-foundry/troubleshooting.md new file mode 100644 index 00000000..65ab6144 --- /dev/null +++ b/docs/02-developers/05-smart-contracts/05-foundry/troubleshooting.md @@ -0,0 +1,26 @@ +--- +sidebar_label: Debugging and Troubleshooting +sidebar_position: 106 +title: Common Errors and Tips +description: "Learn about some potential issues you can run into and tips on how to resolve them." +tags: [guides, developers, smart contracts, rsk, rootstock, foundry, dApps, ethers] +--- + +This section provides help on some potential issues you may run into and tips on how to resolve them. + +## Errors + + + + Error: Transaction dropped from the mempool or Error Transaction not completed + + Check the `tx-id` in the explorer. The tx may have went successful but the error is still in the logs. Here are the [mainnet](https://explorer.rootstock.io/) and [testnet](https://explorer.testnet.rootstock.io/) explorers. + + + + Error Failed to get EIP-1559 fees + + - EIP-1559 is not supported or not activated on the Rootstock RPC url. The `--legacy` flag is passed to use legacy transactions instead of `EIP-1559`. + + + \ No newline at end of file diff --git a/docs/02-developers/05-smart-contracts/06-eas/_category_.yml b/docs/02-developers/05-smart-contracts/06-eas/_category_.yml new file mode 100644 index 00000000..643f9338 --- /dev/null +++ b/docs/02-developers/05-smart-contracts/06-eas/_category_.yml @@ -0,0 +1,5 @@ +label: Getting Started with EAS +position: 300 +link: + type: generated-index + slug: /developers/smart-contracts/eas/ \ No newline at end of file diff --git a/docs/02-developers/05-smart-contracts/06-eas/overview.md b/docs/02-developers/05-smart-contracts/06-eas/overview.md new file mode 100644 index 00000000..c6a6c599 --- /dev/null +++ b/docs/02-developers/05-smart-contracts/06-eas/overview.md @@ -0,0 +1,72 @@ +--- +sidebar_position: 310 +title: Ethereum Attestation Service +sidebar_label: Overview +description: "Ethereum Attestation Service (EAS) is an open-source infrastructure public good for making attestations onchain or offchain. Learn how to use it on Rootstock." +tags: [rsk, rootstock, guides, EAS, Attestation, Ethereum] +--- + +[Ethereum Attestation Service (EAS)](https://attest.org/) is an open-source infrastructure public good for making attestations onchain or offchain. + +EAS is a foundational layer that empowers anyone to make attestations about anything. By creating a decentralized ledger of verifiable claims, we can revolutionize traditional finance, build decentralized reputation systems, voting mechanisms, governance frameworks, social media platforms, supply chain tracking systems, knowledge graphs, and lots more. + +## How EAS is integrated with Rootstock + +The EAS essential contracts has been successfully deployed to Rootstock, this includes a robust indexer, and a user-friendly alternative explorer. The following sections will delve into the technical details of these implementations. + +### About EAS + +EAS runs on two [smart contracts](https://docs.attest.org/docs/core--concepts/how-eas-works) +1. Registering attestation Schemas +2. Attesting the Schemas. + +:::info[Info] + +Schemas can be registered for a wide range of use cases, and attestations can be made both on-chain and off-chain. For more complex scenarios, you can incorporate a resolver contract into the Schema. This enables on-chain verification of attestation data and the ability to attach payments to attestations. +::: + +## Start Building + +### Open-Source Code + +Find the open-source repositories + +- [EAS Contracts](https://github.com/rsksmart/eas-contracts): The contracts are elegantly simple. We forked the repository adding the contracts for Rootstock Mainnet and Testnet. +- [EAS SDK](https://github.com/ethereum-attestation-service/eas-sdk): See the latest version of the SDK Library. +- [EAS Indexing Service](https://github.com/rsksmart/eas-indexing-service): See how we index attestation data. Added support for Rootstock Testnet and Mainnet. +- [EAS Explorer](https://github.com/rsksmart/EAS-devtool): Alternative Explorer UI to display attestations. + +## EAS Contracts + +Find the deployed EAS contracts on Rootstock Mainnet and Tesnet: + +### Mainnet + +* **EAS**: + * Contract: [0x54C0726E9d2D57Bc37AD52c7E219A3229e0eE963](https://explorer.rootstock.io/address/0x54c0726e9d2d57bc37ad52c7e219a3229e0ee963) +* **SchemaRegistry**: + * Contract: [0xeF29675d82CC5967069d6d9C17F2719f67728F5B](https://explorer.rootstock.io/address/0xeF29675d82CC5967069d6d9C17F2719f67728F5B) +* **EIP712Proxy**: + * Contract: [0x08cc68B734B14E7984D638eF141eC6De9Faf7d27](https://explorer.rootstock.io/address/0x08cc68B734B14E7984D638eF141eC6De9Faf7d27) +* **Indexer**: + * Contract: [0x4c0Ac010C2ec50fc1Ff3e7E35DaDA06A7F26073f](https://explorer.rootstock.io/address/0x4c0Ac010C2ec50fc1Ff3e7E35DaDA06A7F26073f) + +### Testnet + +* **EAS**: + * Contract: [0xc300aeEaDd60999933468738c9F5D7e9C0671e1c](https://explorer.testnet.rootstock.io/0xc300aeEaDd60999933468738c9F5D7e9C0671e1c) +* **SchemaRegistry**: + * Contract: [0x679c62956cD2801AbAbF80e9D430f18859Eea2d5](https://explorer.testnet.rootstock.io/0x679c62956cD2801AbAbF80e9D430f18859Eea2d5) +* **EIP712Proxy**: + * Contract: [0x91dD0c0795E22f7448bC2330aDe1020D2115cCbC](https://explorer.testnet.rootstock.io/0x91dD0c0795E22f7448bC2330aDe1020D2115cCbC) +* **Indexer**: + * Contract: [0x4352E5b2567551986E21eD65D5Ad3052a09e3717](https://explorer.testnet.rootstock.io/address/0x4352E5b2567551986E21eD65D5Ad3052a09e3717) + + +## Useful Resources +- [EAS](https://attest.org/) +- [Core Concepts](https://docs.attest.org/docs/category/core-concepts) +- [How EAS Works](https://docs.attest.org/docs/core--concepts/how-eas-works) +- [Use Cases](https://docs.attest.org/docs/quick--start/use-cases-overview)] +- [EAS Docs](https://docs.attest.org/docs/welcome) +- [EAS Github](https://github.com/ethereum-attestation-service) \ No newline at end of file diff --git a/docs/02-developers/05-smart-contracts/contract-addresses.md b/docs/02-developers/05-smart-contracts/contract-addresses.md index 146b7a95..a7e9fcd3 100644 --- a/docs/02-developers/05-smart-contracts/contract-addresses.md +++ b/docs/02-developers/05-smart-contracts/contract-addresses.md @@ -1,5 +1,5 @@ --- -sidebar_position: 250 +sidebar_position: 600 title: Rootstock Contract Addresses sidebar_label: Contract Addresses tags: [rsk, rootstock, developers, quick starts, smart contracts, contract addresses] diff --git a/docs/02-developers/05-smart-contracts/verify-address-ownership.md b/docs/02-developers/05-smart-contracts/verify-address-ownership.md index 7a3202e6..553fca96 100644 --- a/docs/02-developers/05-smart-contracts/verify-address-ownership.md +++ b/docs/02-developers/05-smart-contracts/verify-address-ownership.md @@ -1,5 +1,5 @@ --- -sidebar_position: 300 +sidebar_position: 700 sidebar_label: Verify address ownership title: 'Verify Address Ownership with Metamask Wallet' description: 'Confirm that you own an Rootstock address using RIF Identity Manager' diff --git a/docs/02-developers/07-rpc-api/01-setup.md b/docs/02-developers/07-rpc-api/02-rootstock/01-setup.md similarity index 57% rename from docs/02-developers/07-rpc-api/01-setup.md rename to docs/02-developers/07-rpc-api/02-rootstock/01-setup.md index f4e20c68..cd07b848 100644 --- a/docs/02-developers/07-rpc-api/01-setup.md +++ b/docs/02-developers/07-rpc-api/02-rootstock/01-setup.md @@ -1,58 +1,32 @@ --- -sidebar_label: Getting Started -sidebar_position: 100 -title: Getting Started with the RPC API +sidebar_label: Getting Started with the Rootstock RPC API +sidebar_position: 101 +title: Getting Started with the Rootstock RPC API tags: [faucet, Rootstock, testnet, address, wallet, tools] -description: "Easily create, interact and deploy EVM compatible smart contracts using a robust set of JSON RPC methods available through the RPC API." +description: "Get started with the Rootstock RPC Service to interact with Rootstock nodes." --- -The [RPC API](http://rpc.rootstock.io/) provides a seamless and intuitive web interface for developers to interact with [Rootstock nodes](/node-operators/setup/) via [JSON-RPC](/node-operators/json-rpc/methods/) methods. It aims to address the challenges faced by developers when trying to access critical information like logs, transactions, and balances through RPC, which can significantly impact the timely development of dApps on the Rootstock blockchain. - -In this guide, you will learn: - -- How to create an account and [make your first API call](#getting-started) -- View a list of [JSON-RPC methods](/node-operators/json-rpc/methods/) available. - - - -## Who is it for? - -* dApp Developers looking to interact with the Rootstock nodes - -## Features - -**Easy Setup:** -- Create an API key effortlessly to initiate development. -- Make the First API call in minutes. - -**API Key Authentication:** -- Provides secure authentication for decentralized applications (dApps). -- Limits API requests on a daily or monthly basis. - ## Getting Started :::info[Note] -The [RPC API](https://rpc.rootstock.io/) is available on TESTNET and MAINNET. +The [Rootstock RPC API](https://rpc.rootstock.io/) is available on TESTNET and MAINNET. ::: Visit the [Rootstock RPC API](https://rpc.rootstock.io/)
- RPC API Landing Page + RPC Service Landing Page
-### Get a FREE account +### Get A FREE Account To create an account, click on _Sign up_
- RPC API Sign Up + RPC Service Sign Up
-### Get an API Key +### Get An API Key To get an API key: @@ -68,7 +42,7 @@ Choose a name to identify your `apikey`, and the Network (either `Testnet` or `M Create API key -### Make first API Call +### Make First API Call Click on the newly created `apikey` to get the details: diff --git a/docs/02-developers/07-rpc-api/02-methods.md b/docs/02-developers/07-rpc-api/02-rootstock/02-methods.md similarity index 99% rename from docs/02-developers/07-rpc-api/02-methods.md rename to docs/02-developers/07-rpc-api/02-rootstock/02-methods.md index 8b95eeb2..cdff10a7 100644 --- a/docs/02-developers/07-rpc-api/02-methods.md +++ b/docs/02-developers/07-rpc-api/02-rootstock/02-methods.md @@ -1,17 +1,17 @@ --- -sidebar_label: RPC API Methods -sidebar_position: 200 -title: RPC API Methods +sidebar_label: Rootstock RPC API Methods +sidebar_position: 102 +title: Rootstock RPC API Methods tags: [faucet, Rootstock, rpc api, testnet, address, wallet, tools] description: "Easily create, interact and deploy EVM compatible smart contracts using a robust set of JSON RPC methods available through the RPC API." --- -Find below a list of methods available on the RPC API. See [how to setup the RPC API](/developers/rpc-api/setup/). +Find below a list of methods available on the Rootstock RPC Service. See [how to setup the Rootstock RPC Service](/developers/rpc-api/rootstock/setup/). ## eth_accounts - _Method:_ `eth_accounts` - - Returns a list of addresses owned by the client. Since Rootstock RPC API does not store keys, this will always return empty. + - Returns a list of addresses owned by the client. Since Rootstock RPC Service does not store keys, this will always return empty. - _Params:_ None ```shell @@ -294,12 +294,13 @@ curl --location 'https://rpc.testnet.rootstock.io/' \ --header 'accept: application/json' \ --header 'Content-Type: application/json' \ --data '{ -"jsonrpc":"2.0", -"method":"eth_getBalance", -"params":[ -"0x1fab9a0e24ffc209b01faa5a61ad4366982d0b7f", -"latest"], -"id":0 + "jsonrpc":"2.0", + "method":"eth_getBalance", + "params":[ + "0x1fab9a0e24ffc209b01faa5a61ad4366982d0b7f", + "0x6444bb" + ], + "id":0 }' ``` diff --git a/docs/02-developers/07-rpc-api/02-rootstock/index.md b/docs/02-developers/07-rpc-api/02-rootstock/index.md new file mode 100644 index 00000000..129a4031 --- /dev/null +++ b/docs/02-developers/07-rpc-api/02-rootstock/index.md @@ -0,0 +1,33 @@ +--- +sidebar_label: Rootstock RPC API +sidebar_position: 100 +title: Rootstock RPC API +tags: [faucet, Rootstock, testnet, address, wallet, tools] +description: "Get started with the RPC API service to interact with Rootstock nodes." +--- + +The [Rootstock RPC API](https://rpc.rootstock.io/) provides a seamless and intuitive web interface for developers to interact with [Rootstock nodes](/node-operators/setup/) via [JSON-RPC](/developers/rpc-api/rootstock/methods/) methods. It aims to address the challenges faced by developers when trying to access critical information like logs, transactions, and balances through RPC, which can significantly impact the timely development of dApps on the Rootstock blockchain. + +In this guide, you will learn: + +- How to create an account and [make your first API call](/developers/rpc-api/rootstock/setup/) +- View a list of [JSON-RPC methods](/developers/rpc-api/rootstock/methods/) available on the Rootstock RPC Service. + + + +## Who Is It For? + +* dApp Developers looking to interact with the Rootstock nodes + +## Features + +**Easy Setup:** +- Create an API key effortlessly to initiate development. +- Make the First API call in minutes. + +**API Key Authentication:** +- Provides secure authentication for decentralized applications (dApps). +- Limits API requests on a daily or monthly basis. \ No newline at end of file diff --git a/docs/02-developers/07-rpc-api/03-alchemy/index.md b/docs/02-developers/07-rpc-api/03-alchemy/index.md new file mode 100644 index 00000000..5bed1038 --- /dev/null +++ b/docs/02-developers/07-rpc-api/03-alchemy/index.md @@ -0,0 +1,135 @@ +--- +sidebar_label: Rootstock - Alchemy RPC Provider +sidebar_position: 300 +title: Rootstock - Alchemy RPC Provider +description: 'Guide to interacting with the Rootstock network using Alchemy.' +tags: [rsk, rootstock, tutorials, developers, alchemy, quick starts, dApps, smart contracts, rpc] +--- + +A step-to-step guide for developers to interact with Rootstock network with the [Alchemy RPC Provider](https://www.alchemy.com/). + +It aims to address the challenges faced by developers when trying to access critical information like logs, transactions, and balances through RPC, which can significantly impact the timely development of dApps on the Rootstock blockchain. + +In this guide you will learn: +- How to create an **Alchemy** project to make your first API call. +- View some options to interact with the node RPC with the **Alchemy** sdk and tools. + +## Prerequisites + +Before you start this guide, make sure you have the following: + +- Basic understanding of smart contracts and how to interact with them on the Rootstock blockchain. +- Familiarity with Ethereum-based dApp development can be helpful. +- Ensure you have a development environment set up for interacting with blockchain nodes. +- Basic programming knowledge of ***JavaScript***, ***Python***, or other supported languages to make `API calls`. And familiarity with making ***HTTP*** requests and handling ***JSON*** responses. + +## Who Is It For? +- Developers looking to interact with the Rootstock nodes. + +## Features + +### Easy Setup +- Create an API key effortlessly to initiate development. +- Make your first API call in minutes. + +### API Key Authentication +- Provides secure authentication for decentralized applications (dApps). +- Limits API requests on a daily or monthly basis. + +## Getting Started + +To access the **Alchemy** tools, visit its [Dashboard Portal](https://www.alchemy.com/). If you don't already have an account, you can sign up for free. And then, simply log in to get started. + +### Step 1: Create New App +After logging in, you'll be directed to the main dashboard. From there, you have different options for interacting with **Alchemy** tools. + +![Alchemy - Create New App](/img/developers/quickstart/1-alchemy.png) + +Click the option `Create new app`, where you'll be prompted to provide the ***app's name***, ***description***, and specify its intended ***use case***. + +- **Name:** This is your app's unique identifier. Choose a meaningful and descriptive name to help you easily recognize the app in your dashboard. This name will appear throughout the platform and may be used in API references. +- **Description (Optional):** Provide additional information about the app's purpose or functionality. While this field is optional, it's a good practice to include a brief description to help you or your team members understand the app's role or features, especially when managing multiple apps. +- **Use Case:** Specify how you plan to use the app. **Alchemy** provides options such as ***Defi***, ***Analytics***, ***Gaming***, ***Wallet***, among others. Choosing the correct use case helps configure the app properly for its intended environment, ensuring it performs optimally for development, testing, or live deployment. + +![Alchemy - App Props](/img/developers/quickstart/2-alchemy.png) + +### Step 2: Choose Chains +After clicking `Next`, you'll be prompted to select the network for your dApp. In the Search field, type ***Rootstock***, then click on the Rootstock node. Once selected, click the `Next` button to proceed. + +![Alchemy - Choose Chain](/img/developers/quickstart/3-alchemy.png) + +### Step 3: Activate Services +The next screen will display the services available for the Rootstock network, including ***NODE API***. Click on Create app to complete the setup. + +![Alchemy - Activate Services](/img/developers/quickstart/4-alchemy.png) + + Your app information will now be visible, similar to the example shown. + +![Alchemy - App information](/img/developers/quickstart/5-alchemy.png) + +#### Set Up Tab +In the `Setup` tab you will see different options for using the rpc node, depending on the ***Method***, ***Language*** and ***SDK*** you need to use for it. + +By default, the dashboard shows an example for the `get latest block` call on `Javascript` and `Viem`. + +```javascript +import { createPublicClient, http } from "viem"; +import { rootstock } from "viem/chains"; + +const client = createPublicClient({ + chain: rootstock, + transport: http("https://rootstock-mainnet.g.alchemy.com/v2/"), +}); + +const block = await client.getBlock({ + blockNumber: 123456n, +}); + +console.log(block); +``` + +However, you will have different language options available for the rpc call, included `CLI` (command line interface). + +#### Language Options +- **CLI (Command Line Interface):** No SDK options are available with this choice. +- **JavaScript:** You can choose from ***Viem***, ***Ethers.js***, or ***Fetch*** as your SDK options. +- **TypeScript:** Only the ***Viem*** SDK option is available for selection. +- **Python:** You can select ***web3.py*** as the SDK option. + +Is it possible to test the CLI option easily in your console by pasting the following code: + +```bash +curl -X POST https://rootstock-mainnet.g.alchemy.com/v2/\ +-H "Content-Type: application/json" \ +-d '{ + "jsonrpc": "2.0", + "method": "eth_getBlockByNumber", + "params": ["latest", false], + "id": 1 +}' +``` + +And the response should look like this: +```json +{"jsonrpc":"2.0","id":1,"result":{"number":"0x67a9c4","hash":"0xe3d0d2b47eb0a06f04cea614355a6ba10935c62596e188e3d27dcafb7ddc746f","parentHash":"0x140a94c77bc08077133d874405252b4463bcbfe500cc7a9e48f4626cdfd91104","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","logsBloom":"0x00000000000000000000101000000000000080000040000000000000000000000020400000010000000000000000001000002000000000000008800000000000000000000000000000000000000008000000000000000001000000000000000000000000000000000040000000000000000000000000000000000000020000000001000000000081000000000004000000000000000000000000000020000000000000000200100020000000000000000180000000000080001000020000000000000001000000000000000000008000000030000000000000200000100000000000000000000000002004000880000000000400000000000000200010000200" … +``` + +#### Metrics Tab +In this tab, you can see the analytics for your app, with the success rates and total requests. + +![Alchemy - Metrics Tab](/img/developers/quickstart/6-alchemy.png) + +#### Networks Tab +In this tab, you will find the Rootstock card, where you can copy the RPC url you will use in your dApp (mainnet or testnet). + +![Alchemy - Networks Tab](/img/developers/quickstart/7-alchemy.png) + +#### Settings Tab +In this tab you find different configuration options of your app, like advanced config, allow list, JWT keys, or delete your app from the **Alchemy** dashboard. + +## Conclusion +The use of RPC API is an important part of the frontend and backend interaction with the blockchain. Alchemy is a poweful platform which contains a lot of tools that can be used for developers to create their code faster. + +## Useful Links +- [Alchemy Dashboard](https://www.alchemy.com/) +- [Rootstock RPC API Service](/developers/smart-contracts/foundry/) \ No newline at end of file diff --git a/docs/02-developers/07-rpc-api/_category_.yml b/docs/02-developers/07-rpc-api/_category_.yml index c29f80e6..f43799ed 100644 --- a/docs/02-developers/07-rpc-api/_category_.yml +++ b/docs/02-developers/07-rpc-api/_category_.yml @@ -1,5 +1,7 @@ + label: RPC API position: 5 link: type: generated-index - slug: /developers/rpc-api/ \ No newline at end of file + slug: /developers/rpc-api/ + description: "RPC API services for interacting with Rootstock network." \ No newline at end of file diff --git a/docs/02-developers/08-libraries/bitcoin-tx-solidity-helper.md b/docs/02-developers/08-libraries/bitcoin-tx-solidity-helper.md new file mode 100644 index 00000000..2194b073 --- /dev/null +++ b/docs/02-developers/08-libraries/bitcoin-tx-solidity-helper.md @@ -0,0 +1,168 @@ +--- +title: How to Handle Bitcoin Transactions in Solidity +tags: [rif, rootstock, solidity, bitcoin, smart contracts, libraries, bitcoin transactions] +sidebar_label: Bitcoin Transaction Solidity Helper Library +sidebar_position: 300 +description: "This guide demonstrates to a developer how to handle Bitcoin transactions in a Solidity Smart contract, we will also learn how to parse transactions, hash transactions and validate scripts for bitcoin transactions" +--- + +Bitcoin, a decentralized digital currency, serves as both a store of value and a means of transferring wealth. Its security is rooted in the blockchain, a distributed ledger maintained by a network of miners. These miners expend significant computational power and energy to create new blocks, which are added to the blockchain every 10 minutes. The more hashing power contributed by miners, the more secure the network becomes. [Learn more about Bitcoin](https://developer.bitcoin.org/index.html). + +Rootstock, the pioneering open-source smart contract platform built on Bitcoin, aims to enhance the Bitcoin ecosystem by introducing smart contract functionality, near-instant payments, and improved scalability. Its comprehensive technology stack, encompassing Rootstock smart contracts and the Rootstock Infrastructure Framework, is designed to foster a more equitable and inclusive financial system. Read more about the [Rootstock Stack](/concepts/fundamentals/stack/). + +The [Bitcoin Solidity helper library](https://github.com/rsksmart/btc-transaction-solidity-helper) facilitates seamless interaction between Bitcoin transactions and Solidity smart contracts on the Rootstock platform. In this guide, we will learn how to handle Bitcoin transactions in a Solidity Smart contract, we will also learn how to parse transactions, hash transactions and validate scripts for bitcoin transactions. You can find the public repository for the [bitcoin transaction solidity helper library](https://github.com/rsksmart/btc-transaction-solidity-helper). + +## Features of the Library + +The features of the Bitcoin Solidity Helper library include: +1. Bitcoin transaction output parsing: This accurately extracts and organizes transaction outputs from raw Bitcoin transactions. It is able to receive a raw tx and return an array of structures with the tx outputs. +2. Bitcoin transaction hashing: This calculates the cryptographic hash of a Bitcoin transaction, ensuring its authenticity and integrity. It receives a raw tx and returns its hash. +3. Bitcoin transaction output script validation: This verifies the validity and type of output scripts within a Bitcoin transaction, allowing for specific data extraction. It receives a raw output script, validates that it is from a specific type and returns a result. E.g. receive a raw null-data script and return the embedded data in it +4. Bitcoin address generation: is able to generate Bitcoin the address from a specific script and also to validate if a given address was generated from a script or not. +5. Bitcoin address validation: This checks if a Bitcoin address conforms to a particular type or format. It validates if a Bitcoin address is of a given type or not. + +## Prerequisites +* Knowledge of Solidity and how to write smart contracts. +* [Bitcoin Solidity Helper Package](https://github.com/rsksmart/btc-transaction-solidity-helper/pkgs/npm/btc-transaction-solidity-helper) + +## Setup +To setup the Solidity helper library in your project, run the following npm command: + +```bash + npm install @rsksmart/btc-transaction-solidity-helper +``` + +## Usage + +### Import the library: + +```bash +import "@rsksmart/btc-transaction-solidity-helper/contracts/BtcUtils.sol"; +``` + +### Using the library: + +```bash +BtcUtils.TxRawOutput[] memory outputs = BtcUtils.getOutputs(btcTx); +bytes memory scriptData = BtcUtils.parseNullDataScript(outputs[0].pkScript); +``` + +_This fragment parses a raw Bitcoin transaction to extract its outputs and then parses the first output to get the data of the null data script._ + +## Parsing a Bitcoin Transaction Output +All the bitcoin transactions have a specific format when they are serialized. By having knowledge of this format, we can process a raw transaction in order to extract the information about its outputs. + +A raw transaction has the following top-level format: + +| Bytes | Name | Data Type | Description | +| --- | --- | --- | --- | +| 4 | Version | `int32_t` | [Transaction version number](https://developer.bitcoin.org/terms.html#term-transaction-version-number) (note, this is signed); currently version 1 or 2. Programs creating transactions using newer consensus rules may use higher version numbers. Version 2 means that [BIP68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki#specification) applies. | +| Varies | tx_in count | compactSize uint | Number of inputs in this transaction. | +| Varies | tx_in | txIn | Transaction inputs. See description of txIn below. | +| Varies | tx_out count | compactSize uint | Number of outputs in this transaction. | +| Varies | tx_out | txOut | Transaction outputs. See description of txOut below. | +| 4 | lock_time | `uint32_t` | A time ([Unix epoch time](https://en.wikipedia.org/wiki/Unix_time)) or block number. See the [locktime parsing rules](https://developer.bitcoin.org/devguide/transactions.html#locktime_parsing_rules). | + + +> See the [Reference Implementation](https://developer.bitcoin.org/reference/transactions.html#raw-transaction-format) + +The approach that the library takes is to calculate, based on the length of each section, where does the output part start. After this, it starts parsing each output separately and adding its script and value into a solidity data structure. + +| Bytes | Name | Data Type | Description | +| --- | --- | --- | --- | +| 8 | Value | `int64_t` | Number of satoshis to spend. May be zero; the sum of all outputs may not exceed the sum of satoshis previously spent to the outpoints provided in the input section. (Exception: coinbase transactions spend the block subsidy and collect transaction fees.) | +| 1+ | pk_script bytes | compactSize uint | Number of bytes in the pubkey script. Maximum is 10,000 bytes. | +| 1+ | pk_script | `char[]` | Defines the conditions which must be satisfied to spend this output. | + +> See the [Reference Implementation](https://developer.bitcoin.org/reference/transactions.html#txout-a-transaction-output) + +```solidity +struct TxRawOutput { + uint64 value; + bytes pkScript; + uint256 scriptSize; + uint256 totalSize; + } +``` + +After finishing the processing of each output, the library returns an ordered output array, so the user can take advantage of this information in its solidity contract. + +In order to show the benefits of this library, we’ll use the example of the [Flyover Protocol](/developers/integrate/flyover/). In this protocol, there is a smart contract that one party uses to claim a refund, in order to claim this refund, they need to prove that there was a payment with a specific amount done to a specific address in the Bitcoin Network, in order to do this, the smart contract receives the Bitcoin raw transaction. Since making this validation is not a trivial process, as it requires to parse the whole transaction, here is where we can see the utility of the library. + +The usage of the output parsing functionality is the following: +```solidity +BtcUtils.TxRawOutput[] memory outputs = BtcUtils.getOutputs(btcTx); +``` + +Then the user is able to perform any validation: +```solidity +require(expectedValue <= outputs[0].value, "incorrect amount"); +``` + +:::info[Info] +The value field of the output structure is in satoshis. +::: + +## Hashing Transactions +The hash algorithm used in the Bitcoin Network is just the `SHA256(SHA256())` of the serialized transaction. The library exposes one function that will apply this hash algorithm to any byte array passed to it, making it easy to calculate the transaction id of any raw transaction present in the contract. + +This function is specifically useful to interact with the [rootstock native bridge](/concepts/powpeg/), as many of its functions have a transaction id as parameter. For example, by using the transaction hash function, it is easy to know how many confirmations a Bitcoin block has inside a smart contract function. + +### Example code with explanation +Based on the example stated in the previous section, after validating that a specific transaction has an output paying a certain amount to an address. We need to know if that transaction has enough confirmations: + +Here's an example: + +```solidity +BtcUtils.TxRawOutput[] memory outputs = BtcUtils.getOutputs(btcTx); +require(expectedValue <= outputs[0].value, "incorrect amount"); +bytes32 txId = BtcUtils.hashBtcTx(btcTx) +// assuming btcBlockHeaderHash,partialMerkleTree, merkleBranchHashes +// were provided in the function parameters +uint confirmations = bridge.getBtcTransactionConfirmations( + txId, + btcBlockHeaderHash, + partialMerkleTree, + merkleBranchHashes + ) +require(confirmations > expectedConfirmations, "not enough confirmations"); +``` + +Read more about the [bridge functionality](https://github.com/rsksmart/rskj/blob/master/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java) + +## Script Validation for Bitcoin Transaction Output +In the Bitcoin network, when a user wants to send funds to another, the user creates a transaction and adds an output with the value that it wants to send. The other user doesn’t β€œreceive” this amount directly, instead, we call receiving to the ability of providing the proper input to the output script so it returns `true`: + + + A transaction is valid if nothing in the combined script triggers failure and the top stack item is True (non-zero) when the script exits. Read more info in [Bitcoin Script](https://en.bitcoin.it/wiki/Script) + + +> By having knowledge of the structure of the outputs that each type of address has, we can process and validate any arbitrary output extracted with the functions explained in the previous sections. In the same way, we can parse those outputs to obtain the specific value that later is encoded (in base58check, bech32 or bech32m) and presented as the β€œdestination address”. + +The output that the library supports and is able to parse to an address are: +* P2PKH (Pay to public key hash) +* P2SH (Pay to script hash) +* P2WPKH (Pay to witness public key hash) +* P2WSH (Pay to witness script hash) +* P2TR (Pay to taproot) + +**Some use cases for script validation:** + +As seen in the previous example, we validated inside our smart contract that a Bitcoin transaction has the correct amount and enough confirmations, now we need to validate that it was performed on the correct address. To do this, the library has the capability of parsing an arbitrary output and converting it into an address. + +Here's an example: + +```solidity +bytes memory btcTxDestination = BtcUtils.outputScriptToAddress( + outputs[0].pkScript, + mainnetFlag + ); + require(keccak256(expectedAddress) == keccak256(btcTxDestination), "incorrect address"); +``` + +## Conclusion +Congratulations, we have successfully learnt how to use the Solidity Helper library to parse, hash, and validate scripts within Bitcoin transactions. By using this library, developers can gain valuable insights into Bitcoin transaction data and build more sophisticated smart contract dApps on Rootstock. + +**Some future enhancements to the library includes:** +* Transaction Input Parsing: The ability to extract and analyze transaction input data to receive a raw tx and return an array of structs with the tx inputs. +* Transaction Creation: Utilities to facilitate the creation of raw Bitcoin transactions within smart contracts. diff --git a/docs/02-developers/index.md b/docs/02-developers/index.md index 39703967..73050887 100644 --- a/docs/02-developers/index.md +++ b/docs/02-developers/index.md @@ -11,7 +11,7 @@ Welcome to the Rootstock Developers Overview section. This section enables developers getting started with the Rootstock blockchain. Developers can install a local development environment using Hardhat, etc, create and test contracts with the libraries provided and use the libraries to build decentralized applications :::info[Info] -* Looking to quickly test your dApp on testnet before deploying to mainnet? Use the [RPC API](https://rpc.rootstock.io/) or view the [json-rpc methods](/developers/rpc-api/methods/) available on the RPC API. +* Looking to quickly test your dApp on testnet before deploying to mainnet? Use the [Rootstock RPC API](https://rpc.rootstock.io/) or view the [json-rpc methods](/developers/rpc-api/rootstock/methods/) available on the RPC API. * Dive right in with [step-by-step guides](/developers/quickstart/) to get your development environment set up and deploy your first dApp. ::: @@ -24,7 +24,7 @@ This section enables developers getting started with the Rootstock blockchain. D | [Quick Starts](/developers/quickstart/) | Dive right in with step-by-step guides to get your development environment set up and deploy your first dApp.| | [Smart Contract Development](/developers/smart-contracts/) | Explore in-depth resources on building secure and scalable smart contracts on Rootstock.| | [Integration Guides](/developers/integrate/) | Deepen your knowledge with detailed guides and informative tutorials that cover various aspects of Rootstock development.| -| [JSON-RPC](/developers/rpc-api/setup/) | Test your dApps on testnet in minutes before deploying to mainnet using the RPC API.| +| [JSON-RPC](/developers/rpc-api/) | Test your dApps on testnet in minutes before deploying to mainnet using RPC API providers on Rootstock.| | [Libraries](/developers/libraries/) | Access essential tools and libraries to streamline your development process. | diff --git a/docs/03-node-operators/04-setup/03-configuration/03-reference.md b/docs/03-node-operators/04-setup/03-configuration/03-reference.md index ed19471c..86a5ec88 100644 --- a/docs/03-node-operators/04-setup/03-configuration/03-reference.md +++ b/docs/03-node-operators/04-setup/03-configuration/03-reference.md @@ -37,6 +37,7 @@ The following detail the most commonly used configuration fields parsed by RSKj. - [`wallet`](#wallet) - [`scoring`](#scoring) - [`miner`](#miner) +- [`miner.stableGasPrice`](#minerstablegasprice) - [`blockchain.config.name`](#blockchainconfigname) - [`bind_address`](#bind_address) - [`public.ip`](#publicip) @@ -347,9 +348,60 @@ scoring { Check out [Configure RSKj node for mining](/node-operators/merged-mining/configure-mining) for detailed information about the `miner` configuration. +## miner.stableGasPrice + +The `stableGasPrice` feature allows miners to set a predictable gas price for transactions, establishing a minimum rate that is less affected by market volatility and better aligned with fiat currency values like USD or EUR. This enhances cost management and improves overall transaction efficiency. + +The source configuration supports two methods: `ETH_CALL` and `HTTP_GET`. + +- **ETH_CALL**: This method retrieves the gas price directly from a specified smart contract, allowing for real-time adjustments based on the contract's logic. +- **HTTP_GET**: This method fetches gas price data from an external API, providing flexibility to pull market data from trusted sources. + +**Example of ETH_CALL** +```plaintext +stableGasPrice { + enabled = true + + source { + method = "ETH_CALL" + params { + from = "0x0000000000000000000000000000000000000000" + to = "0xCA41630b09048b6f576459C34341cAB8Dc2cBE7E" + data = "0xdf16e52d" + } + } + + minStableGasPrice = 476190000000 # Minimum gas price + refreshRate = 6 hours # How often to check for updates +} +``` + +- **Source**: Retrieves the gas price from a specific smart contract +- **Minimum Gas Price**: Ensures the miner uses a baseline price to avoid setting it too low +- **Refresh Rate**: Updates the gas price + +**Example of HTTP_GET** +```plaintext +stableGasPrice { + enabled = true + + source { + method = "HTTP_GET" + params { + url = "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd" + jsonPath = "/bitcoin/usd" + timeout = 5 seconds + } + } + + minStableGasPrice = 476190000000 # Minimum gas price + refreshRate = 6 hours # How often to check for updates +} +``` + ## blockchain.config.name -A string that describe the name of the configuration. +A string that describes the name of the configuration. We use: | | `blockchain.config.name` | diff --git a/docs/03-node-operators/08-public-nodes/index.md b/docs/03-node-operators/08-public-nodes/index.md index a62458ea..4caaafbd 100644 --- a/docs/03-node-operators/08-public-nodes/index.md +++ b/docs/03-node-operators/08-public-nodes/index.md @@ -16,7 +16,7 @@ and in accordance with the bitcoiners' maxim: **Don't trust. Verify.** :::info[RPC Node Providers] The Rootstock public nodes do not expose WebSockets, they are `HTTP` only. -To work around this, you may either [run your own Rootstock node](/node-operators/setup/node-runner/), or use the [Rootstock RPC API](/developers/rpc-api/setup/) or use a third-party node provider, such as [Getblock](https://getblock.io/nodes/rsk/), [NowNodes](https://nownodes.io/nodes/rsk) or [dRPC](https://drpc.org/chainlist/rootstock?utm_source=docs&utm_medium=rootstock). +To work around this, you may either [run your own Rootstock node](/node-operators/setup/node-runner/), or use the [Rootstock RPC API](/developers/rpc-api/rootstock/setup/) or use a third-party node provider, such as [Getblock](https://getblock.io/nodes/rsk/), [NowNodes](https://nownodes.io/nodes/rsk) or [dRPC](https://drpc.org/chainlist/rootstock?utm_source=docs&utm_medium=rootstock). ::: ## Testnet diff --git a/docs/04-resources/02-contribute/index.md b/docs/04-resources/02-contribute/index.md index 75dbcb92..0be67737 100644 --- a/docs/04-resources/02-contribute/index.md +++ b/docs/04-resources/02-contribute/index.md @@ -8,7 +8,7 @@ tags: [rootstock, rsk, contribute, open source] Are you passionate about web3, bitcoin and the Blockchain? Do you have a passion for Open Source and Web3? Do you enjoy writing, coding, bounty hunting, solving real-world problems, and eager to contribute to the future of Bitcoin and Decentralized Finance? Join the [Rootstock Discord Community](https://rootstock.io/discord) and start making contributions! -## Who is it for? +## Who Is It For? Whether you're a seasoned developer, creative writer, researcher, bug bounty hunter, or simply enthusiastic about blockchain, the program welcomes contributors from all backgrounds. diff --git a/docs/04-resources/04-tutorials/index.md b/docs/04-resources/04-tutorials/index.md index 13d4c71d..b203f128 100644 --- a/docs/04-resources/04-tutorials/index.md +++ b/docs/04-resources/04-tutorials/index.md @@ -21,6 +21,14 @@ linkHref="/resources/tutorials/rootstock-rust/" description="Rust is extensively getting used on backend side of many defi applications, dApps, developer tools, indexers and bridges. This guide will help developers to start using Rust on Rootstock blockchain." /> + See how to [Get an API Key from the RPC API](/developers/rpc-api/setup/) +> See how to [Get an API Key from the RPC API](/developers/rpc-api/rootstock/setup/) See full configuration on [GitHub](https://github.com/rsksmart/demo-code-snippets/blob/5cc5124fe5bddc85f09a82e49eba7591003543f0/switch-network-to-rsk/networks.js). diff --git a/docs/04-resources/04-tutorials/rootstock-rust.md b/docs/04-resources/04-tutorials/rootstock-rust.md index bea9c04c..e87cf7e4 100644 --- a/docs/04-resources/04-tutorials/rootstock-rust.md +++ b/docs/04-resources/04-tutorials/rootstock-rust.md @@ -85,7 +85,7 @@ Next, update the `rootstock-rs/src/main.rs` file with the program below: :::info[Info] -Replace `API_KEY` with your RPC API Key. To get an API_KEY, see the [RPC Docs](/developers/rpc-api/setup/). +Replace `API_KEY` with your RPC API Key. To get an API_KEY, see the [RPC Docs](/developers/rpc-api/rootstock/setup/). ::: @@ -190,7 +190,7 @@ async fn main() -> eyre::Result<()> { :::info[Info] -Replace `API_KEY` with your RPC API Key. To get an API_KEY, see the [RPC Docs](/developers/rpc-api/setup/). Also replace RIF Testnet contract addresses with your own address as you would be required to use a private key later. +Replace `API_KEY` with your RPC API Key. To get an API_KEY, see the [RPC Docs](/developers/rpc-api/rootstock/setup/). Also replace RIF Testnet contract addresses with your own address as you would be required to use a private key later. ::: diff --git a/docs/04-resources/06-guides/powpeg-app/faqs.md b/docs/04-resources/06-guides/powpeg-app/faqs.md index cd362582..07dfd5fd 100644 --- a/docs/04-resources/06-guides/powpeg-app/faqs.md +++ b/docs/04-resources/06-guides/powpeg-app/faqs.md @@ -68,36 +68,49 @@ Here, you can find a list of frequently asked questions (FAQs) about the PowPeg > - ![Read popup info](/img/resources/powpeg/pegin-popup.png) - - 10. How long does it take for a native pegout transaction to complete? + + 10. How long does it take for a pegin transaction to complete using the PowPeg (FAST MODE) option? - > - native pegin needs 34 hours to be completed - > - ![Read popup info](/img/resources/powpeg/pegin-popup.png) + > - Using fast mode, pegin time has been significantly reduced to ~20 mins. + > Note: In Fast Mode, we utilize Liquidity Providers (LPs) to expedite the transfer of funds to end users. These third-party providers can set their own transfer times. This information is displayed on the screen, allowing users to select the LP that offers the most suitable transfer speed for their needs. - 11. What are the min and max for pegin transaction? + 11. How long does it take for a native pegout transaction to complete? + + > - native pegout needs 34 hours to be completed + + + + 12. How long does it take for a pegout transaction to complete using the PowPeg (FAST MODE) option? + + > - Using fast mode, pegout time has been significantly reduced to ~20 mins. + > Note: In Fast Mode, we utilize Liquidity Providers (LPs) to expedite the transfer of funds to end users. These third-party providers can set their own transfer times. This information is displayed on the screen, allowing users to select the LP that offers the most suitable transfer speed for their needs. + + + + 13. What are the min and max for pegin transaction? > - The minimum values allowed when creating a peg-in transaction is 0.005 BTC. > - The maximum values allowed when creating a peg-in transaction is 10 BTC. - - 12. What are the min and max for pegout transaction? + + 14. What are the min and max for pegout transaction? - > - The minimum values allowed when creating a peg-in transaction is 0.004 RBTC. - > - The maximum values allowed when creating a peg-in transaction is 10 RBTC. + > - The minimum values allowed when creating a peg-out transaction is 0.004 RBTC. + > - The maximum values allowed when creating a peg-out transaction is 10 RBTC. - - 13.After making a native pegout, to which address will I receive my BTCs? + + 15.After making a native pegout, to which address will I receive my BTCs? > - During the pegout process, the destination address of your BTC is derived from your signature, this enables one to know which address will receive the BTCs. > - See the [Derivation details page](/resources/guides/powpeg-app/pegout/deriving-electrum/) - - 14.When using **Trezor** i'm receiving the error **Forbidden key path** ? + + 16.When using **Trezor** i'm receiving the error **Forbidden key path** ? > - The latest versions of Trezor Suite have implemented a security rule to disable its use with non-standard key paths. Therefore, the user must explicitly set **Perform Safety Checks** to **PROMPT** option in **Trezor Suite** in order to use the **Trezor wallet** in the PowPeg application. > - If is not enabled you will receive this error ![Trezor Error Key Path](/img/resources/powpeg/trezor-error.png) diff --git a/docs/04-resources/06-guides/powpeg-app/pegin/ledger.md b/docs/04-resources/06-guides/powpeg-app/pegin/ledger.md index c196553a..1c1f66b8 100644 --- a/docs/04-resources/06-guides/powpeg-app/pegin/ledger.md +++ b/docs/04-resources/06-guides/powpeg-app/pegin/ledger.md @@ -72,6 +72,8 @@ Here, we are using the ledger hardware wallet to interact with the PowPeg. Selec The pop up shown in the image below describes the duration of the peg-in process which requires at least 100 confirmations on the Bitcoin network, this gives an estimate of around 17 hours in total. It also describes the three main steps involved which is; connecting to the hardware wallet, sending a signed transaction to the BTC network until the corresponding RBTC value is made available in the destination wallet and a receipt for this transaction. +> Note: Using fast mode, pegin time has been significantly reduced to ~20 mins. + ![Read popup info](/img/resources/powpeg/pegin-popup.png) > Click the checkbox - β€œDon’t show again” to turn off this pop-up in the future or close temporarily. diff --git a/docs/04-resources/06-guides/powpeg-app/pegin/trezor.md b/docs/04-resources/06-guides/powpeg-app/pegin/trezor.md index fba72991..2dd23ff8 100644 --- a/docs/04-resources/06-guides/powpeg-app/pegin/trezor.md +++ b/docs/04-resources/06-guides/powpeg-app/pegin/trezor.md @@ -31,6 +31,8 @@ In this guide, we will be performing a peg in transaction using the [PowPeg App] The pop up shown in the image below describes the duration of the peg-in process which requires at least 100 confirmations on the Bitcoin network, this gives an estimate of around 17 hours in total. It also describes the three main steps involved which is; connecting to the hardware wallet, sending a signed transaction to the BTC network until the corresponding RBTC value is made available in the destination wallet and a receipt for this transaction. +> Note: Using fast mode, pegin time has been significantly reduced to ~20 mins. + ![Connect Trezor](/img/resources/powpeg/pegin-popup.png) **Step 1: Connecting to a trezor wallet** diff --git a/docs/04-resources/07-hackathon/index.md b/docs/04-resources/07-hackathon/index.md index 70947d35..56bf0744 100644 --- a/docs/04-resources/07-hackathon/index.md +++ b/docs/04-resources/07-hackathon/index.md @@ -6,15 +6,96 @@ tags: [hackathons, rsk, workshop, resources, rootstock] description: "Hackathon resources and tools" --- -This guide details the necessary hardware and software requirements for developing on the Rootstock blockchain. It includes setup instructions for essential tools such as Java, Node.js, Hardhat, and RSKj, ensuring developers have a clear path to prepare their environment for Rootstock projects, whether for local development, testing, or deployment. For IRL hackathons and events, download the [Hackathon Cheatsheet PDF with QR Codes](/rootstock-cheatsheet.pdf). +This guide details the necessary hardware and software requirements for developing on the Rootstock blockchain. - +It includes setup instructions for essential tools such as Java, Node.js, Hardhat, and RSKj, ensuring developers have a clear path to prepare their environment for Rootstock projects, whether for local development, testing, or deployment. + +For IRL hackathons and events, download the [Hackathon Cheatsheet PDF with QR Codes](/rootstock-cheatsheet.pdf). + + + + + +## Prerequisites + +This guide is designed to help both beginners and experienced developers get started with building on Rootstock. The content is organized to help you find what you need based on your skill level. + + + + +

If you're new to blockchain development, start here! We've outlined the essential skills and tools you'll need to begin your journey.

+ +
    +
  1. + Basic Programming Knowledge
    + Familiarity with programming languages like JavaScript or Python will be helpful, even if you're new to blockchain development. +
  2. +
  3. + Understanding Blockchain Basics
    + Learn about blockchain technology, smart contracts, and dApps before diving in. We recommend starting with introductory resources on blockchain concepts. +
  4. +
  5. + Intro to Web3 Development Tools
    + While not strictly necessary to start, getting a basic understanding of tools like Remix IDE for smart contract development will make your journey smoother. We have beginner-friendly tutorials available here. +
  6. +
  7. + Version Control with Git (Optional)
    + Learning basic Git and GitHub skills can help you manage projects and collaborate with others. +
  8. +
+

Start building your first dApp using hardhat Quickstart Guide for Beginners.

+
+ + + +

If you already have a background in blockchain or Web3 development, you can dive straight into more advanced topics and leverage the tools available on Rootstock.

+ +
    +
  1. + Knowledge of Blockchain and Smart Contracts
    + You should be comfortable with [blockchain principles](https://rsk.thinkific.com/courses/blockchain-developer) and decentralized networks. +
  2. +
  3. + Experience with Web3 Development Tools
    + Tools like Hardhat, Web3.js, and Remix IDE should be part of your existing toolkit. +
  4. +
  5. + Basic Programming Skills
    + Proficiency in Solidity and other Web3-related programming languages (like JavaScript/React or Python/Web3.py) will be beneficial. +
  6. +
  7. + Familiarity with ERC Standards
    + Understanding ERC20, ERC721, and ERC1155 standards for token contracts will be valuable. +
  8. +
  9. + Advanced Topics (Optional)
    + Knowledge of account abstraction, automation frameworks like Cucumber, and other advanced Web3 concepts can help you explore more sophisticated solutions. +
  10. +
+ +

Access our [Guide for Experienced Developers](/developers/quickstart/) to get started.

+
+
+ + +## Tools to Speed Up Your Development + +These tools will make it easy for you to build on Rootstock: + +- **[Remix IDE](/developers/quickstart/remix/)**: An integrated development environment tailored for smart contract development. +- **[Hardhat](/developers/quickstart/hardhat/)**: A flexible development environment for building and deploying smart contracts. +- **[Web3.py](/developers/quickstart/web3-python/)**: JavaScript and Python libraries for interacting with the Ethereum blockchain. +- **[Rootstock Explorer](https://explorer.testnet.rootstock.io/)**: A blockchain explorer to view transaction details on the Rootstock network. +- **[RPC API](/developers/rpc-api/)**: The RPC API provides a seamless and intuitive web interface for developers to interact with Rootstock nodes via JSON-RPC methods. + +Explore the [full list of tools and libraries](/dev-tools/) available on Rootstock. + +:::tip[Prerequisites page] + +For more information on specific requirements for developing on Rootstock, Visit the [Prerequisites page](/developers/requirements/) page. + +::: -


- +## Starter Kits + +| Quickstart Kits/Sections | Description | Prerequisites | Action | +|---------------------------------------------------------------|---------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------|----------------------------| +| **Wagmi Starter Kit** | This starter kit provides a foundation for building decentralized applications (dApps) on the Rootstock blockchain using React, Wagmi, and Shadcn libraries. | Basic understanding of React and Web3.js | [Use the Kit](https://dev.rootstock.io/developers/quickstart/wagmi/) | +| **Hardhat Starter Kit** | Smart Contract examples, Tests, Deployments, and Tasks for Common ERC Standards (ERC20, ERC721, ERC1155).| Familiarity with Hardhat, Solidity, and ERC standards | [Use the Kit](https://dev.rootstock.io/developers/quickstart/hardhat/) | +| **Account Abstraction Kit** | Account Abstraction Starter dApp using Etherspot. | Knowledge of account abstraction and Etherspot | [Use the Kit](https://dev.rootstock.io/developers/quickstart/rootstock-etherspot/) | +| **dApp Automation with Cucumber** | Learn how to automate dApps using Cucumber Agile Automation Framework. | Basic understanding of automation frameworks like Cucumber | [Automate dApps](https://dev.rootstock.io/resources/tutorials/dapp-automation-cucumber/) | +| **RIF Relay Starter Kit** | Starter kit to develop on RIF Relay. | Understanding of RIF Relay and smart contracts | [Use the Kit](https://dev.rootstock.io/developers/integrate/rif-relay/sample-dapp/) | +| **Get Started with The Graph** | Easily query on-chain data through a decentralized network of indexers. | Familiarity with querying on-chain data and The Graph protocol | [Get Started](https://dev.rootstock.io/dev-tools/thegraph/) | +| **Get Started with Web3.py** | Get started with deploying and interacting with smart contracts on Rootstock using Web3.py. | Knowledge of Python and Web3.py | [Get Started](https://dev.rootstock.io/developers/quickstart/web3-python/) | +| **Port an Ethereum dApp to Rootstock** | Learn how to port an Ethereum dApp to Rootstock. | Experience with Ethereum dApp development | [Get Started](https://dev.rootstock.io/resources/port-to-rootstock/ethereum-dapp/) | +| **Deploy, Interact and Verify Smart Contracts using Remix and Rootstock Explorer** | In this guide, we will use the Remix IDE to write, compile, deploy, interact, and verify a smart contract on the Rootstock Explorer. | Familiarity with Remix IDE and smart contract basics | [Use Remix](https://dev.rootstock.io/developers/quickstart/remix/) | diff --git a/docs/04-resources/08-runes/Intro-runes.md b/docs/04-resources/08-runes/Intro-runes.md new file mode 100644 index 00000000..05a7d4bf --- /dev/null +++ b/docs/04-resources/08-runes/Intro-runes.md @@ -0,0 +1,109 @@ +--- +sidebar_position: 1 +title: Introduction to Runes +sidebar_label: Introduction to Runes +tags: [rsk, rootstock, resources, tutorials, runes, nft, Ethereum, dApps, smart contracts] +description: "The Rootstock Runes Mock Bridge opens up exciting opportunities for developers to build Runes-focused applications within the Rootstock ecosystem. This bridge introduces three core solutions: Mock Bridge, Marketplace, Giveaway Engine" +--- + +The Rootstock Runes Mock Bridge opens up exciting opportunities for developers to build Runes-focused applications within the Rootstock ecosystem. This bridge introduces three core solutions: + +Here’s the table in a list format in Markdown: + +- **Mock Bridge** + - Description: Facilitates transferring Runes between different blockchain networks. + - Repo: [Link](https://github.com/rsksmart/rsk-runes) + +- **Marketplace** + - Description: A platform for trading and exchanging Runes tokens. + - Repo: N/A + +- **Giveaway Engine** + - Description: A system for distributing tokens in a structured or promotional manner. + - Repo: [Link](https://github.com/rsksmart/airdrop-ui.git) + + +These tools allow developers to create diverse Runes-based applications, further expanding the Rootstock ecosystem and promoting innovation. + +In this guide, you will explore the exciting possibilities the Rootstock Runes Mock Bridge presents for developing Runes-focused applications within the Rootstock ecosystem. + +You will gain an understanding of Bitcoin Runes, including how they operate on the Bitcoin blockchain using the Unspent Transaction Output (UTXO) model and the OP\_RETURN opcode. + +**Expect to learn:** + +| **Component** | **Description** | +|----------------------|--------------------------------------------------------------------------------------------------------------| +| Core Components | Insight into the Mock Bridge and how they facilitate Runes token interactions. | +| Technical Concepts | A clear explanation of the UTXO model and OP_RETURN. | +| Practical Examples | Step-by-step examples demonstrating how to send Runes, accompanied by visual diagrams to aid understanding. | + + +By the end of this article, you will be able to build and deploy the Runes Mock Bridge and connect it to a frontend, equipping you with the foundational knowledge and technical skills necessary to start building innovative applications using Bitcoin Runes within the Rootstock ecosystem. + +### **Who Is This Guide For?** + +This guide is aimed at developers interested in working with Bitcoin Runes, particularly within the Rootstock ecosystem. You’ll need some basic knowledge of blockchain technology, Bitcoin, and Ethereum, but we’ll also provide step-by-step instructions for setting up your environment. + +### **Understanding Bitcoin Runes** + +**What Are Runes?** +Bitcoin Runes is a protocol for creating fungible tokens directly on the blockchain. Developed by Casey Rodarmor, the mind behind Ordinals, Runes offers a more efficient way to issue tokens. + +Unlike [BRC-20 and SRC-20 tokens](https://academy.binance.com/en/glossary/src-20-tokens), Runes operate independently and are not dependent on the Ordinals protocol but operate on Bitcoin. Built on [Bitcoin’s Unspent Transaction Output (UTXO) model](https://www.kraken.com/learn/what-is-bitcoin-unspent-transaction-output-utxo), Runes is fully on-chain, offering a simpler and more efficient token system. + +This UTXO-based structure gives Runes an edge over other token models, like those on Ethereum, by ensuring that all data remains on the blockchain without needing external input. + +## **How Runes Work** + +Bitcoin Runes is a protocol for creating and managing tokens on the Bitcoin blockchain. It leverages two key features: Bitcoin's UTXO (Unspent Transaction Output) model and the OP\_RETURN opcode. + +### **Understanding UTXO and How Runes Use It** + +Bitcoin's UTXO model tracks Bitcoin's movement by breaking each transaction into outputs, called UTXOs. When you spend Bitcoin, you're using these UTXOs as inputs for your transaction. + +Think of a UTXO like a digital coin in your walletβ€”each UTXO can represent a specific amount of Bitcoin, and when you spend it, the remaining "change" becomes a new UTXO. + +In the case of Bitcoin Runes, each UTXO can hold not just Bitcoin, but also different tokens or Runes. For example, let's say you have 2 Bitcoin Runes and want to transfer 1 Rune to a friend. + +Your UTXO will be split into one that transfers 1 Rune to your friend and another that keeps 1 Rune for you. The UTXO model helps track these tokens across the network, making it easy to know how many Runes each address owns. + +### **OP\_RETURN: Attaching Information to Transactions** + +Bitcoin transactions typically transfer currency from one address to another. However, the OP\_RETURN opcode allows for more than just currency transferβ€”it lets users attach extra information (up to 80 bytes) to a transaction. + +This added data is important because it’s how Runes store essential details like: + +* The token's name (e.g., "Rune of Power") +* The token’s ID (a unique identifier) +* Commands for specific actions (like transferring or minting tokens) + +This extra information is written into the blockchain in a part of the transaction called a "Runestone." When a Bitcoin transaction containing a Rune occurs, the data stored in the OP\_RETURN field tells the network what kind of Rune is involved and what should happen to it (e.g., transfer 1 Rune from John to Kate). + +### **Example: Sending Runes on Bitcoin** + +Let’s break this down with an example: + +1. **John owns 3 Runes** stored in a Bitcoin UTXO. +2. He wants to send 2 Runes to Kate. +3. John creates a Bitcoin transaction that uses his UTXO as input and attaches the Rune transaction data to it. +4. The transaction includes an **OP\_RETURN field**, where the information about transferring 2 Runes (this is the Runestone) is recorded. +5. When the transaction is processed, the Bitcoin network updates the UTXO to show that John now has 1 Rune and Kate has 2\. + +### **Simplified Diagram:** + +A diagram can help visualize this process. + + +This simplified flow shows how UTXOs and OP\_RETURN work together to track Rune transactions. + +### **Why Use Bitcoin Runes?** + +By using these features of Bitcoin, Runes allow token creation and management without needing a separate blockchain. This makes them secure (since they rely on Bitcoin’s strong security) and simple, as they use the same underlying transaction system that Bitcoin already uses. + +In short, Bitcoin Runes work by: + +1. Tracking tokens using Bitcoin's UTXO model. +2. Storing token data and actions using the OP\_RETURN field in Bitcoin transactions. + +This system lets users create, transfer, and manage tokens on the Bitcoin network in a straightforward way. + diff --git a/docs/04-resources/08-runes/_category_.yml b/docs/04-resources/08-runes/_category_.yml new file mode 100644 index 00000000..c2cf9d93 --- /dev/null +++ b/docs/04-resources/08-runes/_category_.yml @@ -0,0 +1,6 @@ +label: Runes +position: 2 +link: + type: generated-index + description: The Rootstock Runes Mock Bridge opens up exciting opportunities for developers to build Runes-focused applications within the Rootstock ecosystem. This bridge introduces three core solutions + slug: /resources/runes/ diff --git a/docs/04-resources/08-runes/runes-contracts.md b/docs/04-resources/08-runes/runes-contracts.md new file mode 100644 index 00000000..b5482bd4 --- /dev/null +++ b/docs/04-resources/08-runes/runes-contracts.md @@ -0,0 +1,275 @@ +--- +sidebar_position: 3 +title: Runes Contract Explanation walk through +sidebar_label: Runes Contract Explanation walk through +tags: [rsk, rootstock, resources, tutorials, setup, Runes, dApps, smart contracts, Remix IDE, MetaMask] +description: "The Rootstock Runes Mock Bridge setup page shows you how to getting building your runes, by first cloning our project and testing it locally." +--- + +### **1\. Understanding the Contract Structure** + +This contract defines a new token type, **RuneToken**, based on the **ERC-1155 standard**. It also uses the **Ownable** contract, which restricts certain functions to the contract's owner. + +#### **Key Imports:** + +``` +import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/Strings.sol"; +``` + +* **ERC1155**: This is a token standard that supports both fungible and non-fungible tokens within the same contract. +* **Ownable**: This contract standard restricts certain actions to only the contract's owner (the one who deployed it or someone assigned as the owner). +* **Strings**: A utility library for working with string conversions. + +### **Main Components of the Contract** + +#### **Events:** + +* `TokensFrozen`: Emits an event when tokens are frozen for a specific account. +* `TokensUnfrozen`: Emits an event when tokens are unfrozen. + +#### **Data Structures:** + +* **Balance**: Holds the account and balance of a token. +* **TokenInfo**: Contains details about a token, such as its URI ( **Uniform Resource Identifier**), name, symbol, maximum supply, current supply, default minting amount, and balance. + +#### **Mappings:** + +* `_tokenInfos`: Stores the information about each token, keyed by the token ID. +* `_userTokens`: Tracks all tokens held by a user. +* `_frozenTokens`: Keeps track of how many tokens are frozen for each user. + +### + +### **2\. The Constructor** + +``` +constructor(address initialOwner) ERC1155("") Ownable(initialOwner) {} +``` + +* **ERC1155 ("")**: This calls the ERC1155 constructor, but the URI is set as an empty string initially. +* **Ownable (initialOwner)**: The `Ownable` contract is initialized with the `initialOwner` as the owner of the contract, allowing only this address to perform certain actions (e.g., minting). + +### **3\. The `uri` Function** + +``` +function uri(uint256 tokenId) public view override returns (string memory) { + return _tokenInfos[tokenId].uri; +} +``` + +This function returns the URI for a given token ID. The URI typically points to a metadata file that contains additional details about the token (e.g., images, descriptions). + +### **4\. Minting Fungible Tokens** + +``` +function mintFungible( + string memory tokenURI, + string memory runeName, + string memory symbol, + uint256 maxSupply, + uint256 initialSupply, + uint256 defaultMintAmount, + address receiver +) public onlyOwner { + // Function logic here +} +``` + +This function allows the owner of the contract to mint fungible tokens. + +#### **Steps Involved:** + +1. **Check max supply**: Ensure that the initial supply is not greater than the maximum allowed supply. +2. **Generate a token ID**: A unique token ID is created by hashing the `runeName` using `keccak256`. +3. **Token ID uniqueness check**: Ensure that the token ID doesn't already exist. +4. **Save Token Info**: Store details about the token in the `_tokenInfos` mapping. +5. **Mint the token**: Mint the specified amount (`initialSupply`) to the `receiver` address. +6. **Track ownership**: Add the minted token to the user's list of owned tokens using `_addUserToken`. + +### **5\. Minting Non-Fungible Tokens (NFTs)** + +``` +function mintNonFungible( + string memory tokenURI, + string memory runeName, + string memory symbol, + address receiver +) public onlyOwner { + // Function logic here +} +``` + +This function is similar to `mintFungible` but for minting non-fungible tokens. A non-fungible token is a unique token, meaning only one exists. + +#### **Key Differences:** + +* **Max Supply** is always `1` for non-fungible tokens. +* **Current Supply** is also set to `1`. + +### **6\. Minting More Tokens** + +``` +function mintMore( + string memory runeName, + address receiver +) external onlyOwner { + // Function logic here +} +``` + +This function allows the contract owner to mint additional tokens of an existing fungible token, as long as the new supply doesn’t exceed the maximum supply. + +#### **Key Steps:** + +1. **Check token existence**: Ensure the token exists by checking its `maxSupply`. +2. **Check supply limits**: Ensure the current supply plus the new minting amount doesn’t exceed the max supply. +3. **Mint tokens**: Mint more tokens to the `receiver`. + +### **7\. Token Freezing and Unfreezing** + +#### **Freezing Tokens:** + +``` +function freezeTokens(string memory runeName, uint256 amount, address owner) external onlyOwner { + // Function logic here +} +``` + +* Freezing tokens restricts the user from transferring them. +* The function ensures that the account has sufficient tokens to freeze. +* The frozen amount is added to `_frozenTokens`. + +#### **Unfreezing Tokens:** + +``` +function unfreezeTokens(string memory runeName, uint256 amount, address owner) external onlyOwner { + // Function logic here +} +``` + +* This function unfreezes the tokens, allowing the user to transfer them again. +* The frozen amount is reduced from `_frozenTokens`. + +### **8\. Token Information Queries** + +#### **Get Token Information:** + +``` +function getTokenInfo(uint256 tokenId, address holder) public view returns (TokenInfo memory) { + // Function logic here +} +``` + +* This function retrieves the details about a token (such as URI, name, symbol, max supply, etc.). +* It can also include the token balance of a specific `holder` if the `holder` address is provided. + + +#### **Get Tokens Owned by a User:** + +``` +function getUserTokens(address user) public view returns (uint256[] memory) { + return _userTokens[user]; +} +``` + +* This function returns a list of all token IDs owned by a specific user. + +### **9\. Token Transfer Functions with Freezing Consideration** + +ERC1155 includes transfer functions (`safeTransferFrom` and `safeBatchTransferFrom`). These are overridden in this contract to take into account frozen tokens. + +``` +function safeTransferFrom( + address from, + address to, + uint256 id, + uint256 amount, + bytes memory data +) public virtual override { + require(balanceOf(from, id) >= amount + _frozenTokens[id][from], "Insufficient unlocked balance for transfer"); + super.safeTransferFrom(from, to, id, amount, data); +} +``` + +This ensures that users cannot transfer frozen tokens. The contract checks that the unlocked balance (total balance minus frozen balance) is sufficient before allowing transfers. + +### **10\. Overriding `balanceOf` to Consider Frozen Tokens** + +``` +function balanceOf(address account, uint256 tokenId) public view override returns (uint256) { + uint256 totalBalance = super.balanceOf(account, tokenId); + uint256 frozenBalance = _frozenTokens[tokenId][account]; + return totalBalance - frozenBalance; +} +``` + +This function returns the number of **unfrozen** tokens owned by a user for a specific token ID. + +:::info[Complete Codebase on GitHub] +[**Complete RSK-Runes**](https://github.com/rsksmart/rsk-runes/tree/main/contracts) +::: + + +## **Smart Contract Deployment** + +To deploy the Runes smart contract using Remix IDE, follow these steps in detail: + +### **Step 1: Access Remix IDE** + +1. Open your web browser and go to [Remix IDE](https://remix.ethereum.org/#lang=en&optimize=false&runs=200&evmVersion=null&version=soljson-v0.8.26+commit.8a97fa7a.js). + +### **Step 2: Create a New File** + + + +1. In the Remix IDE, navigate to the **File Explorer** (the first icon on the left sidebar). +2. Click on the **file** icon to create a new file. +3. Name the file `RuneToken.sol`. + +### **Step 3: Copy and Paste the Smart Contract** + +1. Locate the `RuneToken.sol` file from the RSK-RUNES repository under the contracts folder + + + +2. Open the `RuneToken.sol` file and copy the entire smart contract code. +3. Paste the copied code into the newly created `RuneToken.sol` file in Remix IDE. + + + +4. Click on the **Save** icon (the disk icon) to save the file. + +### + +### **Step 4: Compile the Smart Contract** + + + +1. Go to the **Solidity Compiler** tab (the third icon in the left sidebar). +2. Make sure the compiler version matches `0.8.26`. If not, select the correct version from the dropdown menu. +3. Click on the **Compile RuneToken.sol** button. A green check icon inside a circle will appear, indicating that the compilation was successful. + +### **Step 5: Deploy the Smart Contract** + + + +1. Navigate to the **Deploy & Run Transactions** tab (the fourth icon in the left sidebar). +2. Under **Environment**, select **Remix VM** +3. In the **Account** dropdown, copy the first address by clicking the icon next to it. +4. Paste the copied address into the **Deploy** input field. +5. Click the **Deploy** button. + +### **Step 6: Copy the Smart Contract Address** + + + +1. After deployment, scroll down to see the **Deployed Contracts** section. +2. You will find the generated smart contract address listed there. Copy this address for your records. + +### **Alternative Method to Copy the Contract Address** + +1. Alternatively, you can also copy the contract address from the **Transaction Receipt** that appears after deployment. +2. Look for the contract address in the receipt and copy it as well. + diff --git a/docs/04-resources/08-runes/runes-setup.md b/docs/04-resources/08-runes/runes-setup.md new file mode 100644 index 00000000..09ecdda3 --- /dev/null +++ b/docs/04-resources/08-runes/runes-setup.md @@ -0,0 +1,234 @@ +--- +sidebar_position: 2 +title: Runes Setup +sidebar_label: Runes Setup +tags: [rsk, rootstock, resources, tutorials, setup, Runes, dApps, smart contracts, Remix IDE, MetaMask] +description: "The Rootstock Runes Mock Bridge setup page shows you how to getting building your runes, by first cloning our project and testing it locally." +--- + + + +### **Prerequisites** + +Before getting started with the Runes Mock Bridge, ensure you have the following prerequisites in place: + +1. **Familiarity with Remix IDE** + You should have a basic understanding of how to use Remix IDE, an online platform for writing, compiling, and deploying Solidity smart contracts. +2. **Knowledge of Solidity** + A solid grasp of Solidity, the smart contract programming language, is essential. You'll be writing or interacting with Solidity contracts as part of this process. +3. **MetaMask Wallet Installed and Connected to Rootstock Testnet** + Make sure you have [MetaMask](https://dev.rootstock.io/dev-tools/wallets/metamask/) installed in your browser, and know how to connect it to the Rootstock (RSK) network for managing your transactions. +4. **Rootstock Account** + You'll need an account on the[RPC API Dashboard](https://dashboard.rpc.rootstock.io/login). This will allow you to create API keys for interacting with the Rootstock blockchain via RPC. +5. **Local Copy of `bc-runes-js` Package** + Clone the [`bc-runes-js`](https://github.com/rsksmart/bc-runes-js) package to your local environment. This package is necessary for generating a Taproot address and Wallet Import Format (WIF) key, which are required for the bridge. + +Once these prerequisites are in place, you'll be ready to proceed with setting up and using the Runes Mock Bridge effectively. + +### **Setting Up the `.env` File for the Runes Mock Bridge** + +``` +NEXT_PUBLIC_APP_PK='your-private-key' +NEXT_PUBLIC_RPC_URL='your rsk rpc url' +NEXT_PUBLIC_EXPLORER_URL=https://blockstream.info/testnet/tx +NEXT_PUBLIC_RSK_EXPLORER_URL= https://explorer.testnet.rootstock.io/tx +NEXT_PUBLIC_CONTRACT_ADDRESS='your erc1155 contract address' +NEXT_PUBLIC_TAPROOT_ADDRESS='your taproot address' +NEXT_PUBLIC_WIF='your wif key' +``` + +To run the **Runes Mock Bridge** effectively, you'll need to set up the environment variables in a `.env` file. These variables are crucial for connecting your application to the blockchain network, accessing private keys, and managing other sensitive configurations. + +Here's a detailed guide on what each environment variable means, how to get them, and how to set up your `.env` file correctly. + +#### **1\. `NEXT_PUBLIC_APP_PK='your-private-key'`** + +This is the private key for your application, which is essential for signing transactions or interacting with the blockchain via the Runes Mock Bridge + +:::info[Info] + Please avoid using a wallet that contains real funds for these exercises. Using an empty wallet ensures your funds remain secure and reduces the risk of unintentional loss. +::: + +* You can obtain your private key from your wallet. Typically, you will export the private key from the wallet software you're using (like MetaMask or any other supported wallet). +* Follow a detailed tutorial specific to your wallet on how to extract your private key, and then input it here. + +#### **2\. `NEXT_PUBLIC_RPC_URL='your RSK RPC URL'`** + +The Remote Procedure Call (RPC) URL is how your Runes Mock Bridge interacts with the Rootstock (RSK) blockchain. + +* To get the RSK RPC URL, go to the[RPC API Dashboard](https://dashboard.rpc.rootstock.io/login) and log in. After logging in, you can create an API key that will give you access to the RPC URL. +* Once the key is generated, you can use it to set up this variable, which allows your bridge to communicate with the blockchain. + +#### **3\. `NEXT_PUBLIC_EXPLORER_URL=https://blockstream.info/testnet/tx`** + +This is the URL for the **Bitcoin Testnet Explorer** provided by Blockstream, where you can track Bitcoin testnet transactions. + +:::note[Note] +This value remains constant and doesn't need to be changed, as it will always point to the Bitcoin testnet explorer. +::: + +#### **4\. `NEXT_PUBLIC_RSK_EXPLORER_URL=https://explorer.testnet.rootstock.io/tx`** + +This is the URL for the **Rootstock Testnet Explorer**, where you can track transactions related to the Rootstock network. + +:::note[Note] +Like the Blockstream explorer URL, this value is also constant and doesn't need to be changed. It is set to the correct Rootstock testnet explorer. +::: + +#### **5\. `NEXT_PUBLIC_CONTRACT_ADDRESS='your ERC-1155 contract address'`** + +:::info[Important] +The RuneToken implementation used is not a standard ERC-1155 contract. It includes custom functions to freeze tokens transferred from Rootstock to Bitcoin. To ensure compatibility, please use the same (or an improved) version of the smart contract available in this repository: [RuneToken.sol](https://github.com/rsksmart/rsk-runes/blob/main/contracts/RuneToken.sol) and deploy it. +::: + + +This variable is used to specify the address of your deployed ERC-1155 contract, which plays a key role in the bridge's functionality. + +* You need to deploy your ERC-1155 contract using Remix IDE or a similar tool. Once the deployment is complete, you will get the contract address. +* Copy the contract address from Remix IDE after deployment and paste it into this variable. + +#### **6\. `NEXT_PUBLIC_TAPROOT_ADDRESS='your taproot address'`** + +Taproot addresses are used for Bitcoin transactions with improved privacy and flexibility. The [Runes Mock Bridge](https://github.com/rsksmart/rsk-runes) requires a Taproot address for interacting with Bitcoin's taproot transactions. + +* You can generate a Taproot address using a special package we’ve created. Follow these steps: + 1. Clone the repository from [bc-runes-js](https://github.com/rsksmart/bc-runes-js.git). + 2. Run `npm install` to install all the required dependencies. + 3. Run `npm run generate-address` to generate the Taproot address. +* Once generated, copy the Taproot address from the output and paste it into this variable. + +``` +> bc-runes-js@0.3.2 generate-address +> node src/utils/address.js --log=address + +No WIF set, generating new random address +{ + taprootAddress: 'tb1pl9lcxu4f373dpzqzvq5amcm8het2chgwc45yhtlxkz5r66dq2zcqhfvrnx', + WIF: 'cQwnr3fnmrkEPYNpCnsHqn7opcEwfezKbmadBD8b85XozXQCZyzP' +} + +``` +> you can generate multiple taproot address + +#### **7\. `NEXT_PUBLIC_WIF='your WIF key'`** + +The Wallet Import Format (WIF) key is the encoded version of your Bitcoin private key, which is necessary for signing Bitcoin transactions on the testnet. + +* The same package used to generate the Taproot address will also generate the WIF key. + 1. After running `npm run generate`, you will get both the Taproot address and the WIF key as part of the output. + 2. Copy the WIF key and paste it into this variable. + + + +:::note[Note] +**Security:** Ensure that the `.env` file is kept private and not exposed in public repositories or shared with unauthorized people. This file contains sensitive information such as your private keys, which could be exploited if leaked. + +**Testing:** If you are using testnets (like Bitcoin or Rootstock testnets), make sure to configure your RPC URL, private keys, and contract addresses to match the appropriate testnet environment. This ensures that you're not interacting with the mainnet during development. +::: + + +## **Installation Guide** + +To clone and run the Runes Mock Bridge project locally, follow these steps: + +#### **1\. Clone the Repository:** + +``` +git clone https://github.com/rsksmart/rsk-runes.git +cd rsk-runes +``` + +#### **2\. Install Dependencies:** + +Use either `yarn` or `npm` to install the necessary dependencies: + +``` +yarn +or +npm install +``` + +#### **3\. Access the Application:** + +Once the installation is complete, start the development server and access the application in your browser by visiting: + +``` +http://localhost:3000 +``` + + + +1. **Click on "Connect Wallet"**: + + * Locate and click the **"Connect Wallet"** button. This is typically found in the top right corner of the platform. + +2. **Select MetaMask**: + + * From the list of available wallets, select **MetaMask**. + +3. **Follow the On-Screen Instructions**: + + * Once connected, your wallet address will appear on the platform, indicating that your MetaMask wallet is successfully linked. + +## Mint Runes on Rootstock + +After logging in, follow the steps below to mint a new rune. + +1. **Check Your MetaMask Wallet**: + * At the top right of the screen, you will see your connected MetaMask wallet address (Rootstock network). Ensure it's the correct wallet before proceeding. +2. **NFT Toggle (Optional)**: + * If you're minting an NFT, turn on the **NFT** toggle switch. Otherwise, leave it off to mint a standard token. +3. **Name**: + * **Description**: Enter the name of your rune, which will serve as its identifier. + * **Example**: You might name it something like "EventRune." +4. **Symbol**: + * **Description**: Enter a single character (letter, number, or symbol) as the token symbol. + * **Example**: Use something simple like "R" or "$." +5. **Premine**: + * **Description**: This is the amount of runes that will be minted immediately to the rune creator. + * **Example**: Enter "10" to pre-mine 10 runes directly into your wallet. +6. **Amount**: + * **Description**: Define the number of runes minted per transaction. + * **Example**: Enter "1" to mint one rune per transaction. +7. **Cap**: + * **Description**: The maximum number of runes that can be minted, excluding pre-mined runes. + * **Example**: Set it to "100" if you want to limit the total rune supply to 100\. +8. **Receiver**: + * **Description**: This will automatically fetch your Rootstock wallet address where the minted runes will be sent. +9. **Etch Token**: + * After filling out all the fields, click the **"Etch Token"** button to start the minting process. +10. **Wait for Confirmation**: + * Once you've clicked **Etch Token**, you will see a screen that informs you that your transaction is being processed. + * **Example**: The screen will show that it is waiting for multiple confirmations (e.g., "Waiting for 7 confirmations"). During this time, the network is validating your transaction. + * You will need to wait until the required number of confirmations is reached before the rune minting process is complete. +11. **Runes List**: +* After the confirmations are completed, your newly minted rune will appear in the **Runes List** at the bottom of the screen, displaying all the runes you've created. + + +12. **Log Out**: +* If you're done, click the **"Logout"** button at the top right of the screen to securely end your session. + +### Bridge Runes to BTC + + + +Once you've successfully minted your rune, you can bridge it to BTC. Follow the instructions below. + +1. **Click on the "Bridge" Button**: + * After minting your rune (like the one shown in the image above), click on the **"Bridge"** button next to the rune you want to convert to BTC. + * This will take you to the bridging screen. +2. **Enter the Required Details**: + * On the new screen, you'll be prompted to enter the following information: + * **Name**: + * **Description**: Enter the name of the rune you want to bridge. This should match the name of the rune you created earlier. + * **Example**: If you named your rune "EventRune," enter that as the name. + * **Amount**: + * **Description**: Enter the number of runes you want to bridge to BTC. + * **Example**: If you want to bridge 10 runes, enter "10." + * **BTC Address**: + * **Description**: Enter your Bitcoin wallet address where the BTC equivalent will be sent after the rune is bridged. + * **Example**: Ensure this is a valid BTC wallet address (e.g., "bc1q..."). +3. **Click "Runes to BTC" Button**: + * After filling in the details, click on the **"Runes to BTC"** button to initiate the bridging process. + * The system will process the bridging, and your runes will be converted to BTC and sent to the provided BTC address. + diff --git a/docs/05-dev-tools/data/thegraph.md b/docs/05-dev-tools/data/thegraph.md index 33b7a807..5229fbe0 100644 --- a/docs/05-dev-tools/data/thegraph.md +++ b/docs/05-dev-tools/data/thegraph.md @@ -54,7 +54,7 @@ Run the following command locally: npm install -g @graphprotocol/graph-cli ``` -> You must have at least v0.76.0 to deploy subgraphs on Rootstock mainnet. +> You must have at least v0.85.0 to deploy subgraphs on Rootstock mainnet and testnet. ### Initialize a Subgraph⁠ diff --git a/docs/05-dev-tools/wallets/metamask.mdx b/docs/05-dev-tools/wallets/metamask.mdx index 628dce08..edef75e0 100644 --- a/docs/05-dev-tools/wallets/metamask.mdx +++ b/docs/05-dev-tools/wallets/metamask.mdx @@ -14,14 +14,15 @@ In this guide, you will learn about the different ways to set up and connect to > Ideal for general users looking to automatically add the Rootstock network to their MetaMask wallet. -1. Install MetaMask on your browser from the oficial website: [https://metamask.io/download/](https://metamask.io/download/) +1. Install MetaMask on your browser from the official website: [https://metamask.io/download/](https://metamask.io/download/) 2. Click on the buttons below to add Rootstock Mainnet and Rootstock Testnet -
+

+
-
+
-
+
Total Supply5,587,672.181 stRIFVaries and will increase and decrease as RIF is staked and unstaked.
Contract Address 0x5db91e24BD32059584bbDb831A901f1199f3d459
Contract TypeERC1967ProxyContract TypesERC20, ERC677, ERC1967Proxy
How to Get -
How to Stake -
- - + ## Option 3: Add Rootstock Networks to MetaMask Programmatically -> Ideal for developers looking to initiate a network switch on MetaMask from a website or dApp. -See how to [Connect Rootstock to Metamask Programmatically](/resources/tutorials/rootstock-metamask/). - +> Ideal for developers looking to initiate a network switch on MetaMask from a website or dApp. +> See how to [Connect Rootstock to Metamask Programmatically](/resources/tutorials/rootstock-metamask/). ## Watch the Video Explainer @@ -164,6 +177,7 @@ A **workaround** for this is to lowercase the addresses after copying them. - This tutorial uses the Public Nodes as RPC. You can connect to other nodes or use the [Rootstock RPC API](/developers/rpc-api/). - The node must enable CORS for browser-based dApps to work. - Please review the [configuration file reference](/node-operators/setup/configuration/) for CORS settings. + ::: ## Next Steps diff --git a/docusaurus.config.js b/docusaurus.config.js index e871bc5d..360aa0f2 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -239,7 +239,7 @@ const config = { appId: 'WAFPQL14PU', // Public API key: it is safe to commit it - apiKey: '4da8ccafcd04d9c5efd1601a60658bce', + apiKey: '78aa26683ec349ff7e4a7c2d723e4cb7', indexName: 'dev-rootstock', diff --git a/src/components/CardsGrid/Card/index.js b/src/components/CardsGrid/Card/index.js new file mode 100644 index 00000000..ea7d54ac --- /dev/null +++ b/src/components/CardsGrid/Card/index.js @@ -0,0 +1,36 @@ +import React from "react"; +import clsx from "clsx"; +import Button from "/src/components/Button"; + +import styles from "./styles.module.scss"; + +export default function Card({value, subtitle, title, description, color = "orange", className, linkHref, linkTitle, image, ...props}) { + + return
+ {image && ( + {title} + )} +
+ {subtitle && ( + + {subtitle} + + )} +

{title}

+
+ {description && ( +
+ {description} +
+ )} + {linkHref && ( + + )} +
+} diff --git a/src/components/CardsGrid/Card/styles.module.scss b/src/components/CardsGrid/Card/styles.module.scss new file mode 100644 index 00000000..215fae55 --- /dev/null +++ b/src/components/CardsGrid/Card/styles.module.scss @@ -0,0 +1,10 @@ +.Card{ + --rsk-card-main-color: var(--bs-orange); + a:not([class*="btn"]){ + color: var(--rsk-card-main-color); + text-decoration: underline; + &:hover { + text-decoration: none; + } + } +} diff --git a/src/components/CardsGrid/index.js b/src/components/CardsGrid/index.js new file mode 100644 index 00000000..99d3c770 --- /dev/null +++ b/src/components/CardsGrid/index.js @@ -0,0 +1,17 @@ +import React from "react"; +import clsx from "clsx"; +import styles from './styles.module.scss'; + +export default function CardsGrid({children, className, ...props}) { + const childItems = (Array.isArray(children) ? children : [children]).filter( + Boolean, + ); + + return
+ {childItems.map((tabItem, i) => + + {tabItem} + + )} +
+} diff --git a/src/components/CardsGrid/styles.module.scss b/src/components/CardsGrid/styles.module.scss new file mode 100644 index 00000000..f2aa97ec --- /dev/null +++ b/src/components/CardsGrid/styles.module.scss @@ -0,0 +1,7 @@ +.CardsGrid{ + display: grid; + gap: 16px; + @media (min-width: 768px) { + grid-template-columns: repeat(2, 1fr); + } +} diff --git a/src/components/Carousel/CarouselItem/index.js b/src/components/Carousel/CarouselItem/index.js new file mode 100644 index 00000000..0734bd49 --- /dev/null +++ b/src/components/Carousel/CarouselItem/index.js @@ -0,0 +1,26 @@ +import React from "react"; +import clsx from "clsx"; +import Link from '/src/components/Link'; + +import {SplideSlide} from "@splidejs/react-splide"; + +export default function CarouselItem({title, href, target, image, ...props}) { + + const TagName = ({href, children, title, ...props}) => { + return href ? ( + + {children} + + ) : ( +
+ {children} +
+ ) + } + + return image && + + {title + + +} diff --git a/src/components/Carousel/index.js b/src/components/Carousel/index.js index 14fef142..ba8615a3 100644 --- a/src/components/Carousel/index.js +++ b/src/components/Carousel/index.js @@ -4,9 +4,9 @@ import {Splide, SplideSlide, SplideTrack} from '@splidejs/react-splide'; import Button from "/src/components/Button"; import styles from './styles.module.scss'; -export default function Carousel({images = [], width = 370, height = 206, className, ...props}) { +export default function Carousel({images = [], width = 370, height = 206, className, children, ...props}) { - return images?.length > 0 && ( + return ( {images.map((src, index) => ( - {`Image +
+ {`Image +
) )} + {children}
+ + +``` +Default , small , and large buttons for different use cases. + + + + + diff --git a/src/theme/DocCard/index.js b/src/theme/DocCard/index.js index 54dbd54b..fb6bab1a 100644 --- a/src/theme/DocCard/index.js +++ b/src/theme/DocCard/index.js @@ -1,6 +1,5 @@ import React from 'react'; import clsx from 'clsx'; -import Link from '@docusaurus/Link'; import { findFirstSidebarItemLink, useDocById, @@ -8,9 +7,8 @@ import { import {usePluralForm} from '@docusaurus/theme-common'; import isInternalUrl from '@docusaurus/isInternalUrl'; import {translate} from '@docusaurus/Translate'; -import Heading from '@theme/Heading'; -import styles from './styles.module.css'; -import TitleColor from "../../components/TitleColor"; +import Button from "../../components/Button"; + function useCategoryItemsPlural() { const {selectMessage} = usePluralForm(); return (count) => @@ -27,32 +25,41 @@ function useCategoryItemsPlural() { ), ); } -function CardContainer({href, children}) { +function CardContainer({children}) { return ( - +
{children} - +
); } function CardLayout({href, icon, title, description}) { return ( - - + +

{title} - +

{description && ( -

- {description} -

+
+

+ {description} +

+
+ )} + + {href && ( + )}
); } + function CardCategory({item}) { const href = findFirstSidebarItemLink(item); const categoryItemsPlural = useCategoryItemsPlural(); diff --git a/src/theme/DocCard/styles.module.css b/src/theme/DocCard/styles.module.css deleted file mode 100644 index c4035cbd..00000000 --- a/src/theme/DocCard/styles.module.css +++ /dev/null @@ -1,26 +0,0 @@ -.cardContainer { - --ifm-link-color: var(--ifm-card-color); - --ifm-link-hover-color: var(--rsk-color-main); - --ifm-link-hover-decoration: none; - color: var(--ifm-card-color); - border: 1px solid var(--ifm-card-border-color); - transition: all var(--ifm-transition-fast) ease; - transition-property: border; -} - -.cardContainer:hover { - border-color: var(--ifm-color-primary); - color: var(--ifm-card-color); -} - -.cardContainer *:last-child { - margin-bottom: 0; -} - -.cardTitle { - font-size: 1.2rem; -} - -.cardDescription { - font-size: 0.8rem; -} diff --git a/src/theme/MDXComponents.js b/src/theme/MDXComponents.js index 0c09e982..8b13fab7 100644 --- a/src/theme/MDXComponents.js +++ b/src/theme/MDXComponents.js @@ -2,6 +2,7 @@ import React from 'react'; // Import the original mapper import MDXComponents from '@theme-original/MDXComponents'; import Carousel from '/src/components/Carousel'; +import CarouselItem from '/src/components/Carousel/CarouselItem'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import Accordion from 'react-bootstrap/Accordion'; @@ -10,11 +11,14 @@ import Video from "/src/components/Video"; import Card from "/src/components/CardSimple"; import Filter from "/src/components/Filter"; import FilterItem from "/src/components/Filter/FilterItem"; +import Button from "/src/components/Button"; +import CardsGrid from "/src/components/CardsGrid"; +import CardsGridItem from "/src/components/CardsGrid/Card"; export default { // Re-use the default mapping ...MDXComponents, // Map the "" tag to our Highlight component // `Highlight` will receive all props that were passed to `` in MDX - Carousel, Tabs, TabItem, Accordion, Card, Quote, Video, Filter, FilterItem + Carousel, CarouselItem, Tabs, TabItem, Accordion, Card, Quote, Video, Filter, FilterItem, Button, CardsGrid, CardsGridItem }; diff --git a/src/theme/TOC/styles.module.css b/src/theme/TOC/styles.module.css index 8df06861..79d3cc46 100644 --- a/src/theme/TOC/styles.module.css +++ b/src/theme/TOC/styles.module.css @@ -1,7 +1,9 @@ -.tableOfContents { - +@media (min-width: 997px) { + .tableOfContents { + max-height: 40svh; + overflow: auto; + } } - @media (max-width: 996px) { .tableOfContents { display: none; diff --git a/static/img/developers/flyover/1-remix.png b/static/img/developers/flyover/1-remix.png new file mode 100644 index 00000000..35792533 Binary files /dev/null and b/static/img/developers/flyover/1-remix.png differ diff --git a/static/img/developers/quickstart/1-alchemy.png b/static/img/developers/quickstart/1-alchemy.png new file mode 100644 index 00000000..73bd3b72 Binary files /dev/null and b/static/img/developers/quickstart/1-alchemy.png differ diff --git a/static/img/developers/quickstart/1-remix.png b/static/img/developers/quickstart/1-remix.png new file mode 100644 index 00000000..35792533 Binary files /dev/null and b/static/img/developers/quickstart/1-remix.png differ diff --git a/static/img/developers/quickstart/10-remix.png b/static/img/developers/quickstart/10-remix.png new file mode 100644 index 00000000..5d5a6ae8 Binary files /dev/null and b/static/img/developers/quickstart/10-remix.png differ diff --git a/static/img/developers/quickstart/11-remix.png b/static/img/developers/quickstart/11-remix.png new file mode 100644 index 00000000..b2b563b4 Binary files /dev/null and b/static/img/developers/quickstart/11-remix.png differ diff --git a/static/img/developers/quickstart/12-remix.png b/static/img/developers/quickstart/12-remix.png new file mode 100644 index 00000000..09000d91 Binary files /dev/null and b/static/img/developers/quickstart/12-remix.png differ diff --git a/static/img/developers/quickstart/13-remix.png b/static/img/developers/quickstart/13-remix.png new file mode 100644 index 00000000..080a37f0 Binary files /dev/null and b/static/img/developers/quickstart/13-remix.png differ diff --git a/static/img/developers/quickstart/14-remix.png b/static/img/developers/quickstart/14-remix.png new file mode 100644 index 00000000..4927181d Binary files /dev/null and b/static/img/developers/quickstart/14-remix.png differ diff --git a/static/img/developers/quickstart/15-remix.png b/static/img/developers/quickstart/15-remix.png new file mode 100644 index 00000000..ea34be46 Binary files /dev/null and b/static/img/developers/quickstart/15-remix.png differ diff --git a/static/img/developers/quickstart/16-remix.png b/static/img/developers/quickstart/16-remix.png new file mode 100644 index 00000000..e50c9b03 Binary files /dev/null and b/static/img/developers/quickstart/16-remix.png differ diff --git a/static/img/developers/quickstart/17-remix.png b/static/img/developers/quickstart/17-remix.png new file mode 100644 index 00000000..3438f6ea Binary files /dev/null and b/static/img/developers/quickstart/17-remix.png differ diff --git a/static/img/developers/quickstart/18-remix.png b/static/img/developers/quickstart/18-remix.png new file mode 100644 index 00000000..561a94c1 Binary files /dev/null and b/static/img/developers/quickstart/18-remix.png differ diff --git a/static/img/developers/quickstart/2-alchemy.png b/static/img/developers/quickstart/2-alchemy.png new file mode 100644 index 00000000..fde4098b Binary files /dev/null and b/static/img/developers/quickstart/2-alchemy.png differ diff --git a/static/img/developers/quickstart/2-remix.png b/static/img/developers/quickstart/2-remix.png new file mode 100644 index 00000000..5a4f0038 Binary files /dev/null and b/static/img/developers/quickstart/2-remix.png differ diff --git a/static/img/developers/quickstart/3-alchemy.png b/static/img/developers/quickstart/3-alchemy.png new file mode 100644 index 00000000..23840b71 Binary files /dev/null and b/static/img/developers/quickstart/3-alchemy.png differ diff --git a/static/img/developers/quickstart/3-remix.png b/static/img/developers/quickstart/3-remix.png new file mode 100644 index 00000000..a1284984 Binary files /dev/null and b/static/img/developers/quickstart/3-remix.png differ diff --git a/static/img/developers/quickstart/4-alchemy.png b/static/img/developers/quickstart/4-alchemy.png new file mode 100644 index 00000000..97310bc9 Binary files /dev/null and b/static/img/developers/quickstart/4-alchemy.png differ diff --git a/static/img/developers/quickstart/4-remix.png b/static/img/developers/quickstart/4-remix.png new file mode 100644 index 00000000..b6a9d7de Binary files /dev/null and b/static/img/developers/quickstart/4-remix.png differ diff --git a/static/img/developers/quickstart/5-alchemy.png b/static/img/developers/quickstart/5-alchemy.png new file mode 100644 index 00000000..85b12394 Binary files /dev/null and b/static/img/developers/quickstart/5-alchemy.png differ diff --git a/static/img/developers/quickstart/5-remix.png b/static/img/developers/quickstart/5-remix.png new file mode 100644 index 00000000..3d068de2 Binary files /dev/null and b/static/img/developers/quickstart/5-remix.png differ diff --git a/static/img/developers/quickstart/5a-remix.png b/static/img/developers/quickstart/5a-remix.png new file mode 100644 index 00000000..bc33a706 Binary files /dev/null and b/static/img/developers/quickstart/5a-remix.png differ diff --git a/static/img/developers/quickstart/6-alchemy.png b/static/img/developers/quickstart/6-alchemy.png new file mode 100644 index 00000000..91344d95 Binary files /dev/null and b/static/img/developers/quickstart/6-alchemy.png differ diff --git a/static/img/developers/quickstart/6-remix.png b/static/img/developers/quickstart/6-remix.png new file mode 100644 index 00000000..65708378 Binary files /dev/null and b/static/img/developers/quickstart/6-remix.png differ diff --git a/static/img/developers/quickstart/7-alchemy.png b/static/img/developers/quickstart/7-alchemy.png new file mode 100644 index 00000000..aef85395 Binary files /dev/null and b/static/img/developers/quickstart/7-alchemy.png differ diff --git a/static/img/developers/quickstart/7-remix.png b/static/img/developers/quickstart/7-remix.png new file mode 100644 index 00000000..b26bbac8 Binary files /dev/null and b/static/img/developers/quickstart/7-remix.png differ diff --git a/static/img/developers/quickstart/8-remix.png b/static/img/developers/quickstart/8-remix.png new file mode 100644 index 00000000..452e642b Binary files /dev/null and b/static/img/developers/quickstart/8-remix.png differ diff --git a/static/img/developers/quickstart/9-remix.png b/static/img/developers/quickstart/9-remix.png new file mode 100644 index 00000000..1642983a Binary files /dev/null and b/static/img/developers/quickstart/9-remix.png differ diff --git a/static/img/guides/quickstart/hardhat/balance-of.png b/static/img/guides/quickstart/hardhat/balance-of.png new file mode 100644 index 00000000..063375d7 Binary files /dev/null and b/static/img/guides/quickstart/hardhat/balance-of.png differ diff --git a/static/img/guides/quickstart/hardhat/connect-button.png b/static/img/guides/quickstart/hardhat/connect-button.png new file mode 100644 index 00000000..6c7202b5 Binary files /dev/null and b/static/img/guides/quickstart/hardhat/connect-button.png differ diff --git a/static/img/guides/quickstart/hardhat/connected-address.png b/static/img/guides/quickstart/hardhat/connected-address.png new file mode 100644 index 00000000..c7ca2cbb Binary files /dev/null and b/static/img/guides/quickstart/hardhat/connected-address.png differ diff --git a/static/img/guides/quickstart/hardhat/frontend.png b/static/img/guides/quickstart/hardhat/frontend.png deleted file mode 100644 index 63b78878..00000000 Binary files a/static/img/guides/quickstart/hardhat/frontend.png and /dev/null differ diff --git a/static/img/guides/quickstart/hardhat/transfer-complete.png b/static/img/guides/quickstart/hardhat/transfer-complete.png new file mode 100644 index 00000000..c3fa8991 Binary files /dev/null and b/static/img/guides/quickstart/hardhat/transfer-complete.png differ diff --git a/static/img/guides/quickstart/hardhat/transferring.png b/static/img/guides/quickstart/hardhat/transferring.png new file mode 100644 index 00000000..9f82c035 Binary files /dev/null and b/static/img/guides/quickstart/hardhat/transferring.png differ diff --git a/static/img/guides/quickstart/hardhat/write-contract.png b/static/img/guides/quickstart/hardhat/write-contract.png new file mode 100644 index 00000000..a737c4b0 Binary files /dev/null and b/static/img/guides/quickstart/hardhat/write-contract.png differ diff --git a/static/img/resources/runes/Compile-the-Smart-Contract.png b/static/img/resources/runes/Compile-the-Smart-Contract.png new file mode 100644 index 00000000..06d78842 Binary files /dev/null and b/static/img/resources/runes/Compile-the-Smart-Contract.png differ diff --git a/static/img/resources/runes/Copy-and-Paste -the-Smart-Contract.png b/static/img/resources/runes/Copy-and-Paste -the-Smart-Contract.png new file mode 100644 index 00000000..3a1747c3 Binary files /dev/null and b/static/img/resources/runes/Copy-and-Paste -the-Smart-Contract.png differ diff --git a/static/img/resources/runes/Copy-the-Smart-Contract-Address.png b/static/img/resources/runes/Copy-the-Smart-Contract-Address.png new file mode 100644 index 00000000..fa40c408 Binary files /dev/null and b/static/img/resources/runes/Copy-the-Smart-Contract-Address.png differ diff --git a/static/img/resources/runes/Deploy-the-Smart-Contract.png b/static/img/resources/runes/Deploy-the-Smart-Contract.png new file mode 100644 index 00000000..e0f8a428 Binary files /dev/null and b/static/img/resources/runes/Deploy-the-Smart-Contract.png differ diff --git a/static/img/resources/runes/Paste-RemixIDE.png b/static/img/resources/runes/Paste-RemixIDE.png new file mode 100644 index 00000000..640675cc Binary files /dev/null and b/static/img/resources/runes/Paste-RemixIDE.png differ diff --git a/static/img/resources/runes/Remix-create-new-file.png b/static/img/resources/runes/Remix-create-new-file.png new file mode 100644 index 00000000..52657e0c Binary files /dev/null and b/static/img/resources/runes/Remix-create-new-file.png differ diff --git a/static/img/resources/runes/bridge-runes.png b/static/img/resources/runes/bridge-runes.png new file mode 100644 index 00000000..dfdd7c28 Binary files /dev/null and b/static/img/resources/runes/bridge-runes.png differ diff --git a/static/img/resources/runes/how-runes-works.png b/static/img/resources/runes/how-runes-works.png new file mode 100644 index 00000000..1712d148 Binary files /dev/null and b/static/img/resources/runes/how-runes-works.png differ diff --git a/static/img/resources/runes/mint-runes.png b/static/img/resources/runes/mint-runes.png new file mode 100644 index 00000000..1b89cd03 Binary files /dev/null and b/static/img/resources/runes/mint-runes.png differ diff --git a/static/img/resources/runes/runes-ui.png b/static/img/resources/runes/runes-ui.png new file mode 100644 index 00000000..89768568 Binary files /dev/null and b/static/img/resources/runes/runes-ui.png differ diff --git a/static/img/rif/rns/theStack.png b/static/img/rif/rns/theStack.png new file mode 100644 index 00000000..69a7c48a Binary files /dev/null and b/static/img/rif/rns/theStack.png differ diff --git a/vercel.json b/vercel.json index 30f45fe9..15716a23 100644 --- a/vercel.json +++ b/vercel.json @@ -632,6 +632,8 @@ {"source" : "/guides/dex/dex-vs-cex", "destination" : "https://blog.rootstock.io/noticia/dex-vs-cex/"}, {"source" : "/guides/get-crypto-on-rsk/cryptocurrency-vs-token", "destination" : "https://blog.rootstock.io/noticia/cryptocurrency-vs-token/"}, {"source" : "/guides/stablecoin/stablecoin-vs-digital-assets", "destination" : "https://blog.rootstock.io/noticia/stablecoin-vs-digital-asset/"}, - {"source" : "/guides/dex/features-of-a-dex", "destination" : "https://blog.rootstock.io/noticia/features-of-a-dex/"} + {"source" : "/guides/dex/features-of-a-dex", "destination" : "https://blog.rootstock.io/noticia/features-of-a-dex/"}, + {"source" : "/developers/quickstart/alchemy/", "destination" : "/developers/rpc-api/alchemy/"}, + {"source" : "/developers/rpc-api/setup/", "destination" : "/developers/rpc-api/rootstock/setup/"} ] } \ No newline at end of file