http://www.7klian.com

利用 Ink!开拓 Substrate ERC20 智能合约

   function approve(address _spender, uint _value) returns (bool success);
            *self.total_supply
        owner: AccountId,
        fn transfer_from(&mut self, from: AccountId, to: AccountId, value: Balance) -> bool {
    }
            true
            self.env().emit_event(Approval {
        #[ink(topic)]
        balances: storage::HashMap<AccountId, Balance>,
            });
•授权事件
        }
                from: Some(from),
            let owner = self.env().caller();
        value: Balance,

ERC20界说了一些尺度的接口函数:balanceOf 、 totalSupply 、transfer 、transferFrom 、approve和allowance 。以及一些可选的字段,譬喻通证名称、标记以及小数保存位数等。

            self.balances.insert(from, from_balance – value);
                return false
            assert_eq!(contract.balance_of(AccountId::from([0x0; 32])), 10);
                to: Some(caller),
        value: Balance,
        allowances: storage::HashMap<(AccountId, AccountId), Balance>,
        #[ink(topic)]
            let to_balance = self.balance_of_or_zero(&to);
        #[ink(message)]
        #[ink(topic)]
    }
            self.allowances.insert((owner, spender), value);
        }
            let mut contract = Erc20::new(100);
    struct Approval {
        // 东西要领:若用户未被初始化,代币余额置为0
        fn new_works() {
    #[ink(event)]
        #[ink(message)]
            let from_balance = self.balance_of_or_zero(&from);
            true
            let caller = self.env().caller();
   event Transfer(address indexed _from, address indexed _to, uint _value);
        #[ink(topic)]
$ git clone [email protected]:paritytech/substrate.git
3.6 单位测试用例编写
        #[ink(message)]
cargo-contract 0.6.1
            // 获取合约接管者账户余额(代币吸收者账户大概未被初始化,通过此要领将其余额初始化为0)
        fn total_supply(&self) -> Balance {
            let caller = self.env().caller();
    cargo contract BCOMMAND>
    new                  Setup and create a new smart contract project
        fn balance_of_or_zero(&self, owner: &AccountId) -> Balance {
        #[ink(message)]
        fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance {
            self.balances.insert(to, to_balance + value);
    }
2.1 什么是ERC20尺度
            let to_balance = self.balance_of_or_zero(&to);
            self.balance_of_or_zero(&owner)
        from: Option<AccountId>,
        owner: AccountId,
            *self.total_supply
    struct Erc20 {
            // 获取合约挪用者账户余额
        }
    build                Compiles the smart contract
            true
1.1 安装Substrate节点
    struct Transfer {
                from: Some(from),
    Created contract erc20
        fn transfer_from(&mut self, from: AccountId, to: AccountId, value: Balance) -> bool {
#[ink::contract(version = “0.1.0”)]
        spender: AccountId,
            let from_balance = self.balance_of_or_zero(&from);
    #[ink(storage)]
            self.env().emit_event(Transfer {
        ……
    mod tests {
        to: Option<AccountId>,
    help                 Prints this message or the help of the given subcommand(s)
            }
    }
            });
        #[ink(topic)]
•转账事件
        }
Utilities to develop Wasm smart contracts
•合约结构事件
            assert!(contract.transfer(AccountId::from([0x0; 32]), 10));
            assert_eq!(contract.balance_of(AccountId::from([0x0; 32])), 0);
        #[ink(message)]
            }
        }
        spender: AccountId,
            self.transfer_from_to(from, to, value)
contract ERC20 {
        #[ink(message)]
    }
        fn new(&mut self, initial_supply: Balance) {
                value: initial_supply,
        fn transfer_from_to(&mut self, from: AccountId, to: AccountId, value: Balance) -> bool {
            self.transfer_from_to(from, to, value)
                value,
        }
(2)查询用户代币余额接口
    #[cfg(test)]
        }
        fn total_supply(&self) -> Balance {
                to: Some(caller),
        use super::*;
            self.balances.insert(caller, initial_supply);
        fn balance_works() {

        #[ink(message)]
        #[test]
        // (代币所有者, 代币授权利用者) -> 代币授权利用者可支配余额
切换到一个新分支 ‘v2.0.0-rc4’
panic = “abort”           <– Panics shall be treated as aborts: reduces binary size
$ tree erc20/
            assert_eq!(contract.balance_of(AccountId::from([0x1; 32])), 100);
                from: None,
3.4 合约接口要领建设
        }
        }
            self.allowance_of_or_zero(&owner, &spender)
            self.transfer_from_to(from, to, value)
    test                 Test the smart contract off-chain
            self.balances.insert(to, to_balance + value);
                value: initial_supply,
            assert_eq!(contract.balance_of(AccountId::from([0x1; 32])), 100);
   function totalSupply() constant returns (uint theTotalSupply);
        fn balance_works() {
    struct Erc20 {

3 ERC20合约开拓

详见:https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
        #[ink(message)]
   function transferFrom(address _from, address _to, uint _value) returns (bool success);
            assert_eq!(contract.balance_of(AccountId::from([0x1; 32])), 100);
执行呼吁后,会生成2个文件,个中lib.rs会包罗一些基本框架,我们可以在此基本上
开拓我们的合约。
opt-level = “z”           <– Optimize for small binary output
    -h, –help       Prints help information
                value,
(4)授权转账——授权接口
            let caller = self.env().caller();
        #[test]
1.2 安装cargo contract插件
   function allowance(address _owner, address _spender) constant returns (uint remaining);
(1)查询代币刊行总量接口
        #[ink(message)]
        #[test]
$ cd substrate
(v2.0.0-rc4)$ cargo build –release
        total_supply: storage::Value<Balance>,
            // 配置刊行总量
            let contract = Erc20::new(777);
    #[ink(event)]
    }
        #[ink(constructor)]
        fn transfer_from_works() {
            contract.approve(AccountId::from([0x1; 32]), 20);
        fn allowance_of_or_zero(&self, owner: &AccountId, spender: &AccountId) -> Balance {
        fn transfer(&mut self, to: AccountId, value: Balance) -> bool {
            self.balances.insert(caller, initial_supply);
            self.balances.insert(from, from_balance – value);
$ cargo contract –help
    struct Erc20 {
            });
        fn balance_of(&self, owner: AccountId) -> Balance {
            let allowance = self.allowance_of_or_zero(&from, &caller);
lto = true                <– enable link-time-optimization: more efficient codegen
        fn approve(&mut self, spender: AccountId, value: Balance) -> bool {
通过授权转账,挪用方可以授权指定账户,从其地点中安详的消费指定命量的代币。
        /// The total supply.
        }
   function balanceOf(address _owner) constant returns (uint balance);
            let contract = Erc20::new(777);
        #[test]

        #[ink(message)]
        fn balance_of_or_zero(&self, owner: &AccountId) -> Balance {
            assert_eq!(contract.balance_of(AccountId::from([0x0; 32])), 0);
            if allowance < value {
        }
        fn approve(&mut self, spender: AccountId, value: Balance) -> bool {
            // 获取合约建设者
        #[ink(message)]
                value,
    #[ink(event)]
        }
            // 给吸收地点转出指定金额代币
        #[test]
    }
        /// 代币刊行总量
        #[ink(topic)]
            *self.allowances.get(&(*owner, *spender)).unwrap_or(&0)
(6)授权转账——转账接口
    #[ink(storage)]
            });
            true
        value: Balance,
SUBCOMMANDS:
        }
                return false
            if from_balance < value {
            // 获取合约接口挪用者地点
            // 吸收者余额增加指定命量
•辅佐手册
(3)转账接口
        }
            // 合约建设者拥有所有刊行代币
                spender,
    generate-metadata    Generate contract metadata artifacts
            *self.balances.get(owner).unwrap_or(&0)
            });
3.5 合约事件建设
                from: None,
            assert_eq!(contract.total_supply(), 100);
我们留意到,,在举办余额的增减时,并未像以太坊的solidity智能合约,利用特另外SafeMath接口,这是因为ink!提供了内置防溢出掩护,通过在Cargo.toml 设置文件中,添加如下设置来提供该安详机制:
(5)授权转账——余额查询
        #[ink(topic)]
   event Approval(address indexed _owner, address indexed _spender, uint _value);
            *self.allowances.get(&(*owner, *spender)).unwrap_or(&0)
OPTIONS:
        }
        /// 用户及余额映射

                value,
ERC20 通证尺度(ERC20 Token Standard)是通过建设通证时的一种类型。凭据 ERC20 的类型可以编写一个智能合约,建设“可交流畅证”。它并非强制要求,但遵循这个尺度,所建设的通证可以与浩瀚生意业务所、钱包等举办交互,它此刻已被行业普遍接管。

[profile.release]
        }
    impl Erc20 {
            assert_eq!(contract.total_supply(), 777);
        #[test]
            self.env().emit_event(Transfer {
        #[ink(topic)]
(master)$ git checkout -b v2.0.0-rc4 v2.0.0-rc4
USAGE:
            self.env().emit_event(Transfer {
            self.allowances.insert((owner, spender), value);
            self.balance_of_or_zero(&owner)
            assert!(!contract.transfer(AccountId::from([0x0; 32]), 100));
        to: Option<AccountId>,
            }
    use ink_core::storage;
            self.total_supply.set(initial_supply);
erc20/
        balances: storage::HashMap<AccountId, Balance>,
        from: Option<AccountId>,
        }
        total_supply: storage::Value<Balance>,
$ cargo +nightly test

        }
            if from_balance < value {
use ink_lang as ink;
        fn new_works() {
                spender,
            });
    }
    struct Transfer {
#![cfg_attr(not(feature = “std”), no_std)]
        }
                return false
└── lib.rs
                to: Some(to),
        }
                owner,
获代替币授权利用者剩余被答允转移的代币数量。
            assert_eq!(contract.total_supply(), 777);
        /// The balance of each user.
                return false
        value: Balance,
        #[ink(constructor)]
•安装呼吁
    #[ink(storage)]
        fn balance_of(&self, owner: AccountId) -> Balance {

1 情况搭建
            assert_eq!(contract.balance_of(AccountId::from([0x1; 32])), 100);
            let contract = Erc20::new(100);
2 ERC20合约先容
        fn transfer_works() {
   function transfer(address _to, uint _value) returns (bool success);
                owner,
overflow-checks = true    <– Arithmetic overflow protection
            assert_eq!(contract.total_supply(), 100);
            let caller = self.env().caller();
            let mut contract = Erc20::new(100);
        fn new(&mut self, initial_supply: Balance) {
            self.allowances.insert((from, caller), allowance – value);
            // 代币所有者(owner)授权代币利用者(spender)可支配余额(value)
答允智能合约自动执行转账流程并代表所有者发送给定命量的代币
        #[test]
3.1 建设合约工程
跑测试用例:
        fn allowance_of_or_zero(&self, owner: &AccountId, spender: &AccountId) -> Balance {
需完善合约存储:
        #[ink(message)]
        #[ink(topic)]
        fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance {
    #[ink(event)]
            let owner = self.env().caller();
        }

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

相关文章阅读