# \[Announcement\] near-contract-tools - functions and macros for developing Rust smart contracts on NEAR

**URL:** <https://gov.near.org/t/announcement-near-contract-tools-functions-and-macros-for-developing-rust-smart-contracts-on-near/29341>\
**Category:** Projects\
**Tags:** development\
**Created:** [September 22, 2022, 8:36am UTC](https://gov.near.org/t/announcement-near-contract-tools-functions-and-macros-for-developing-rust-smart-contracts-on-near/29341 "2022-09-22T08:36:28Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jacob](https://dub1.discourse-cdn.com/flex005/user_avatar/gov.near.org/jacob/32/2239_2.png) [@jacob](https://gov.near.org/u/jacob)\
**Post date:** [September 22, 2022, 8:36am UTC](https://gov.near.org/t/announcement-near-contract-tools-functions-and-macros-for-developing-rust-smart-contracts-on-near/29341/1 "2022-09-22T08:36:28Z")

</div>

# Introducing: `near-contract-tools`

[![](https://img.shields.io/crates/d/near-contract-tools)](https://crates.io/crates/near-contract-tools) [![](https://img.shields.io/crates/v/near-contract-tools)](https://crates.io/crates/near-contract-tools) [![](https://img.shields.io/github/stars/NEARFoundation/near-contract-tools?style=social)](https://github.com/NEARFoundation/near-contract-tools)

> Helpful functions and macros for developing smart contracts on NEAR Protocol.

The goal of [`near-contract-tools`](https://crates.io/crates/near-contract-tools) is to provide secure-by-default, drop-in components to compose smart contracts for NEAR Protocol. `near-contract-tools` is a collection of common tools and patterns for NEAR smart contract development which make source code cleaner, easier to read, and more flexible.

Projects using `near-contract-tools` can:

- write an NEP-141 fungible token in _two_ lines of code,
- fearlessly manage storage keys,
- create NEP-297 events with a single macro invocation,
- easily implement role-based permissioning, contract ownership, and pausability,
- add highly customizable multisig functionality,
- and more!

_ **THIS IS STILL EARLY SOFTWARE** : WE ARE LOOKING FOR PEOPLE WILLING TO TEST THIS LIBRARY IN PREPARATION FOR ITS 1.0 RELEASE._

- [Repository](https://github.com/NEARFoundation/near-contract-tools)
- [Crates.io](https://crates.io/crates/near-contract-tools)
- [Documentation](https://docs.rs/near-contract-tools/)

## Background

The NEAR Foundation formed the new Engineering team to provide in-house software developmentto accelerate the NEAR ecosystem. The Engineering team has been hard at work on `near-contract-tools` to support a wide-range of smart contract needs.

If `near-sdk` is the atoms of your smart contract, `near-contract-tools` is the molecules.

## Design Principles

- **Developer experience.** This library is written by Rust developers, for Rust developers, so the patterns are implemented in the way most natural for Rust.
- **“Just Works.”** Sane defaults; extra options are there if you want to dive deeper.
- **Modular.** Although there is a `FungibleToken` composite macro, each standard (NEP-141, NEP-148) is implemented completely independently.
- **Non-invasive.** You can add `near-contract-tools` to your project and just use one of the components: it doesn’t require that you use, for example, the `Owner` component in order to use the `Migrate` component. However, if you do want this functionality, it is simple to get the components to work together.
- **Concise.** Macro usage is optional, but preferred.

## Core Components

- Approval
  - Multisig

- NEP Standards
  - NEP-141 (Fungible Token Core)
  - NEP-148 (Fungible Token Metadata)
  - NEP-297 (Events)

- State migration
- Upgradability
- Ownership
- Pausability
- Role-based access control
- Storage slots calculated at compile time
- (miscellaneous other utilities)

## Installation

Add `near-contract-tools` to your Rust smart contract using `cargo`:

```auto
$ cargo add near-contract-tools

```

## Examples

### Fungible Token 2-liner

```rust
// add these lines:
#[derive(near_contract_tools::FungibleToken)]
#[fungible_token(name = "My Fungible Token", symbol = "MYFT", decimals = 24, no_hooks)]
// that's it!
#[near_sdk::near_bindgen]
struct MyFungibleTokenContract { }
// no need to put anything in the default struct

```

Use it:

```rust
#[near_sdk::near_bindgen]
impl MyFungibleTokenContract {
    pub fn send_half_my_balance_to(&mut self, account_id: near_sdk::AccountId) {
        // Nep141 functions are available to the public blockchain
        use near_contract_tools::standard::nep141::Nep141;

        // ft_* functions are defined!
        let balance: u128 = self.ft_balance_of(account_id.clone()).into();
        let send = balance / 2;
        near_sdk::require!(send > 0, "You don't have enough money!");
        self.ft_transfer(
            account_id,
            send.into(),
            Some("Half my balance!".to_string()),
        );
    }

    pub fn double_my_balance(&mut self) {
        // Nep141Controller functions are not available to the public blockchain
        use near_contract_tools::standard::nep141::{Nep141, Nep141Controller};

        let predecessor = near_sdk::env::predecessor_account_id();
        let balance = self.ft_balance_of(predecessor.clone());
        // Here's one of those non-public functions
        self.mint(&predecessor, balance.into(), Some("Doubling my balance!"));
    }
}

```

### NEP-297 Events

```rust
use near_contract_tools::{event, standard::nep297::Event};
use near_sdk::{AccountId, json_types::U128};

// Definition
#[event(standard = "ft_event", version = "1.0.0")]
pub struct FtMint {
    pub owner_id: AccountId,
    pub amount: U128,
}

#[event(standard = "ft_event", version = "1.0.0")]
pub struct FtTransfer {
    pub old_owner_id: AccountId,
    pub new_owner_id: AccountId,
    pub amount: U128,
}

// ...

```

Use it:

```rust
FtMint {
    owner_id: "owner".parse().unwrap(),
    amount: 100.into(),
}
.emit();

```

* * *

[Check out more example code.](https://github.com/NEARFoundation/near-contract-tools/tree/develop/workspaces-tests/src/bin)

## Build contracts _fast_ with `near-contract-tools`!

`near-contract-tools` improves the smart contract development experience on NEAR Protocol. It comes with macros that work out-of-the-box, providing developers with patterns that are often copy-pasted across projects. `near-contract-tools` is highly modular, and each component is opt-in. Developers can extend the components with custom functionality and use them alongside the rest of the library.

This is one more tool to help you build without limits!

---

<div class="post-metadata">

**Author:** ![kenjon](https://dub1.discourse-cdn.com/flex005/user_avatar/gov.near.org/kenjon/32/40789_2.png) [@kenjon](https://gov.near.org/u/kenjon)\
**Post date:** [September 22, 2022, 10:02am UTC](https://gov.near.org/t/announcement-near-contract-tools-functions-and-macros-for-developing-rust-smart-contracts-on-near/29341/2 "2022-09-22T10:02:40Z")

</div>

Hey @encody great work on this project!

Can you talk about the differences between the multisig used in near-contract-tools as opposed to: [core-contracts/multisig2 at master · near/core-contracts · GitHub](https://github.com/near/core-contracts/tree/master/multisig2).

Also could you explain storage slots being calculated at compile time. What are the major benefits and are there any security risks that developers should be aware of when using this storage slot pattern?

---

<div class="post-metadata">

**Author:** ![sandoche](https://dub1.discourse-cdn.com/flex005/user_avatar/gov.near.org/sandoche/32/42255_2.png) [@sandoche](https://gov.near.org/u/sandoche)\
**Post date:** [September 22, 2022, 10:20am UTC](https://gov.near.org/t/announcement-near-contract-tools-functions-and-macros-for-developing-rust-smart-contracts-on-near/29341/3 "2022-09-22T10:20:33Z")

</div>

The OpenZeppelin for the NEAR Dapps! Congrats @jacob !

---

<div class="post-metadata">

**Author:** ![Ryan.Walsh](https://dub1.discourse-cdn.com/flex005/user_avatar/gov.near.org/ryan.walsh/32/13659_2.png) [@Ryan.Walsh](https://gov.near.org/u/Ryan.Walsh)\
**Post date:** [September 22, 2022, 2:43pm UTC](https://gov.near.org/t/announcement-near-contract-tools-functions-and-macros-for-developing-rust-smart-contracts-on-near/29341/4 "2022-09-22T14:43:30Z")

</div>

@jacob This looks great! I think you could copy most or all of this post and put it in the Readme, too.

---

<div class="post-metadata">

**Author:** ![jacob](https://dub1.discourse-cdn.com/flex005/user_avatar/gov.near.org/jacob/32/2239_2.png) [@jacob](https://gov.near.org/u/jacob)\
**Post date:** [September 23, 2022, 1:14am UTC](https://gov.near.org/t/announcement-near-contract-tools-functions-and-macros-for-developing-rust-smart-contracts-on-near/29341/5 "2022-09-23T01:14:20Z")

</div>

The [multisig implementation](https://github.com/NEARFoundation/near-contract-tools/tree/develop/src/approval) in `near-contract-tools` is split into a few parts. First, there’s the `Approval` component, which manages the approval process for and execution of actions. This makes it easy to write different approval schemes (e.g. _n_ of _m_ (provided), governance token holding, etc.) and different action types, which can then be mixed-and-matched. For the typical multisig wallet, an action would simply be any arbitrary transaction, and since this is a common use-case, `near-contract-tools` provides `NativeTransactionAction`, which is a thin wrapper around the native transaction action kinds.

Storage slots are a way to increase storage efficiency by calculating storage keys instead of storing them. You can explore the differences between these two contracts:

- [Fungible Token](https://explorer.testnet.near.org/accounts/dev-1663695129778-86910052656745) with `near-contract-standards` (note that this also implements the storage management standard, so it is not exactly a apples-to-apples comparison)
- [Fungible Token](https://explorer.testnet.near.org/accounts/dev-1663843615170-10123516049715) with `near-contract-tools`

The benefits of using storage slots:

- Reduces storage I/O cycles, since `STATE` deserialization is not necessary
- Reduces the amount of data put in storage
- It is easier to find potential key collisions since all of the information needed to calculate a key is in the contract code and not split across the code and the storage
