NEAR-Protokoll und Solana

9 min read
Near Protocol and Solana
To Share and +4 nLEARNs

Heute wollen wir uns zwei der vielversprechendsten Smart-Contract-Plattformen der Welt ansehen – Near Protocol und Solana. Ethereum dominiert zwar nach wie vor diesen Markt, doch die mangelnde Skalierbarkeit und die hohen Gebühren für Transaktionen haben die meisten Entwickler dazu gezwungen, nach praktikablen Alternativen zu suchen. Near und Solana haben sich als die beiden Spitzenreiter herauskristallisiert.

Was ist Solana?

Solana wurde 2017 von Anatoly Yakovenko gegründet, der zuvor bei DropBox gearbeitet hatte. Yakovenko schuf Solana zusammen mit Eric Williams und CTO Greg Fritzgerald, um die bestehenden Probleme in Bitcoin und Ethereum zu lösen. Das Projekt hat Investitionen von Multicoin Capital, Foundation Capital, SLOW Capital, CMCC Global, Abstract Ventures und anderen angezogen.

NEAR Solana

Merkmale der Solana-Blockchain

  • 50.000 Transaktionen pro Sekunde und 0,4 Sekunden Blockzeit
  • Das System kann 28,4 Millionen Transaktionen pro Sekunde in einem 40-Gigabit-Netzwerk durchführen.
  • Solana verwendet den Proof-of-History-Konsensalgorithmus.

Wie funktioniert der Proof-of-History (PoH)?

In einem dezentralen Netzwerk, das sich über ein großes Gebiet erstreckt, ist ein Konsens unerlässlich. Bitcoin verwendet den Proof-of-Work-Konsens (PoW), um den Konsens zu gewährleisten. Obwohl diese Methode sehr sicher ist, kann man ihr größtes Problem nicht ignorieren – die fehlende Skalierbarkeit. Man darf nicht vergessen, dass Bitcoin nur 7 Transaktionen pro Sekunde durchführen kann.

Solana verwendet Proof-of-History, d.h. es erstellt historische Aufzeichnungen, um zu beweisen, dass ein Ereignis zu einem bestimmten Zeitpunkt stattgefunden hat. Hier sind einige Punkte, die Sie im Auge behalten müssen:

  • Der Algorithmus verwendet eine hochfrequente Verifizierbare Verzögerungsfunktion, die eine bestimmte Anzahl von aufeinanderfolgenden Schritten benötigt, um abgeschlossen zu werden.
  • Die im Netzwerk getakteten Transaktionen oder Ereignisse werden mit einem eindeutigen Hashwert versehen, der öffentlich verifiziert werden kann.
  • Anhand der Zählung kann das Netz genau feststellen, wann die Transaktion oder das Ereignis stattgefunden hat.
  • Jeder Knoten verfügt über eine kryptografische Uhr, mit deren Hilfe die Netzwerkzeit und die Reihenfolge der Ereignisse verfolgt werden können.

Dank PoH unterstützt das Solana-Netzwerk 50.000 Transaktionen pro Sekunde, während es mit GPUs läuft. 

Was ist ein Solana-Cluster?

Ein Cluster ist eine Gruppe unabhängiger Computer, die zusammenarbeiten und als ein einziges System betrachtet werden können. Die Hauptmerkmale des Clusters sind wie folgt:

  • Sie helfen bei der Überprüfung der Ausgabe von nicht vertrauenswürdigen, vom Benutzer eingereichten Programmen. 
  • Er führt Aufzeichnungen über jede Transaktion oder jedes Ereignis, das ein Benutzer durchführt.
  • Es wird festgehalten, welche Computer sinnvolle Arbeit geleistet haben, um das Netzwerk am Laufen zu halten.
  • Es verfolgt den Besitz von realen Gütern.

Which of the following utilizes sharding?

Correct! Wrong!

Programmierung in Solana

Die Smart Contracts in Solana werden in Rust oder C geschrieben und in Berkeley Packet Filter (BPF) Bytecode kompiliert. Da mehr Werkzeuge zur Verfügung stehen, ist es empfehlenswert, in Rust zu programmieren. Anfänger sollten ihre Programme unter Verwendung des Anchor-Frameworks programmieren, das die Ausführung vereinfacht.

Solana hat ein einzigartiges Kontomodell, das den Dateien im Linux-Betriebssystem ähnelt. Sie können beliebige Daten aufnehmen und enthalten auch Metadaten darüber, wie auf sie zugegriffen werden kann. Beachten Sie jedoch, dass die Konten eine feste Größe haben und nicht in der Größe verändert werden können. 

Das derzeitige Programmiermodell von Solana zwingt Sie möglicherweise dazu, die Anwendungslogik aus der Kette auszulagern oder die Funktionalität so zu modifizieren, dass sie ineffizient und durch die feste Kontengröße eingeschränkt ist.

Which of the following is an integral part of Solana?

Correct! Wrong!

Beispielvertrag

#![feature(proc_macro_hygiene)]

use anchor_lang::prelude::*;
use anchor_spl::token::{self, TokenAccount, Transfer};

#[program]
pub mod plutocratic_hosting {
    use super::*;

    /// Initialize a new contract with initialized content.
    #[access_control(Initialize::validate(&ctx, nonce))]
    pub fn initialize(
        ctx: Context<Initialize>,
        price: u64,
        content: String,
        nonce: u8,
    ) -> ProgramResult {

        // Transfer funds to the contract vault.
        let cpi_accounts = Transfer {
            from: ctx.accounts.from.to_account_info().clone(),
            to: ctx.accounts.vault.to_account_info().clone(),
            authority: ctx.accounts.owner.clone(),
        };
        let cpi_program = ctx.accounts.token_program.clone();
        let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
        token::transfer(cpi_ctx, price)?;

        // Initialize the content data.
        let content_record = &mut ctx.accounts.content;
        content_record.price = price;
        content_record.content = content;
        content_record.nonce = nonce;
        content_record.owner = *ctx.accounts.owner.to_account_info().key;
        content_record.vault = *ctx.accounts.vault.to_account_info().key;
        Ok(())

    }

    /// Purchase content address for new price, if transferring more tokens.
    #[access_control(check_funds(&ctx.accounts.content, price))]
    pub fn purchase(ctx: Context<Purchase>, price: u64, content: String) -> ProgramResult {
        // Transfer funds from contract back to owner.
        let seeds = &[
            ctx.accounts.content.to_account_info().key.as_ref(),
            &[ctx.accounts.content.nonce],
        ];
        let signer = &[&seeds[..]];
        let cpi_accounts = Transfer {
            from: ctx.accounts.vault.to_account_info().clone(),
            to: ctx.accounts.owner_token.to_account_info().clone(),
            authority: ctx.accounts.contract_signer.clone(),
        };
        let cpi_program = ctx.accounts.token_program.clone();
        let cpi_ctx = CpiContext::new_with_signer(cpi_program, cpi_accounts, signer);
        token::transfer(cpi_ctx, ctx.accounts.content.price)?;

        // Transfer funds from new owner to contract.
        let cpi_accounts = Transfer {
            from: ctx.accounts.new_owner_token.to_account_info().clone(),
            to: ctx.accounts.vault.to_account_info().clone(),
            authority: ctx.accounts.new_owner.clone(),
        };
        let cpi_program = ctx.accounts.token_program.clone();
        let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
        token::transfer(cpi_ctx, price)?;

        // Overwrite content
        let content_record = &mut ctx.accounts.content;
        content_record.price = price;
        content_record.content = content;
        content_record.owner = *ctx.accounts.new_owner.to_account_info().key;

        Ok(())
    }
}

#[account]
pub struct ContentRecord {
    /// Price at which the current content is owned.
    pub price: u64,
    /// Content Data.
    pub content: String,
    /// Public key of current owner of the content.
    pub owner: Pubkey,
    /// Address for token program of funds locked in contract.
    pub vault: Pubkey,
    /// Nonce for the content, to create valid program derived addresses.
    pub nonce: u8,
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(init)]
    content: ProgramAccount<'info, ContentRecord>,
    #[account(mut, "&vault.owner == contract_signer.key")]
    vault: CpiAccount<'info, TokenAccount>,
    /// Program derived address for the contract.
    contract_signer: AccountInfo<'info>,
    /// Token account the contract is made from.
    #[account(mut, has_one = owner)]
    from: CpiAccount<'info, TokenAccount>,
    /// Owner of the `from` token account.
    owner: AccountInfo<'info>,
    token_program: AccountInfo<'info>,
    rent: Sysvar<'info, Rent>,
}


impl<'info> Initialize<'info> {
    pub fn validate(ctx: &Context<Self>, nonce: u8) -> Result<()> {
        let signer = Pubkey::create_program_address(
            &[
                ctx.accounts.content.to_account_info().key.as_ref(),
                &[nonce],
            ],
            ctx.program_id,
        )
        .map_err(|_| ErrorCode::InvalidNonce)?;
        if &signer != ctx.accounts.contract_signer.to_account_info().key {
            return Err(ErrorCode::InvalidSigner.into());
        }
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Purchase<'info> {
    #[account(mut, has_one = vault)]
    content: ProgramAccount<'info, ContentRecord>,
    #[account(mut)]
    vault: CpiAccount<'info, TokenAccount>,
    #[account(seeds = [
        content.to_account_info().key.as_ref(),
        &[content.nonce],
    ])]
    contract_signer: AccountInfo<'info>,
    #[account(mut, has_one = owner)]
    owner_token: CpiAccount<'info, TokenAccount>,
    #[account(mut)]
    new_owner_token: CpiAccount<'info, TokenAccount>,
    #[account(signer)]
    new_owner: AccountInfo<'info>,
    owner: AccountInfo<'info>,
    token_program: AccountInfo<'info>,
}

fn check_funds(check: &ContentRecord, new_price: u64) -> Result<()> {
    if check.price >= new_price {
        return Err(ErrorCode::InsufficientFunds.into());
    }

    Ok(())
}

#[error]
pub enum ErrorCode {
    #[msg("The given nonce does not create a valid program derived address.")]
    InvalidNonce,
    #[msg("The derived signer does not match that which was given.")]
    InvalidSigner,
    #[msg("Insufficient funds provided to purchase route.")]
    InsufficientFunds,
}

Was geschieht in dem Vertrag?

  • Alle Konten, auf die zugegriffen werden soll, sind in der Struktur für jeden Aufruf mit #[derive(Accounts)] vermerkt. 
  • Die Funktionen helfen, die Kontodaten für den anfänglichen Besitzer und den Kauf zu initialisieren. Dadurch kann jeder das Konto für weitere Token kaufen. 
  • Temporäre Daten werden als Funktionsparameter übergeben. Diese Parameter befinden sich innerhalb der Funktionen initialize und purchase. Dazu gehört auch der Kontext, in dem die für die Transaktion erforderlichen Konten geführt werden.
  • Der Zustand des Vertrags befindet sich in der ContentRecord-Struktur. Diese ist zusätzlich mit #[account] annotiert, um anzuzeigen, dass sie das Datenlayout für ein Konto darstellt.

Was ist das NEAR-Protokoll?

Das im Sommer 2018 entstandene Protokoll wurde entwickelt, um die perfekte Umgebung für dezentrale Anwendungen zu schaffen, indem es höhere Geschwindigkeiten, einen höheren Durchsatz und eine bessere Kompatibilität mit anderen Chains bietet. NEAR verfügt über eine einzigartige Sharding-Technik und führt einen Blockgenerierungsmechanismus namens „Doomslug“ ein, der 2019 vorgeschlagen wird. Doomslug ermöglicht eine praktische oder „Doomslug“-Finalität, die sicherstellt, dass die Blöcke innerhalb von Sekunden ihre Finalität erhalten.

Das NEAR-Protokoll wird vom NEAR-Kollektiv entwickelt, einer Gemeinschaft von Entwicklern und Forschern, die an der Entwicklung des Projekts mitarbeiten. Einige wichtige Merkmale von NEAR sind:

  • NEAR ist ein Sharded-System, das eine unendliche Skalierbarkeit ermöglicht. 
  • NEAR ist ein benutzerfreundliches Protokoll, mit dem Entwickler einfach und schnell Anwendungen erstellen können. 
  • NEAR ist keine Side Chain, sondern ein Layer-1-Protokoll. 
  • dApps, die mit NEAR erstellt werden, laufen auf der zugrunde liegenden NEAR-Schicht, also dem Layer 1. 

Was ist das NEAR-Kollektiv? 

Zum NEAR-Kollektiv gehören einzelne Organisationen und andere Mitwirkende, die kontinuierlich an der Verbesserung des NEAR-Protokolls arbeiten. Das Kollektiv arbeitet an Projekten wie dem Schreiben des ursprünglichen Codes und der Implementierung für das NEAR-Netzwerk. NEAR ist vollständig dezentralisiert, arbeitet unabhängig und kann nicht abgeschaltet oder manipuliert werden, auch nicht von denen, die es aufgebaut haben.

Es handelt sich um eine gemeinnützige Organisation, die sich auf die Schaffung eines lebendigen Ökosystems rund um die NEAR-Blockchain konzentriert. Sie hilft bei der Koordination von Governance-Aktivitäten und der Entwicklung. Das NEAR-Kollektiv hat mehrere Projekte, wobei die NEAR-Blockchain nur eines von mehreren Projekten ist, die unter der Ägide des Kollektivs stehen. 

NEAR-Konsens-Mechanismus

Der bei NEAR implementierte Konsensmechanismus heißt Nightshade. Nightshade modelliert das System als eine einzige Blockchain. Die Liste aller Transaktionen in jedem Block wird in physische Chunks aufgeteilt, ein Chunk pro Shard. Alle Chunks werden zu einem Block akkumuliert. Beachten Sie, dass Chunks nur von Knoten validiert werden können, die den Status dieses Shards verwalten.

Apropos Validierung: Eine Schlüsselkomponente von NEAR sind die Validierer. Diese Validatoren sind für die Aufrechterhaltung des Konsenses innerhalb des Protokolls verantwortlich. Validatoren sind spezialisierte Knoten, die ihre Server zu 100 % der Zeit online halten und ihre Systeme ständig aktualisieren müssen. 

Hier sind einige Punkte, die Sie bei den Netzwerk-Validatoren beachten müssen.

  • NEAR bestimmt seine Netzwerk-Validatoren in jeder neuen Epoche und wählt sie auf der Grundlage ihres Einsatzes.
  • Die bereits gewählten Validatoren werden erneut registriert, indem sie automatisch ihre Token und die angesammelten Belohnungen erneut einsetzen.
  • Potenzielle Validatoren müssen einen dynamisch festgelegten Wert überschreiten.
  • Es gibt zwei Methoden, mit denen ein Validator seinen Einsatz erhöhen kann – er kann die Token selbst kaufen oder über die Delegation von Einsätzen leihen.
  • Die Belohnung, die Sie erhalten, ist direkt proportional zu Ihrem Einsatz – je höher Ihr Einsatz, desto höher Ihre Belohnung.

Der Konsens basiert auf dem schwersten Blockchain Konsens. Das heißt, sobald ein Blockproduzent einen Block veröffentlicht, sammelt er die Unterschriften der Validierungsknoten. Das Gewicht eines Blocks ist dann der kumulierte Einsatz aller Unterzeichner, deren Unterschriften in dem Block enthalten sind. Das Gewicht einer Kette ist die Summe der Blockgewichte. Zusätzlich verwendet der Konsens eine Finalitätsfunktion, die zusätzliche Bedingungen für eine höhere Blockchain Sicherheit einführt.

Doomslug” is a block generation mechanism of which protocol?

Correct! Wrong!

Aurora und NEAR-Protokoll

Aurora wurde auch auf dem NEAR-Protokoll eingeführt und bietet eine Ethereum Layer-2 Erfahrung. Aurora verbessert NEAR unter anderem in folgenden Punkten: 

  • Es hilft, den Durchsatz auf Tausende von Transaktionen pro Sekunde zu erhöhen.
  • Eine Block-Finalitätszeit von 2 Sekunden.
  • Zukunftssicheres Wachstum des Ökosystems
  • Niedrige Transaktionsgebühren, die 1000-mal niedriger sind als bei Ethereum.
  • Uneingeschränkte Kompatibilität mit Ethereum.

Beispielvertrag

use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::collections::LookupMap;
use near_sdk::{env, near_bindgen, AccountId, Balance, Promise};

#[global_allocator]
static ALLOC: near_sdk::wee_alloc::WeeAlloc = near_sdk::wee_alloc::WeeAlloc::INIT;

#[derive(BorshDeserialize, BorshSerialize)]
pub struct ContentRecord {
    pub price: Balance,
    pub content: String,
    pub owner: AccountId,
}

#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
pub struct ContentTracker {
    values: LookupMap<String, ContentRecord>,
    contract_owner: AccountId,
}

impl Default for ContentTracker {
    fn default() -> Self {
        let contract_owner = env::predecessor_account_id();
        Self {
            values: LookupMap::new(b"v".to_vec()),
            contract_owner,
        }
    }
}

#[near_bindgen]
impl ContentTracker {
    /// Gets content at a given route.
    pub fn get_route(&self, route: String) -> Option<String> {
        self.values.get(&route).map(|v| v.content)
    }

    /// Purchases a route based on funds sent to the contract.
    #[payable]
    pub fn purchase(&mut self, route: String, content: String) {
        let deposit = env::attached_deposit();
        assert!(deposit > 0);
        if let Some(entry) = self.values.get(&route) {
            assert!(
                deposit > entry.price,
                "Not enough deposit to purchase route, price: {} deposit: {}",
                entry.price,
                deposit
            );


            // Refund purchase to existing owner
            Promise::new(entry.owner).transfer(entry.price);
        }


        // Update record for the contract state.
        self.values.insert(
            &route,
            &ContentRecord {
                price: deposit,
                content,
                owner: env::predecessor_account_id(),
            },
        );
    }


    /// Allows owner of the contract withdraw funds.
    pub fn withdraw(&mut self) {
        assert_eq!(env::predecessor_account_id(), self.contract_owner);


        // Send the contract funds to the contract owner
        Promise::new(self.contract_owner.clone()).transfer(env::account_balance());
    }
}

Was ist in dem Vertrag geregelt?

Was steht nun in dem Vertrag? Schauen wir uns das mal genauer an.

  • Der Vertrag wird durch #[near_bindgen] im ContentTracker definiert. Er ähnelt einem Konstruktor in Solidity und wird aufgerufen, wenn der Vertrag bereitgestellt wird.
  • Die Kauffunktion ist mit #[payable] annotiert.
  • Der Vertrag enthält asynchrone Aufrufe in Form von Promise::new(…).transfer(…); Zeilen.
  • Die Datenstruktur LookupMap<String, ContentRecord> behandelt die Schlüssel-Wert-Suche, die auf den Speicher zugreift. Dies entspricht dem Solidity-„Mapping“.

Schlussfolgerung

Sowohl Solana als auch NEAR Protocol sind brillante Smart-Contract-Plattformen, die eine sehr aktive Community aufgebaut haben. Beide bringen spezielle Funktionen mit, die helfen, das größte Problem der dezentralen Welt zu bekämpfen – Geschwindigkeit. Beide Plattformen befinden sich noch im Wachstum und sind vielversprechend.

40
Scroll to Top