ERC-20标准
ERC-20标准在以太坊改进提案(EIP)中定义,请仔细阅读它,因为它定义了我们已实现的方法:
balance_of
转让
total_supply
批准
津贴
从转移
薄荷
克隆示例智能合约
示例ERC-20位于GitHub中。
所需的程序框架
这是标准的智能合约。在rust中,关键字use就像includeC / C ++中的语句。卡斯珀的智能合约要求包括几个程序框架。他们是:
CasperLabslabs_contract_macros:CasperLabs DSL,其中包括每个智能合约所需的样板代码
智能合约:用于运行时和存储的CasperLabs智能合约API
类型:CasperLabs智能合约类型系统
use alloc::{
collections::{BTreeMap, BTreeSet},
string::String,
};
use core::convert::TryInto;
use CasperLabslabs_contract_macro::{CasperLabslabs_constructor, CasperLabslabs_contract, CasperLabslabs_method};
use contract::{
contract_api::{runtime, storage},
unwrap_or_revert::UnwrapOrRevert,
};
use types::{
account::AccountHash,
bytesrepr::{FromBytes, ToBytes},
contracts::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints},
runtime_args, CLType, CLTyped, CLValue, Group, Parameter, RuntimeArgs, URef, U256,
};
CasperLabs智能合约初始化
部署智能合约后,必须使用一些值对其进行初始化,这是在CasperLabslabs_contract和CasperLabslabs_constructor宏的帮助下完成的。智能合约使用名称,符号,小数,起始余额和起始令牌供应进行初始化。
#[CasperLabslabs_contract]
mod ERC20 {
#[CasperLabslabs_constructor]
fn constructor(tokenName: String, tokenSymbol: String, tokenTotalSupply: U256) {
set_key("_name", tokenName);
set_key("_symbol", tokenSymbol);
let _decimals: u8 = 18;
set_key("_decimals", _decimals);
set_key(&new_key("_balances", runtime::get_caller()), tokenTotalSupply);
let _totalSupply: U256 = tokenTotalSupply;
set_key("_totalSupply", _totalSupply);
}
然后,我们还添加了一些辅助函数来进行设置,并从CasperLabs智能合约中检索值。该[CasperLabslabs_method]宏有利于这一点。注意,这些辅助函数中的每一个都引用set_key构造函数中的每个定义,并且使用通用get_key函数来检索值。
#[CasperLabslabs_method]
fn name() -> String {
get_key("_name")
}
#[CasperLabslabs_method]
fn symbol() -> String {
get_key("_symbol")
}
#[CasperLabslabs_method]
fn decimals() -> u8 {
get_key("_decimals")
}
总供给,平衡和津贴
以下是一些ERC-20方法。下面是执行balance_of,total_supply和allowance。配额方法使所有者可以指定支出者帐户可以支出的金额。
#[CasperLabslabs_method]
fn totalSupply() {
ret(get_key::("_totalSupply"));
}
#[CasperLabslabs_method]
fn balance_of(account: AccountHash) -> U256 {
get_key(&balance_key(&account))
}
#[CasperLabslabs_method]
fn allowance(owner: AccountHash, spender: AccountHash) -> U256 {
let key = format!(“allowances{}_{}”, owner, spender);
get_key::(&key)
}
转移
这是transfer一种方法,它使得可以在sender地址之间传递令牌recipient。如果sender地址有足够的余额,则应将令牌转移到该recipient地址。该CasperLabslabs_method宏创建的方法,该方法调用的入口点 _transfer方法。
#[CasperLabslabs_method]
fn transfer(recipient: AccountHash, amount: U256) {
_transfer(runtime::get_caller(), recipient, amount);
}
fn _transfer(sender: AccountHash, recipient: AccountHash, amount: U256) {
let new_sender_balance: U256 = (get_key::(&new_key("_balances", sender)) - amount);
set_key(&new_key("_balances", sender), new_sender_balance);
let new_recipient_balance: U256 = (get_key::(&new_key("_balances", recipient)) + amount);
set_key(&new_key("_balances", recipient), new_recipient_balance);
}
批准和转移
这里是功能approve和transfer_from。approve用于允许另一个地址代表我使用CasperLabs代币。当多个密钥被授权从一个帐户执行部署时使用。
#[CasperLabslabs_method]
fn approve(spender: AccountHash, amount: U256) {
_approve(runtime::get_caller(), spender, amount);
}
fn _approve(owner: AccountHash, spender: AccountHash, amount: U256) {
set_key(&new_key(&new_key("_allowances", owner), spender), amount);
}
transfer_from 允许花费批准数量的代币。
#[CasperLabslabs_method]
fn transferFrom(owner: AccountHash, recipient: AccountHash, amount: U256) {
_transfer(owner, recipient, amount);
_approve(
owner,
runtime::get_caller(),
(get_key::(&new_key(
&new_key("_allowances", owner),
runtime::get_caller(),
)) - amount),
);
}
PUT和GET功能
这些函数是通用的CasperLabs存储写和读方法。一次执行这些智能合约,然后根据需要调用它们。
fn get_key<T: FromBytes + CLTyped + Default>(name: &str) -> T {
match runtime::get_key(name) {
None => Default::default(),
Some(value) => {
let key = value.try_into().unwrap_or_revert();
storage::read(key).unwrap_or_revert().unwrap_or_revert()
}
}
}
fn set_key<T: ToBytes + CLTyped>(name: &str, value: T) {
match runtime::get_key(name) {
Some(key) => {
let key_ref = key.try_into().unwrap_or_revert();
storage::write(key_ref, value);
}
None => {
let key = storage::new_uref(value).into();
runtime::put_key(name, key);
}
}
}
格式化辅助函数
这些函数将CasperLabs余额和帐户信息从内部表示形式格式化为字符串。
fn balance_key(account: &AccountHash) -> String {
format!(“balances{}”, account)
}
fn allowance_key(owner: &AccountHash, sender: &AccountHash) -> String {
format!(“allowances{}_{}”, owner, sender)
}
作者郑重申明:截至发文时,作者与文中提及项目皆不存在任何利益关系。