5

部署Solidity智能合约到Solana

 2 years ago
source link: https://learnblockchain.cn/article/3328
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

部署Solidity智能合约到Solana

什么是Solana,你如何将Solidity智能合约部署到Solana?

Solana是一个新的区块链,专注于性能。它支持像Ethereum那样的智能合约,他们称之为程序。你可以使用Rust开发这些程序,但现在有一个新的项目,将Solidity编译为Solana程序。换句话说,你现在就可以把你用Solidity写的合约部署到Solana上了。

当然,Solana上的交易成本只是以太坊上的一小部分。那么,这一切是如何进行的呢?

Solana Meme

交易排序(历史证明)

Solana最大的特点是它的历史证明(PoH),它是基于一串sha256哈希值作为时间的证明。其背后的想法是,要计算hash300,必须先按顺序计算hash1,然后hash2,以此类推。这是因为哈希值的输出是无法预测的,每个中间结果都会自动成为下一个中间结果的输入。

最新一代的CPU在计算sha256时速度非常快,但同样必须按顺序进行。而这就是为什么人们可以肯定不会有一个定制的ASIC,它的速度是100倍。

历史实例1的证明

Proof of History Example 2

因此,当一个节点收到用hash300签名的交易时,它将知道这些交易将被放在hash200之后,但在hash400之前(假设100个hash为延迟)。这与ETH2.0使用的可验证延迟函数(VDFs)的概念很相似。区别在于证明的验证,对于VDF来说,验证的步骤要比创建证明复杂得多,而对于PoH来说,需要重新计算每个哈希值。那么,如何才能有效地完成PoH验证?

幸运的是,PoH证明验证,与PoH证明创建不同,可以并行化。证明必须包含每个中间哈希值,然后每个中间哈希值的计算可以被并行验证。这在现代GPU上是可以非常有效地实现的。当然,这样做的缺点是证明尺寸非常大,而且对Solana验证器的硬件要求普遍较高。好处是性能,因为它减少了信息传递的开销+延迟,因为提供了一个预先确定的交易顺序。

新的交易捆绑在一个批次中,并乐观地通过UDP从当前的领导者流向所有其他验证者,其中每个验证者收到捆绑的不同数据部分。在下一个步骤中,验证者相互之间共享缺失的数据集,所有这些都是并发的、不间断的、流式的,从而获得非常高的性能。

在Solana上达成的共识(权益证明)

但PoH并不能解决共识问题,为此Solana使用了PBFT(实用拜占庭容错)的一个版本,它与Cosmos的Tendermint共识算法(这里是一个很好的视频概述)称为Tower BFT。但是,由于Solana可以使用PoH作为其区块链时钟,PBFT的共识超时可以直接用这个编码。

所有先前的PBFT投票的超时时间随着每一个新的投票而翻倍。想象一下,在过去的12秒内,每个验证者都投了32次票的场景。12秒前的最后一票现在有2³²个时段的超时,或大约54年的PoH时间。或者换句话说,你必须在CPU上计算sha256哈希值54年,才能够回滚那次投票。

Solana的其他功能包括。

如果你想了解更多,请查看Solana的文档白皮书博客文章

部署ERC-20 代币到Solana

部署Solidity编写的ERC-20到Solana需要安装以下所有工具并运行部署脚本:

1. 安装Solang

安装Solang的最佳方式是使用VS Code 插件。它将自动安装正确的solang二进制文件和依赖项。或者,你可以直接下载二进制文件,然后手动安装依赖项。VS Code插件也将为你提供Solang的编译能力,由于支持的功能不同,普通的Solidity插件并不十分准确。

为了使扩展正常工作,你需要执行下面几个步骤:

1. 确保在插件设置中选择Solana作为目标

VS Code Solang Target

2. 禁用工作区的solidity插件

VS Code Solang Extensions

现在让我们拿一个ERC20合约来实验,这里的代码是Openzeppelin的1:1拷贝。

你还需要初始化软件包并安装所需的依赖项。

$ npm init
$ npm install @solana/solidity @solana/web3.js

2. 安装Solana工具套件

接下来是安装Solana测试套件,如果你是在Mac OS上运行,只要运行以下命令:

$ sh -c "$(curl -sSfL https://release.solana.com/v1.8.5/install)"

3. 创建ERC-20合约

现在让我们在包根中取一个ERC20合约作为ERC20.sol,这里的代码几乎是Openzeppelin的1:1拷贝。

4. 编译Solidity -> Solana

接下来是安装Solana测试套件。如果你在Mac OS上运行,只要运行以下命令:

$ solang ERC20.sol --target solana --output build
  • build/ERC20.abi:就像你从Ethereum知道的那样,它是合约的ABI。
  • build/bundle.so: 这里的新内容是编译后的Solana程序

5. 部署ERC-20合约

现在创建以下deploy-erc20.js脚本:

const { Connection, LAMPORTS_PER_SOL, Keypair } = require('@solana/web3.js')
const { Contract, publicKeyToHex } = require('@solana/solidity')
const { readFileSync } = require('fs')

const ERC20_ABI = JSON.parse(readFileSync('./build/ERC20.abi', 'utf8'))
const BUNDLE_SO = readFileSync('./build/bundle.so')

;(async function () {
    console.log('Connecting to your local Solana node ...')
    const connection = new Connection(
        // works only for localhost at the time of writing
        // see https://github.com/solana-labs/solana-solidity.js/issues/8
        'http://localhost:8899', // "https://api.devnet.solana.com",
        'confirmed'
    )

    const payer = Keypair.generate()
    while (true) {
        console.log('Airdropping (from faucet) SOL to a new wallet ...')
        await connection.requestAirdrop(payer.publicKey, 1 * LAMPORTS_PER_SOL)
        await new Promise((resolve) => setTimeout(resolve, 1000))
        if (await connection.getBalance(payer.publicKey)) break
    }

    const address = publicKeyToHex(payer.publicKey)
    const program = Keypair.generate()
    const storage = Keypair.generate()

    const contract = new Contract(connection, program.publicKey, storage.publicKey, ERC20_ABI, payer)

    console.log('Deploying the Solang-compiled ERC20 program ...')
    await contract.load(program, BUNDLE_SO)

    console.log('Program deployment finished, deploying ERC20 ...')
    await contract.deploy('ERC20', ['MyToken', 'MTO', '1000000000000000000'], program, storage, 4096 * 8)

    console.log('Contract deployment finished, invoking contract functions ...')
    const symbol = await contract.symbol()
    const balance = await contract.balanceOf(address)

    console.log(`ERC20 contract for ${symbol} deployed!`)
    console.log(`Wallet at ${address} has a balance of ${balance}.`)

    contract.addEventListener(function (event) {
        console.log(`${event.name} event emitted!`)
        console.log(
            `${event.args[0]} sent ${event.args[2]} tokens to
       ${event.args[1]}`
        )
    })

    console.log('Sending tokens will emit a "Transfer" event ...')
    const recipient = Keypair.generate()
    await contract.transfer(publicKeyToHex(recipient.publicKey), '1000000000000000000')

    process.exit(0)
})()

在这里,我们使用了

如果你是Dapp开发者并想连接一个钱包,可以看一下Solana钱包适配器

现在我们准备运行自己的本地Solana链。

$ solana-test-validator --reset --quiet

并在一个单独的标签中运行我们的脚本。

$ node deploy-erc20.js

刚刚命令将ERC-20代币部署到的本地Solana链上! 🎉🎉🎉

那么Solang到底是什么?

用他们自己的话说。通过Solang,你可以为SolanaParity SubstrateEthereum ewasm编译用Solidity编写的智能合约。它使用llvm编译器框架来产生WebAssembly(wasm)或BPF合约代码。

它与MoonbeamEvmos等克隆EVM的项目相比如何?由于EVM的克隆保留了运行EVM的所有开销,Solang的解决方案应该更有效率,因为它是在链上原生运行的,但也有一些注意事项:

Solang的目标是与Solidity 0.7兼容,但有一些关键的区别:

  • 库总是静态地链接到合约代码中。

  • Solang生成WebAssembly或BPF,而不是EVM。这意味着不支持使用EVM指令的assembly {}语句。

  • Solana不存在gas。 有不得超过的计算预算,但没有基于使用的计算单元的收费。

    • 不能在Solana上为外部调用设置gas。
    • tx.gasprice不可用。
    • gasleft()不可用。
  • block.number给出的是槽号而不是块的高度。

  • 你可以使用print()打印输出以进行调试。

  • selfdestructtx.origin不可用。

  • Solana地址是base58编码的,而不是16进制的。可以用特殊的语法来指定一个地址常量

address"<account>"
address foo = address"5GBWmgdFAMqm8ZgAHGobqDqX6tjLxJhv53ygjNtaaAn3sjeZ"
  • 新账户的大小可以用space指定。默认情况下,新账户的大小为1 kilobyte(1024字节),加上任何固定大小字段所需的大小。当你指定空格时,这是在固定尺寸字段(如状态中的字符串)之外的空间。所以,如果你指定space: 0,那么没有任何空间分配给动态的字段。
contract Hatchling {
    string name;

    constructor(string id) payable {
        require(id != "", "name must be provided");
        name = id;
    }
}

contract Adult {
    function test() public {
        Hatchling h = new Hatchling{space: 10240}("luna");
    }
}
  • 那么,这是否可以使用了?

    • 我不确定它是否可以用于生产环境,但即使不是,也肯定很快就可以了。
  • 我们编译的ERC-20合约是否与Solana 上的其他的SPL代币兼容吗?

    • 我也不确定,如果你知道答案,请留言。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK