Solana(索拉纳)公链了解
Solana()公链
⼀、背景
随着加密货币市场热度不断攀升,以太坊的⽤户也不断增加,随之⽽来的就是⾼额的Gas费⽤以及拥堵的⽹络,这迫使⽤户不得不去寻新的。
公链领域存在着“不可能三⾓”,即去中⼼化、安全性和可扩展性三者不可兼得。其中,各⼤公链都会⾸要保证去中⼼化和安全性,于是可扩展性便成为许多新兴公链钻研的⽬标。
Solana是在这个背景下产⽣的。它给⾃⼰的定位是世界上最快的⾼性能公链,它的可扩展性可以达到⽹络级别,理论上标准千兆⽹络下TPS 最⾼可达 71 万。
公链领域的“不可能三⾓”问题,TPS对⽐图如下:
TPS:Transactions Per Second(每秒传输的事物处理个数),即服务器每秒处理的事务数。TPS包括⼀条消息⼊和⼀条消息出,加上⼀次⽤户数据库访问。(业务TPS = CAPS × 每个呼叫平均TPS)
TPS是软件测试结果的测量单位。⼀个事务是指⼀个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使⽤的时间和完成的事务个数。
⼀般的,评价系统性能均以每秒钟完成的技术交易的数量来衡量。系统整体处理能⼒取决于处理能⼒最低模块的TPS值。
⼆、基本概念
下⾯是Solana的⼤事件:
之前DeFi的盛⾏让以太坊交易慢、gas贵。⽽Solana团队在DeFi爆发的前夜,预见性地推出了以太坊桥——⾍洞(Wormhole)协议,实现了Solana和以太坊上资产的跨链转移,这为上⼤量的DeFi项⽬提供了⼀个新的选项。在Layer 2扩容⽅案完善落地之前,Solana为各平台、项⽬提供了⼀条⽆需重写合约即可低成本快速迁移的公链。
当以太坊的问题暴露在所有⼈⾯前的时候,Solana的提前布局为他们带来了很多优质项⽬的迁移和⼤量活跃⽤户。
(⼀)Solana的优势
Solana利⽤⼯作历史证明 PoH、拜占庭容错(Tower BFT)、涡轮机(区块传播协议)、海湾流(⽆内存交易转发协议)、海平⾯(并⾏智能合约)、管道(验证交易)、云散(⽔平扩展账户数据库)以及档案(分布式账本存储)⼋⼤突破性技术构建出了⼀个超⾼性能的区块链。
现在相较与其他公链:费⽤低、可拓展性好、有⾃⼰的⾍洞协议来跨链互通。
跟ETH公链的不同点
(⼆)
(⼆)跟
1.账户模型
作为⼀个开发者,最先要了解的就是账户模型
(1)以太坊账户模型
⼤家都知道以太坊账户模型是分两种,⼀种是主⽹币,⼀种是合约币,主⽹币⾥⾯的的account 就有⼀个balance字断,⽤来记录⽤户的ETH 的数量,如果某个地址拥有其他的token ,是在合约⾥⾯给这
个地址存了个mapping,⽤来记录这个⽤户token 的数量。因此⽤户拥有的ERC20 token其实记账是记录在合约⾥⾯,以太坊合约具有存储功能,是因为合约⽤⼀个世纪状态永远存储在区块⾥⾯。
(2)Solana账户模型
solana 的账户模型不⼀样的地⽅在于,solana 账户除了可以存储本币sol以外,还增加了⼀个data字段。
先看⼀下账户的字段:
详细描述⼀下
lamports :这个就是和以太坊的balance⼀样,描述这个账号有多少个SOL 可以使⽤
owner:owner这个字段保证了⽤户对账户的决定拥有权利,如果某⼀个地址是某⼀个account的owner,那么那个地址就可以对这个account 资产进⾏转移。所以solana的合约token其实就是solana程序会帮忙⽣成⼀个account,然后把owner赋予给你。
Executable:这个表⽰⽤户的状态是不是可执⾏的状态。在solana的账户体系⾥⾯的data字断是表⽰存储,或者可执⾏。可执⾏的data是帐户数据专门⽤于不可变字节代码该字节代码⽤于处理交易。
data:这个和executable 描述相似
rent_epoch:这个⽐较有意思,就是solana的合约和solidity合约不⼀样的地⽅,solana的合约部署是要按⼤⼩定期收费的,⽬前是费⽤是2天⼀收,应该是0.01SOL 1K的⼤⼩。如果没有费⽤solana系统就会清除这些账号。
2.solana 合约和solidity合约的区别
solana的合约其实就是⼀段程序,这个程序没有存储功能,程序编译好以后,是⼀个BPF字节码,这个和solidity 编译后是⼀段⼆进制码是⼀样的。 solidity是通过合约地址到合约存在得状态数,然后再通过input参数,拿到需要执⾏得⽅法和参数,再执⾏对于得合约⽅法。solana 这个部分是⼀样得,solana 发布到连上得合约有⼀个programID,这个programID也是⼀个Hash256,类似solidity合约地址⼀
样,solana 合约得⽅法通过⼀个枚举来定义,也就是,⽅法分别是0-1-2-3-4,参数就是解析data,那么solana 合约最难得就是要解析这个data,因为这个data是⽤户⾃⼰定义和排序的,solana不提供标准的map,struct,这些数据结构存储,都是以⽂本得形式存储在各个account⾥⾯得data⾥⾯,所以solana合约最困难得就是要对data进⾏编码,解析再解码,你可以想象⼀下⼀个token合约,solidity 最多两个map,⼀个是balance,⼀个是allowance,就够了,但是solana不⼀样,他没有存储,他需要
为每⼀个⼈创建⼀个临时得account,然后解析出来,给他们做tranfer或者approve操作。还要有⼀堆的安全性判断。最重要得是你要得存储进⾏排版,解析。
(三)Solana的合约
由于账户模型的不⼀样,那么刚开始理解solana的合约就很困难,基于Solana开发需要知道的⼏个问题:
1、solana 合约开发环境
2、solana 合约开发语⾔
3、solana 合约部署
4、solana 合约逻辑
5、solana 合约前端后端交互
1.solana 合约框架
先整理清楚solana 合约是怎么运⾏的。
2.合约具体分析
通过学习token 合约来整体理解Solana,这⾥不讲helloworld,因为token 合约结构更完善。go语言开发环境搭建
token 合约路径:
token 合约⽬录结构
–cli
–js
---- cli
---- client
--------token.js
–program
----src
-
-----entrypoint.rs // 这个整个程序的⼊⼝,也就是solana节点会把交易⾥⾯的参数都传⼊到这个接⼝
------error.rs // 错误信息
------instruction.rs // 这个才是序列化/反序列化的/结构体的定义问题
------lib.rs //这个是rust ⽤来串联本⽬录或者其他⽬录⽂件⽤的
------native_mint.rs // 这个是mint ⽅法
------processor.rs //这个是token 的所有⽅法调⽤的地⽅,所有⽅法实现的地⽅,进⼊到这些⽅法,需要传⼊的参数包括(函数,参数都要解析出来)
------state.rs // 这个是状态
这⾥类⽐使⽤go 语⾔版本的solidity来理解Solana智能合约,⾸先要明⽩它是需要运⾏在主⽹代码上,所以有⼏个要点:
1、哪个程序
2、哪个函数
3、实现什么功能
4、结果在哪⾥
上⾯问题进⾏解答
⽅法来对上⾯问题进⾏解答
(1)⽤token 的tranfer ⽅法来对
1、哪个程序
前⾯介绍了solana 的智能合约的指向是⼀个programID,programID 就和solidity合约的合约地址是⼀个意思,所以发送交易的时候要指定programID。
2、哪个函数
我们的合约可能有很多⽅法,那么我⼀笔交易,指定了programID,我还需要指定是哪个函数,以及对应的参数,所以再processor⽅法⾥⾯,我们看到⼀个match ⽤来分发函数,⾥⾯的第⼀个就是获取⽤户输⼊的调⽤的哪个⽅法。
代码⽰例:pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult {undefined
let instruction = TokenInstruction::unpack(input)?;
也可以通过看token.js⽅法⾥⾯的交易组装函数(createTransferCheckedInstruction),就有⼀个instruction :12这样⼀个赋值,所以这个12就是对应的函数,那么这个定义⼀般要怎么定义?
{
undefined
instruction: 12, // TransferChecked instruction
amount: new u64(amount).toBuffer(),
decimals,
},
data,
);
看instruction.rs⽂件,⾥⾯有定⼀个enum,⾥⾯定义了每个函数的instruction,也就是说,前端需要知道有哪些函数,这个就和ABI⼀样,但是更简单。复杂的事数据的处理,我们看看12是哪个函数:上⾯表⽰使⽤TransferChecked 这个函数。
TransferChecked {undefined
/// The amount of tokens to transfer.
amount: u64,
/// Expected number of base 10 digits to the right of the decimal place.
decimals: u8,
}
3、这个函数做什么事情
从 pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult 这个函数⾥⾯到12 这个instruction对应的TransferChecked 然后去分发进⼊的是这个【process_transfer】
TokenInstruction::TransferChecked {
amount, decimals } => {undefined
msg!(“Instruction: TransferChecked”);
Self::process_transfer(program_id, accounts, amount, Some(decimals))
}
通过学习可以知道process_transfer这个函数做了什么事情:
1、账户状态的准备检查
2、账户转账处理
3、账户信息打包(pack 函数)
4、怎么存储
由于整个rust 都是⽤指针对内存⽂件进⾏读写操作,所有在pack 结束后就进⾏了存储。
(2)solana 合约交易
对于前端⽽⾔,和solidity有什么区别?
solidity前端只需要使⽤ABI 对input data 进⾏bytecode 就可以了,然后进⾏组装交易,发送签名交易。就可以完成合约的调⽤,使⽤的是web3j的库。
那么solana 的前端调⽤合约交易如何组装呢?
统⼀交易的参数:
static createTransferInstruction(
programId: PublicKey,
source: PublicKey,
destination: PublicKey,
owner: PublicKey,
multiSigners: Array,
amount: number | u64,
输出参数的定义
const dataLayout = BufferLayout.struct([
BufferLayout.u8(‘instruction’),
Layout.uint64(‘amount’),
]);
调⽤合约函数的绑定
const data = Buffer.alloc(dataLayout.span);
{undefined
instruction: 3, // Transfer instruction
amount: new u64(amount).toBuffer(),
},
data,
);
from /to 压缩到keys ⾥⾯
let keys = [
{pubkey: source, isSigner: false, isWritable: true},
{pubkey: destination, isSigner: false, isWritable: true},
];
if (multiSigners.length === 0) {undefined
keys.push({undefined
pubkey: owner,
isSigner: true,
isWritable: false,
});
} else {undefined
keys.push({pubkey: owner, isSigner: false, isWritable: false});
multiSigners.forEach(signer =>
keys.push({undefined
pubkey: signer.publicKey,
isSigner: true,
isWritable: false,
}),
);
}
组装好的交易返回出去
return new TransactionInstruction({undefined
keys,
programId: programId,
data,
});
总的来说交易发送也是对交易的组装,对input的组装,和solidity ⼏乎⼀样。
3.solana 合约开发语⾔
solana ⽬前⽀持 rust、C++ 和C 对合约进⾏开发,官⽅建议跟⽹上建议都是推荐学习Rust,因为整个链都是rust的开发的。整个接⼝或者其他的框架也⼤部分是rust,这样可利⽤的开发⼯具就会更多。
初步学习,在学习完helloworld以后看 token的代码、合约,还有web3j调⽤。
⽰例学习链接如下:
helloworld 链接[]

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。