NEAR Protocole et Solana

Qu’est-ce que Solana ?

Solana a été fondée en 2017 par Anatoly Yakovenko, qui avait auparavant travaillé chez DropBox. Yakovenko, avec Eric Williams et CTO Greg Fritzgerald, a créé Solana pour résoudre les problèmes existants dans Bitcoin et Ethereum. Le projet a attiré des investissements de Multicoin Capital, Foundation Capital, SLOW Capital, CMCC Global, Abstract Ventures, etc.

Caractéristiques de la blockchain Solana

● 50 000 transactions par seconde et 0,4 seconde de temps de bloc
● Le système peut fournir 28,4 millions de transactions par seconde sur un réseau de 40 gigabits.
● Solana utilise l’algorithme de consensus Proof-of-History.

Comment fonctionne la preuve d’histoire (PoH) ?

Dans un réseau décentralisé qui s’étend sur un vaste territoire, le consensus est essentiel. Bitcoin utilise le consensus de preuve de travail (PoW) pour prendre en charge le consensus. Bien que la méthode soit hautement sécurisée, il est difficile de ne pas ignorer son problème le plus important : le manque d’évolutivité. N’oubliez pas que Bitcoin ne peut effectuer que 7 transactions par seconde.

Qu’est-ce qu’un cluster Solana ?

Un cluster est un ensemble d’ordinateurs indépendants qui fonctionnent ensemble et peuvent être considérés comme un système singulier. Les principales caractéristiques du cluster sont les suivantes :

Programmation en Solana

Les contrats intelligents dans Solana sont écrits en Rust ou C et compilés dans le bytecode Berkeley Packet Filter (BPF). Comme il y a plus d’outils disponibles, il est recommandé de coder en Rust. Les débutants doivent coder leurs programmes en utilisant le framework Anchor, ce qui simplifie l’exécution.

Exemple de contrat

#![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,

Que se passe-t-il dans le contrat ?

● Tous les comptes auxquels accéder sont annotés dans la structure pour chaque appel avec #[derive(Accounts)].

Qu’est-ce que le protocole NEAR ?

Créé à l’été 2018, le protocole a été conçu pour créer l’environnement parfait pour les applications décentralisées en offrant des vitesses plus élevées, un débit plus élevé et une meilleure compatibilité avec d’autres chaînes. NEAR a une technique de partage unique et introduit un mécanisme de génération de blocs appelé « Doomslug » proposé en 2019. Doomslug permet une finalité pratique ou « Doomslug », garantissant que les blocs reçoivent la finalité en quelques secondes.

“ Lire l’article complet sur LearnNEAR.Club

Lien : https://learnnear.club/fr/near-protocole-et-solana/

Source :

le site web LearnNear.club

Médias :

Site internet | Twitter | Medium | Telegram|

--

--

Blockchain , Near , Octopus Network

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store