Skip to content

Commit

Permalink
Blogpost on SDK consolidation + Announcement Bar (+ small fix) (#2090)
Browse files Browse the repository at this point in the history
* added blogpost + small fixes

* Apply suggestions from code review

Co-authored-by: Damián Parrino <[email protected]>

---------

Co-authored-by: Damián Parrino <[email protected]>
  • Loading branch information
gagdiez and bucanero authored Jun 29, 2024
1 parent 2e7ca74 commit d8b5b47
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 7 deletions.
56 changes: 56 additions & 0 deletions blog/2024-07-28.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: One place for all Smart Contracts Docs
authors: [gagdiez]
slug: sdks-unified
tags: [updates]
---

*We have consolidated all our documentation in a single section, so you don't need to go searching around for it*

<p><img src="/assets/images/contracts-landing-5a9c76a78e71b0e5f9a96033f1f23d23.png" /></p>

<!-- truncate -->

Smart contracts are small pieces of logic that can live on every NEAR account. To build a contract you use the NEAR SDKs, which comes in two flavours: Rust and JavaScript.

Until today, we had multiple docs explaining how to build smart contracts:
- `/sdk/rust` dedicated to explain how to use the Rust SDK
- `/sdk/js` dedicated to explain how to use the JS SDK
- [`/build/smart-contracts/what-is`](/build/smart-contracts/what-is) - that explains general concepts, and how to implement them using both SDKs

Today, this is over, as all the information on how to build smart contracts is located in a single area: [`/build/smart-contracts/what-is`](/build/smart-contracts/what-is).

Meanwhile, we have transformed the [SDK page](/tools/sdk) to be a simple landing page with links to:
- The [Rust SDK reference docs](https://docs.rs/near-sdk/latest/near_sdk/)
- The [JS SDK reference docs](https://near.github.io/near-api-js/)
- The [Smart Contract Section](/build/smart-contracts/what-is)

## Why did we have 3 sections explaining the same topic?

The reason we had 3 different sections was that, historically, the engineers of each SDK were working on their own docs in isolation. To help mitigate this, we created a section on NEAR docs, meant to consolidate all the external documentation.

One day, the individual SDK pages were deleted - if I remember correctly, it was because we wanted to have fewer domains - and we had to migrate everything in a rush.

This left us in a very weird situation: we already had a section explaining how to build a smart contract... and now we had 3.

## A single source of truth

Luckily, this is now fixed! We have finally conquered the original dream of having a single section for [Smart Contracts](/build/smart-contracts/what-is), with all the information consolidated in there.

Now, we can focus on maintaining a single section, thus making it easier to keep it updated and relevant.

## What's next?

We are currently undergoing a process of **consolidating** all the documentation. This means that we are looking at all the sections that have overlapping information, and trying to merge them into a single place.

This will not only improve the quality of our docs, but also make it easier for you to find the information you need. In fact, improving search is one of the main motors of this change, since we noticed that our search tool ([Algolia](https://www.algolia.com/)) gets confused when the same concept is spread all over the place.

Moreover, having consistent and coherent documentation will allow us to further expand our search capabilities using AI! This is something we are very excited about, as it will allow us to provide you with even more relevant information.

## If you don't like this change, please let us know!

As always, we are more than open to feedback. If you think that this change is not good, or that we are missing something, please let us know! You can reach out to us through the blue feedback button you see at the side of the screen.

We are looking forward to hearing your thoughts and feedback, and hope you enjoy the content we'll be sharing.

Happy coding, and see you in the next post! 🚀
139 changes: 139 additions & 0 deletions docs/2.build/2.smart-contracts/anatomy/best-practices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
---
id: best-practices
title: "Best Practices"
---

# Best practices

## Enable overflow checks

It's usually helpful to panic on integer overflow. To enable it, add the following into your `Cargo.toml` file:

```toml
[profile.release]
overflow-checks = true
```

## Use `require!` early

Try to validate the input, context, state and access using `require!` before taking any actions. The earlier you panic, the more [gas](https://docs.near.org/concepts/protocol/gas) you will save for the caller.

```rust
#[nearn]
impl Contract {
pub fn set_fee(&mut self, new_fee: Fee) {
require!(env::predecessor_account_id() == self.owner_id, "Owner's method");
new_fee.assert_valid();
self.internal_set_fee(new_fee);
}
}
```

**Note**: If you want debug information in the panic message or if you are using an SDK version before `4.0.0-pre.2`,
the Rust `assert!` macro can be used instead of `require!`.

```rust
#[near]
impl Contract {
pub fn set_fee(&mut self, new_fee: Fee) {
assert_eq!(env::predecessor_account_id(), self.owner_id, "Owner's method");
new_fee.assert_valid();
self.internal_set_fee(new_fee);
}
}
```

## Use `log!`

Use logging for debugging and notifying user.

When you need a formatted message, you can use the following macro:

```rust
log!("Transferred {} tokens from {} to {}", amount, sender_id, receiver_id);
```

It's equivalent to the following message:

```rust
env::log_str(format!("Transferred {} tokens from {} to {}", amount, sender_id, receiver_id).as_ref());
```

## Return `Promise`

If your method makes a cross-contract call, you probably want to return the newly created `Promise`.
This allows the caller (such as a near-cli or near-api-js call) to wait for the result of the promise instead of returning immediately.
Additionally, if the promise fails for some reason, returning it will let the caller know about the failure, as well as enabling NEAR Explorer and other tools to mark the whole transaction chain as failing.
This can prevent false-positives when the first or first few transactions in a chain succeed but a subsequent transaction fails.

E.g.

```rust
#[near]
impl Contract {
pub fn withdraw_100(&mut self, receiver_id: AccountId) -> Promise {
Promise::new(receiver_id).transfer(100)
}
}
```

## Reuse crates from `near-sdk`

`near-sdk` re-exports the following crates:

- `borsh`
- `base64`
- `bs58`
- `serde`
- `serde_json`

Most common crates include `borsh` which is needed for internal STATE serialization and
`serde` for external JSON serialization.

When marking structs with `serde::Serialize` you need to use `#[serde(crate = "near_sdk::serde")]`
to point serde to the correct base crate.

```rust
/// Main contract structure serialized with Borsh
#[near(contract_state)]
#[derive(PanicOnDefault)]
pub struct Contract {
pub pair: Pair,
}

/// Implements both `serde` and `borsh` serialization.
/// `serde` is typically useful when returning a struct in JSON format for a frontend.
#[near(serializers = [json, borsh])]
pub struct Pair {
pub a: u32,
pub b: u32,
}

#[near]
impl Contract {
#[init]
pub fn new(pair: Pair) -> Self {
Self {
pair,
}
}

pub fn get_pair(self) -> Pair {
self.pair
}
}
```

## `std::panic!` vs `env::panic`

- `std::panic!` panics the current thread. It uses `format!` internally, so it can take arguments.
SDK sets up a panic hook, which converts the generated `PanicInfo` from `panic!` into a string and uses `env::panic` internally to report it to Runtime.
This may provide extra debugging information such as the line number of the source code where the panic happened.

- `env::panic` directly calls the host method to panic the contract.
It doesn't provide any other extra debugging information except for the passed message.

## Use workspaces

Workspaces allow you to automate workflows and run tests for multiple contracts and cross-contract calls in a sandbox or testnet environment.
Read more, [workspaces-rs](https://github.com/near/workspaces-rs) or [workspaces-js](https://github.com/near/workspaces-js).
4 changes: 2 additions & 2 deletions docs/2.build/2.smart-contracts/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import {Github} from "@site/src/components/codetabs"

[NEAR accounts](../../1.concepts/protocol/account-model.md) can host programs known as smart contracts. Smart contracts can **store data**, and **expose functions** so other users and contracts interact with them.
Welcome! [NEAR accounts](../../1.concepts/protocol/account-model.md) can store small apps known as smart contracts. In this quick tutorial, we will guide you in creating your first contract in the NEAR **testnet**!

In this quickstart tutorial, we will guide you in creating your first smart contract in the NEAR **testnet** that stores and retrieves a greeting.
Join us in creating a friendly contract that stores a greeting, and exposes functions to interact with it.

---

Expand Down
22 changes: 21 additions & 1 deletion docs/4.tools/sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,26 @@ import {FeatureList, Column, Feature} from "@site/src/components/featurelist";

The NEAR SDK is a library that allow to develop smart contracts. Currently, there exist two versions of NEAR SDK: one for Rust and one for JavaScript.

:::tip Want to build a smart contract?

The best place to start learning is our [QuickStart Guide](../2.build/2.smart-contracts/quickstart.md)

:::

<FeatureList>
<Column title="" size="6">
<Feature url="https://docs.rs/near-sdk/latest/near_sdk/" title="Rust SDK" subtitle="Rust SDK Reference docs" image="smartcontract-rust.png" />
</Column>
<Column title="" size="6">
<Feature url="https://near.github.io/near-api-js/" title="JavaScript SDK" subtitle="Javascript SDK Reference docs" image="smartcontract-js.png" />
</Column>
</FeatureList>

---

## Smart Contracts on NEAR


This is how a smart contract written in Rust and JavaScript using the NEAR SDK looks like:

<Tabs groupId="code-tabs">
Expand Down Expand Up @@ -97,7 +117,7 @@ If you are new to smart contracts, we recommend you start with our [Smart Contra

If you need to find a specific function signature, or understand the SDK struct/classes, please visit the SDK specific pages:

- [Rust SDK](https://docs.rs/near-sdk/3.1.0/near_sdk/)
- [Rust SDK](https://docs.rs/near-sdk/latest/near_sdk/)
- [JavaScript SDK](https://near.github.io/near-api-js/)

:::tip
Expand Down
4 changes: 2 additions & 2 deletions website/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ const config = {
themeConfig: {
image: 'docs/assets/welcome-pages/protocol.png',
announcementBar: {
id: 'id-0002',
id: 'id-0003',
content:
'🎉 Come check <a href="/blog">our new blog</a>, where we will share weekly news and updates 🎉',
'🎉 We have consolidated all our <a href="/build/smart-contracts/what-is">smart contract docs</a>, read more about it in our <a href="/blog/sdks-unified">blog post</a> 🎉',
backgroundColor: '#fafbfc',
textColor: '#333',
isCloseable: true,
Expand Down
1 change: 1 addition & 0 deletions website/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ const sidebar = {
"type": "html",
"value": "<hr/>"
},
"build/smart-contracts/anatomy/best-practices",
"build/smart-contracts/anatomy/serialization",
"build/smart-contracts/anatomy/serialization-protocols",
"build/smart-contracts/anatomy/reduce-size",
Expand Down
4 changes: 2 additions & 2 deletions website/src/css/custom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,8 @@ https://www.feelback.dev/docs/guides/stripe-like-documentation-feedback-for-docu

/* Announcement bar */
div[class^="announcementBar_"] {
--site-announcement-bar-stripe-color1: #f5fddd;
--site-announcement-bar-stripe-color2: #c4fbcd;
--site-announcement-bar-stripe-color1: #ddfdfd;
--site-announcement-bar-stripe-color2: #cbe3fd;
background: repeating-linear-gradient(45deg, var(--site-announcement-bar-stripe-color1), var(--site-announcement-bar-stripe-color1) 20px, var(--site-announcement-bar-stripe-color2) 10px, var(--site-announcement-bar-stripe-color2) 40px);
font-size: 16px;
font-weight: 600;
Expand Down

0 comments on commit d8b5b47

Please sign in to comment.