Zinc 虚拟机

2021-05-25  本文已影响0人  雪落无留痕

Zinc为Matter Labs开发的编程语言, 主要为实现EVM兼容的L2方案。Zinc的两个目标:

Zinc类似于Rust语言语法,目前还在开发中。

Zinc是非图灵完备的语言,不允许递归和非常量的循环。

目前Zinc已实现 Curve 应用demo。

示例

Zinc文档给出一个开发智能合约的示例,如下:

//!
//! The 'constant_price' contract entry.
//!
type Address = u160;
type Balance = u248;

enum TokenAddress {
    ETH = 0x0000000000000000000000000000000000000000,
    USDT = 0x3b00ef435fa4fcff5c209a37d1f3dcff37c705ad,
    USDC = 0xeb8f08a975ab53e34d8a0330e0d34de942c95926,
    LINK = 0x4da8d0795830f75be471f072a034d42c369b5d0a,
    TUSD = 0xd2255612f9b045e9c81244bb874abb413ca139a3,
    HT = 0x14700cae8b2943bad34c70bb76ae27ecf5bc5013,
    OMG = 0x2b203de02ad6109521e09985b3af9b8c62541cd6,
    TRB = 0x2655f3a9eeb7f960be83098457144813ffad07a4,
    ZRX = 0xdb7f2b9f6a0cb35fe5d236e5ed871d3ad4184290,
    BAT = 0xd2084ea2ae4bbe1424e4fe3cde25b713632fb988,
    REP = 0x9cac8508b9ff26501439590a24893d80e7e84d21,
    STORJ = 0x8098165d982765097e4aa17138816e5b95f9fdb5,
    NEXO = 0x02d01f0835b7fdfa5d801a8f5f74c37f2bb1ae6a,
    MCO = 0xd93addb2921b8061b697c2ab055979bbefe2b7ac,
    KNC = 0x290eba6ec56ecc9ff81c72e8eccc77d2c2bf63eb,
    LAMB = 0x9ecec4d48efdd96ae377af3ab868f99de865cff8,
    GNT = 0xd94e3dc39d4cad1dad634e7eb585a57a19dc7efe,
    MLTT = 0x690f4886c6911d81beb8130db30c825c27281f22,
    XEM = 0xc3904a7c3a95bc265066bb5bfc4d6664b2174774,
    DAI = 0x2e055eee18284513b993db7568a592679ab13188,
}

impl TokenAddress {
    pub fn is_known(address: Address) -> bool {
        match address {
            0x0000000000000000000000000000000000000000 => true,
            0x3b00ef435fa4fcff5c209a37d1f3dcff37c705ad => true,
            0xeb8f08a975ab53e34d8a0330e0d34de942c95926 => true,
            0x4da8d0795830f75be471f072a034d42c369b5d0a => true,
            0xd2255612f9b045e9c81244bb874abb413ca139a3 => true,
            0x14700cae8b2943bad34c70bb76ae27ecf5bc5013 => true,
            0x2b203de02ad6109521e09985b3af9b8c62541cd6 => true,
            0x2655f3a9eeb7f960be83098457144813ffad07a4 => true,
            0xdb7f2b9f6a0cb35fe5d236e5ed871d3ad4184290 => true,
            0xd2084ea2ae4bbe1424e4fe3cde25b713632fb988 => true,
            0x9cac8508b9ff26501439590a24893d80e7e84d21 => true,
            0x8098165d982765097e4aa17138816e5b95f9fdb5 => true,
            0x02d01f0835b7fdfa5d801a8f5f74c37f2bb1ae6a => true,
            0xd93addb2921b8061b697c2ab055979bbefe2b7ac => true,
            0x290eba6ec56ecc9ff81c72e8eccc77d2c2bf63eb => true,
            0x9ecec4d48efdd96ae377af3ab868f99de865cff8 => true,
            0xd94e3dc39d4cad1dad634e7eb585a57a19dc7efe => true,
            0x690f4886c6911d81beb8130db30c825c27281f22 => true,
            0xc3904a7c3a95bc265066bb5bfc4d6664b2174774 => true,
            0x2e055eee18284513b993db7568a592679ab13188 => true,
            _ => false,
        }
    }
}

contract ConstantPrice {
    const MAX_FEE: u16 = 10000;
    const PERCISION_MUL: Balance = 1E3;

    pub fee: u16;

    pub fn new(_fee: u16) -> Self {
        require(_fee <= Self::MAX_FEE, "The fee value must be between 0 and 10000");

        Self {
            fee: _fee,
        }
    }

    pub fn deposit(mut self) {
        require(zksync::msg.recipient == self.address, "The transfer recipient is not the contract recipient");

        require(TokenAddress::is_known(zksync::msg.token_address), "The deposited token is unknown");

        require(zksync::msg.amount > 0, "Cannot deposit zero tokens");
    }

    pub fn exchange(
        mut self,
        withdraw_token: Address,
    ) {
        require(zksync::msg.recipient == self.address, "The transfer recipient is not the contract recipient");

        require(TokenAddress::is_known(zksync::msg.token_address), "The deposited token is unknown");

        require(TokenAddress::is_known(withdraw_token), "The withdrawn token is unknown");

        require(zksync::msg.amount > 0, "Cannot deposit zero tokens");

        require(zksync::msg.token_address != withdraw_token, "Cannot withdraw the same token");

        let withdraw_token_amount = zksync::msg.amount * 
           ((Self::MAX_FEE - self.fee) as Balance * Self::PERCISION_MUL / Self::MAX_FEE as Balance) /
           Self::PERCISION_MUL;

        require(self.balances.get(withdraw_token).0 >= withdraw_token_amount, "Not enough tokens to withdraw");

        self.transfer(zksync::msg.sender, withdraw_token, withdraw_token_amount);   
    }

    pub fn get_fee(self) -> u16 {
        self.fee
    }
}

采用 zargo 可以对其编译,并在Zksync网络中部署。类似Solidity合约,并可以对其进行查询和调用。

Zinc目前并不完善,相关依赖库比较缺乏,后续仍需要持续关注中。

参考

https://zinc.zksync.io/index.html

https://github.com/matter-labs/zinc

上一篇下一篇

猜你喜欢

热点阅读