• Stars
    star
    453
  • Rank 96,573 (Top 2 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created over 5 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Rust library for writing NEAR smart contracts

near-sdk

Rust library for writing NEAR smart contracts.

Previously known as near-bindgen.

Crates.io version Download Reference Documentation Join the community on Discord GitHub Actions Build

Features | Pre-requisites | Writing Rust Contract | Building Rust Contract | Reference Documentation | Contributing

Release notes

Release notes and unreleased changes can be found in the CHANGELOG

Example

Wrap a struct in #[near_bindgen] and it generates a smart contract compatible with the NEAR blockchain:

use near_sdk::{near_bindgen, env};

#[near_bindgen]
#[derive(Default, BorshDeserialize, BorshSerialize)]
pub struct StatusMessage {
    records: HashMap<AccountId, String>,
}

#[near_bindgen]
impl StatusMessage {
    pub fn set_status(&mut self, message: String) {
        let account_id = env::signer_account_id();
        self.records.insert(account_id, message);
    }

    pub fn get_status(&self, account_id: AccountId) -> Option<String> {
        self.records.get(&account_id).cloned()
    }
}

Features

Unit-testable

Writing unit tests is easy with near-sdk:

#[test]
fn set_get_message() {
    let mut contract = StatusMessage::default();
    contract.set_status("hello".to_string());
    assert_eq!("hello".to_string(), contract.get_status("bob_near".to_string()).unwrap());
}

Run unit test the usual way:

cargo test --package status-message

Asynchronous cross-contract calls

Asynchronous cross-contract calls allow parallel execution of multiple contracts in parallel with subsequent aggregation on another contract. env exposes the following methods:

  • promise_create -- schedules an execution of a function on some contract;
  • promise_then -- attaches the callback back to the current contract once the function is executed;
  • promise_and -- combinator, allows waiting on several promises simultaneously, before executing the callback;
  • promise_return -- treats the result of execution of the promise as the result of the current function.

Follow examples/cross-contract-high-level to see various usages of cross contract calls, including system-level actions done from inside the contract like balance transfer (examples of other system-level actions are: account creation, access key creation/deletion, contract deployment, etc).

Initialization methods

We can define an initialization method that can be used to initialize the state of the contract. #[init] verifies that the contract has not been initialized yet (the contract state doesn't exist) and will panic otherwise.

#[near_bindgen]
impl StatusMessage {
    #[init]
    pub fn new(user: String, status: String) -> Self {
        let mut res = Self::default();
        res.records.insert(user, status);
        res
    }
}

Even if you have initialization method your smart contract is still expected to derive Default trait. If you don't want to disable default initialization, then you can prohibit it like this:

impl Default for StatusMessage {
    fn default() -> Self {
        near_sdk::env::panic_str("Contract should be initialized before the usage.")
    }
}

You can also prohibit Default trait initialization by using near_sdk::PanicOnDefault helper macro. E.g.:

#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize, PanicOnDefault)]
pub struct StatusMessage {
    records: HashMap<String, String>,
}

Payable methods

We can allow methods to accept token transfer together with the function call. This is done so that contracts can define a fee in tokens that needs to be payed when they are used. By the default the methods are not payable and they will panic if someone will attempt to transfer tokens to them during the invocation. This is done for safety reason, in case someone accidentally transfers tokens during the function call.

To declare a payable method simply use #[payable] decorator:

#[payable]
pub fn my_method(&mut self) {
...
}

Private methods

Usually, when a contract has to have a callback for a remote cross-contract call, this callback method should only be called by the contract itself. It's to avoid someone else calling it and messing the state. Pretty common pattern is to have an assert that validates that the direct caller (predecessor account ID) matches to the contract's account (current account ID). Macro #[private] simplifies it, by making it a single line macro instead and improves readability.

To declare a private method use #[private] decorator:

#[private]
pub fn my_method(&mut self) {
...
}
/// Which is equivalent to

pub fn my_method(&mut self ) {
    if near_sdk::env::current_account_id() != near_sdk::env::predecessor_account_id() {
        near_sdk::env::panic_str("Method my_method is private");
    }
...
}

Now, only the account of the contract itself can call this method, either directly or through a promise.

Pre-requisites

To develop Rust contracts you would need to:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  • Add wasm target to your toolchain:
rustup target add wasm32-unknown-unknown

Writing Rust Contract

You can follow the examples/status-message crate that shows a simple Rust contract.

The general workflow is the following:

  1. Create a crate and configure the Cargo.toml similarly to how it is configured in examples/status-message/Cargo.toml;

  2. Crate needs to have one pub struct that will represent the smart contract itself:

    • The struct needs to implement Default trait which NEAR will use to create the initial state of the contract upon its first usage;
    • The struct also needs to implement BorshSerialize and BorshDeserialize traits which NEAR will use to save/load contract's internal state;

    Here is an example of a smart contract struct:

    use near_sdk::{near_bindgen, env};
    
    #[near_bindgen]
    #[derive(Default, BorshSerialize, BorshDeserialize)]
    pub struct MyContract {
        data: HashMap<u64, u64>
    }
  3. Define methods that NEAR will expose as smart contract methods:

    • You are free to define any methods for the struct but only public methods will be exposed as smart contract methods;
    • Methods need to use either &self, &mut self, or self;
    • Decorate the impl section with #[near_bindgen] macro. That is where all the M.A.G.I.C. (Macros-Auto-Generated Injected Code) happens;
    • If you need to use blockchain interface, e.g. to get the current account id then you can access it with env::*;

    Here is an example of smart contract methods:

    #[near_bindgen]
    impl MyContract {
        pub fn insert_data(&mut self, key: u64, value: u64) -> Option<u64> {
            self.data.insert(key)
        }
        pub fn get_data(&self, key: u64) -> Option<u64> {
            self.data.get(&key).cloned()
        }
    }

Building Rust Contract

cargo-near

This can be used as an alternative, to allow building while also generating an abi

# Install the near extension if you haven't already
cargo install cargo-near

# Builds the wasm contract and ABI into `target/near`
cargo near build --release

Using cargo build

RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release

Building with reproducible builds

Since WebAssembly compiler includes a bunch of debug information into the binary, the resulting binary might be different on different machines. To be able to compile the binary in a reproducible way, we added a Dockerfile that allows to compile the binary.

Use contract-builder

NEAR contract standards

near-contract-standards crate provides a set of interfaces and implementations for NEAR's contract standards:

Versioning

Semantic Versioning

This crate follows Cargo's semver guidelines.

State breaking changes (low-level serialization format of any data type) will be avoided at all costs. If a change like this were to happen, it would come with a major version and come with a compiler error. If you encounter one that does not, open an issue!

MSRV

The minimum supported Rust version is currently 1.69. There are no guarantees that this will be upheld if a security patch release needs to come in that requires a Rust toolchain increase.

Contributing

If you are interested in contributing, please look at the contributing guidelines.

More Repositories

1

nearcore

Reference client for NEAR Protocol
Rust
2,324
star
2

borsh

Binary Object Representation Serializer for Hashing
430
star
3

near-api-js

JavaScript library to interact with NEAR Protocol via RPC API
TypeScript
390
star
4

create-near-app

Create a starter app hooked up to the NEAR blockchain
JavaScript
348
star
5

core-contracts

Core contracts: reference staking pool, lockup, voting, whitelist, multisig.
Rust
324
star
6

borsh-rs

Rust implementation of Binary Object Representation Serializer for Hashing
Rust
320
star
7

NEPs

The Near Enhancement Proposals repository
JavaScript
214
star
8

near-wallet

Web wallet for NEAR Protocol which stores keys in browser's localStorage
JavaScript
209
star
9

near-cli

General purpose command line tools for interacting with NEAR Protocol
JavaScript
194
star
10

near-sdk-js

Tools for building NEAR smart contracts in JavaScript
TypeScript
192
star
11

assemblyscript-json

JSON encoder / decoder for AssemblyScript
TypeScript
173
star
12

wallet-selector

This is a wallet selector modal that allows users to interact with NEAR dApps with a selection of available wallets.
TypeScript
151
star
13

docs

NEAR Protocol Documentation
SCSS
147
star
14

near-indexer-for-explorer

Watch NEAR network and store all the data from NEAR blockchain to PostgreSQL database
Rust
123
star
15

near-sdk-as

Tools for building NEAR smart contracts in AssemblyScript
TypeScript
114
star
16

nearup

Public scripts to launch NEAR Protocol betanet and testnet node
Python
102
star
17

near-cli-rs

near CLI is your human-friendly companion that helps to interact with NEAR Protocol from command line.
Rust
100
star
18

borsh-js

TypeScript/JavaScript implementation of Binary Object Representation Serializer for Hashing
JavaScript
89
star
19

stakewars-iii

Stake Wars: Episode 3 challenges and place to report issues
87
star
20

near-workspaces-rs

Write tests once, run them both on NEAR TestNet and a controlled NEAR Sandbox local environment via Rust
Rust
84
star
21

near-explorer

NEAR blockchain explorer
TypeScript
82
star
22

bounties

Specs for technical and non-technical work that earns NEAR tokens
72
star
23

near-linkdrop

Contract to drop tokens via link
Rust
55
star
24

borsh-go

Go implementation of Binary Object Representation Serializer for Hashing
Go
51
star
25

near-api-py

Python API to interact with NEAR via RPC API
Python
51
star
26

near-discovery

The homebase for Near Builders
TypeScript
49
star
27

near-lake-framework-rs

Library to connect to the NEAR Lake S3 and stream the data
Rust
47
star
28

near-jsonrpc-client-rs

Lower-level API for interfacing with the NEAR Protocol via JSONRPC.
Rust
47
star
29

near-lake-indexer

Watch NEAR network and store all the events as JSON files on AWS S3
Rust
45
star
30

near-sandbox

Easily run a local NEAR blockchain
TypeScript
44
star
31

near-workspaces-js

Write tests once, run them both on NEAR TestNet and a controlled NEAR Sandbox local environment
TypeScript
42
star
32

near-sdk-contract-tools

Helpful functions and macros for developing smart contracts on NEAR Protocol.
Rust
41
star
33

mpc

Rust
41
star
34

awesome-near

Curated list of resources: examples, libraries, projects
TypeScript
40
star
35

ecosystem

Community-sourced and curated data for the NEAR Ecosystem.
Python
39
star
36

data-availability

NEAR as data availability!
Rust
39
star
37

near-seed-phrase

Utilities to work with NEAR Protocol key pairs based on BIP39 seed phrases
JavaScript
38
star
38

community

Coordination repository of Near Community
36
star
39

near-contract-helper

Micro-service used by NEAR Wallet to store & send recovery methods
JavaScript
35
star
40

cargo-near

Cargo extension for building Rust smart contracts on NEAR
Rust
33
star
41

near-evm

Obsolete EVM contract experiments. Find current development at: https://github.com/aurora-is-near/aurora-engine
Rust
33
star
42

fast-auth-signer

TypeScript
30
star
43

pagoda-relayer-rs

Rust Reference Implementation of Relayer for NEP-366 Meta Transactions
Rust
29
star
44

wiki

NEAR Wiki
JavaScript
28
star
45

bos-web-engine

Improved execution layer for NEAR decentralized frontend components
TypeScript
26
star
46

borsh-construct-py

Python implementation of Binary Object Representation Serializer for Hashing
Python
26
star
47

near-lake-framework-js

JS Library to connect to the NEAR Lake S3 and stream the data
TypeScript
25
star
48

DX

Developer Experience building on NEAR
25
star
49

finite-wasm

Cheating a little to solve the halting problem at scale
WebAssembly
23
star
50

near-api-swift

Interact with NEAR blockchain from iOS and OS X apps using Swift
Swift
22
star
51

corgis

simple solution for corgi NFT
JavaScript
22
star
52

wasmer

🚀 The leading WebAssembly Runtime supporting WASI and Emscripten
Rust
21
star
53

near-analytics

Python
20
star
54

sdk-docs

The book about near-sdk-rs
JavaScript
20
star
55

neardevhub-widgets

NEAR DevHub UI hosted on NEAR BOS
JavaScript
20
star
56

near-api-kotlin

Kotlin
20
star
57

bos-loader

Rust
19
star
58

near-enhanced-api-server

Rust
18
star
59

read-rpc

Read-only NEAR RPC centralized-like performant solution
Rust
18
star
60

queryapi

Near Indexing as a Service
Rust
17
star
61

near-redpacket

NEAR Redpacket based on NEAR Linkdrop
CSS
14
star
62

near-discovery-components

This is a repository that holds the source code of all NEAR discovery components that the team maintains for near.org.
JavaScript
14
star
63

near-vscode

https://marketplace.visualstudio.com/items?itemName=near-protocol.near-discovery-ide
JavaScript
14
star
64

stakewars-iv

Shell
12
star
65

omni-transaction-rs

Transaction builder for all chains in Rust
Rust
12
star
66

neardevhub-contract

NEAR DevHub contract
Rust
11
star
67

abi

NEAR contract schema and tooling
11
star
68

borshj

Borsh binary serialization format support for Java.
Java
11
star
69

near-sdk-js-template-project

A starting point to write, build and test JavaScript smart contract
JavaScript
11
star
70

near-memory-tracker

near-memory-tracker
Rust
11
star
71

devx

This is the home of NEAR collective developer experience plans and roadmap.
11
star
72

node-docs

NEAR Nodes documentation
CSS
11
star
73

cargo-near-new-project-template

temp project to become part of `cargo near new` command
Rust
11
star
74

rainbow-bridge-lib

JavaScript
10
star
75

rainbow-bridge-sol

Solidity
10
star
76

devrel

The space for DevRel
9
star
77

units-js

Easily parse and format NEAR Tokens and gas units
TypeScript
9
star
78

rainbow-bridge-rs

Rust
9
star
79

near-microindexers

Rust
8
star
80

near-api-unity

Port of https://github.com/near/near-api-js to Unity
C#
8
star
81

near-wallet-roadmap

near-wallet-roadmap
8
star
82

multichain-gas-station-contract

Rust
8
star
83

near-drop-demo

JavaScript
7
star
84

near-indexer-events

Rust
7
star
85

near-sdk-abi

ABI utilities used for generating Rust SDK cross-contract calls
Rust
6
star
86

repro-near-funcall

Repro near function call actions with local near-vm-runner-standalone
JavaScript
6
star
87

as-base64

Encode and Decode base64 strings in AssemblyScript
WebAssembly
6
star
88

near-indexer-for-wallet

Rust
6
star
89

near-ledger-js

Connect to NEAR Ledger app from browser
JavaScript
6
star
90

boilerplate-template-keypom

A github template repository of an end-to-end application that demonstrates minimal UI to build a lazy-minted NFT link drop using Keypom
TypeScript
6
star
91

near-abi-rs

NEAR smart contract ABI primitives
Rust
6
star
92

near-workspaces

Write tests once, run them both on NEAR TestNet and a controlled NEAR Sandbox local environment
6
star
93

near-abi-client-rs

Library to generate Rust client code from NEAR ABI
Rust
5
star
94

discovery-docs

NEAR Discovery Documentation
JavaScript
5
star
95

near-api-helper

Cloudflare worker that can batch RPC calls
JavaScript
5
star
96

local

5
star
97

boilerplate-template-rs

TypeScript
5
star
98

wasm_sizer

Python
5
star
99

multisig-tool

A tool / UI to manage multisig contracts
JavaScript
5
star
100

near-blake2

Pure Rust implementation of the BLAKE2 hash function family.
Rust
5
star