您正在查看: EOS-优秀转载 分类下的文章

EOS每年增发5%,1/5作为节点奖励,剩下4/5居然都给了它?

一、EOS通胀及奖励怎么分?

众所周知,EOS采取每年增发5%代币的通胀模式。这是因为EOS采用了DPOS共识机制,而且没有任何交易手续费(明面上的),所以它通过增发代币的方式来鼓励节点提供计算资源和记账。

但实际上,这些增发的EOS并不完全用于节点奖励,而是分为两部分,其中节点奖励占五分之一,即1%的EOS增发量;剩下的归WPS提案基金(WPF),约4%。

其中节点(包括超级节点和备用节点)奖励的四分之一,即0.25%的EOS增发量为超级节点的出块奖励,剩下的0.75%为所有节点的得票率奖励。备用节点则无出块奖励,只有得票率奖励且要求在100个EOS以上,否则便不算备用节点,无法领取奖励。

而归提案基金(WPF)所有的4%的增发奖励则服务于WPS(工作者提案系统),它就是为了奖励给对社区有益的工作提案,旨在成为社区促进创新的资金来源,以帮助发展生态系统。

二、WPS新提案流程

通过上面的介绍,我们大致了解了WPS是什么。那么在WPS中,我们又该如何将提案提交公众批准呢?(内心OS:其实我就是冲着瓜分4%的增发奖励去的)

具体流程是这样的:EOS持有者发起提案,上链,经由紧急事务委员会进行紧急事务标准评估,满足标准就进行社区投票。如果投票不通过,根据反馈意见重新修改提交,如果投票通过,则获得第一阶段的基金分配

需要提醒的是,这个流程中提到的紧急事务委员会,是属于第一阶段公投时候所产生的,所处理的事务为紧急类别的事务,目前紧急类别的事务包括:Github存储库管理、安全测试、Bug赏金计划以及WPS监督委员会。

三、WPS备受争议

从WPS的设计上看,它将激励社区开发人去提供有效和可拓展的改进所需的补丁和升级,使得EOS.IO能够满足社区不断变化的需求。它无疑将填补目前EOS社区治理的部分空白,对于EOS生态发展起着一定促进作用。

虽然WPS有着诸多优点,但我们注意到这样一个问题,即4%作为提案基金是不是太高了。EOS增发的4%,这可是一笔数额不菲的资金,WPS允许将这部分资金用于由社区批准的项目,如果使用得当固然是幸事一件;但如果没用好,对EOS系统就可能会是一场打击。因此,BM也于前几周在电报群中表达了对选民投票积极性以及对WPS正常运转的忧虑,认为应该取消。

虽然BM这一观点得到了一部分社区成员的认同,但我个人认为:WPS的存在是值得肯定和支持的,但4%这个比例有点高,可以改为一年0.5-1.5%的比例进行试验,然后在试验中进行调整优化。

另外,核心WPS工作组也于上周发布了声明,表示当前核心工作组正在努力构建一套工具和一套拟议的规则和指南,以实现WPS的设计目标。同时,他们将会在9月至10月,执行第一次公投。第一次公投将会决定是否同意将100万EOS通证从eosio.saving帐户转移到新帐户eosio.wps,用做第一阶段的基金,用于紧急事务。(更多内容可查看:https://bihu.com/article/1163451

而在第一阶段之后,将会逐渐替换掉紧急基金会,而且如下图所示,会有监管、社区、基础设施等更多其他类别的提案产生。

所以,现在对WPS盖棺定论还为时尚早,不如让WPS“再飞一会”,待第一次公投后再看它,说不定它会成长为EOS生态中的另一个奇迹。
转载自:https://www.jianshu.com/p/4ad8e49910a9

eosjs简明使用手册(最新版)

eosjs简明使用手册(最新版)

作者:古千峰 2018-7-15

以下教程用于EOS正式版,已在DEV开发链和EOS1.0.5-1.0.7版本的主链上测试通过。

官方文档因为版本的原因,内容多有错误,仅供参考。

eosjs的API与http-RPC调用一致,如rpc使用get-block,则在eosjs中使用getBlock()方法。即去横岗,首字符大写

eosjs几个容易出错的地方

  • asset类型,表达方式为字符串,如:100.0000 EOS,千万注意小数点后四位,少一位都不行
  • 与链连接时需要指定chainId,可以通过cleos get info获得

1- 安装eosjs

eosjs用于对交易签名、交易等操作。
eosjs-api用于读取链上数据,只读,如果只需要读取链上数据的话,只需要使用eosjs-api

在nodejs中安装:

npm install eosjs
npm install eosjs-api

注意nodejs需要最新版,如安装过程发生错误,请用node -vnpm -v查看版本。

2- 建立eosjs与链的连接

Eos = require('eosjs')

// Optional configuration..
config = {
  keyProvider: ['PrivateKeys...'], // 配置私钥字符串
  httpEndpoint: 'http://178.62.196.196:8888', //DEV开发链url与端口
  chainId: "0b08e71a2f8caaccc2dc13244b788f5eba29462ecd5d5dea1ad8cbe9581e885a", // 通过cleos get info可以获取chainId
  mockTransactions: () => null, // 如果要广播,需要设为null
  transactionHeaders: (expireInSeconds, callback) => {
    callback(null/*error*/, headers) //手动设置交易记录头,该方法中的callback回调函数每次交易都会被调用
  },
  expireInSeconds: 60,
  broadcast: true,
  debug: false,
  sign: true,
  authorization: null // 该参数用于在多签名情况下,识别签名帐号与权限,格式如:account@permission
}

eos = Eos(config)

3- 建立eosjs-api与链的连接

如果加载了eosjs后,默认加载eosjs-api,无需单独链接eosjs-api与链

EosApi = require('eosjs-api')

// everything is optional
options = {
  httpEndpoint: 'http://178.62.196.196:8888',
  verbose: false, // API logging
  logger: { // Default logging functions
    //log: config.verbose ? console.log : '',
    error: console.error
  },
  fetchConfiguration: {}
}

eos = EosApi(options)

4- 获取帮助

不添加如何参数,可以获取该方法的使用说明,如:

eos.getBlock()

5- 获取链上最新出块信息

eos.getInfo({}).then(result => { 
    console.log(result) 
})

返回:

{ server_version: 'b195012b',
  chain_id: '0b08e71a2f8caaccc2dc13244b788f5eba29462ecd5d5dea1ad8cbe9581e885a',
  head_block_num: 209307,
  last_irreversible_block_num: 209267,
  last_irreversible_block_id: '00033173a9ccd4bdd60a92d257e9354023b0457b134797be472a236cd908bc31',
  head_block_id: '0003319ba8ddc60d80c3cd0c7a70695cfd951f51ace9a798c913384cfbae659c',
  head_block_time: '2018-07-15T01:51:07.500',
  head_block_producer: 'eoshackathon',
  virtual_block_cpu_limit: 100000000,
  virtual_block_net_limit: 1048576000,
  block_cpu_limit: 99900,
  block_net_limit: 1048576 
}

如果需要拿到某一个数据值,比如:head_block_producer,则使用:

eos.getInfo({}).then(result => { 
    console.log(result.head_block_producer) //以对象属性方式获取head_block_producer
})

6- 获取指定区块信息

eos.getBlock(200000).then(result => { console.log(result) }) //获取第200000个区块

或者:

eos.getBlock({block_num_or_id: 200000}).then(result => { console.log(result) }) //获取第200000个区块

或者:

eos.getBlock('00030d4011a6744857533a6e6d907037a94c27a2dc006b4d28125f76bed2b355').then(result => { console.log(result) }) //根据id获取区块

或者:

eos.getBlock({block_num_or_id: '00030d4011a6744857533a6e6d907037a94c27a2dc006b4d28125f76bed2b355'}).then(result => { console.log(result) }) //根据id获取区块

或者将返回值传到回调函数callback中处理:

callback = (err, res) => { err ? console.error(err) : console.log(res) }
eos.getBlock(200000, callback)

7- 获取账户余额

eos.getCurrencyBalance({ code: "eosio.token", account: "eosio", symbol: "DEV" }).then(result => console.log(result))

以上命令相当于

cleos get currency balance eosio.token eosio DEV

8- 获取某代币的信息

eos.getCurrencyStats({code: "eosio.token", symbol: "DEV"}, callback) //用上面出现的callback,下同

9- 获取账户信息

eos.getAccount({account_name: "eoshackathon"}, callback) //获取eoshackathon账户的信息

相当于:

cleos get account eoshackathon

返回:

{ account_name: 'eoshackathon',
  head_block_num: 219997,
  head_block_time: '2018-07-15T03:20:12.500',
  privileged: false,
  last_code_update: '1970-01-01T00:00:00.000',
  created: '2018-07-13T20:54:28.000',
  ram_quota: 8148,
  net_weight: 500000,
  cpu_weight: 500000,
  net_limit: { used: 145, available: 120795486, max: 120795631 },
  cpu_limit: { used: 1511, available: 11518458, max: 11519969 },
  ram_usage: 3414,
  permissions:
   [ { perm_name: 'active', parent: 'owner', required_auth: [Object] },
     { perm_name: 'owner', parent: '', required_auth: [Object] } ],
  total_resources:
   { owner: 'eoshackathon',
     net_weight: '50.0000 DEV',
     cpu_weight: '50.0000 DEV',
     ram_bytes: 8148 },
  self_delegated_bandwidth: null,
  refund_request: null,
  voter_info: null 
}

10- 获取智能合约代码

eos.getCode({ account_name: "eosio"}, callback)

获取eosio账户的所有合约代码

11- 获取智能合约ABI

eos.getAbi({ account_name: "eosio"}, callback)

12- 获取Table行数据

不成熟

13- 获取账户的Actions列表

eos.getActions({account_name: "eoshackathon", pos: 0, offset: 15}, callback) //pos和offset是指:从第pos条记录开始获取offset条Actions

14- 获取公钥对应的账户

eos.getKeyAccounts({ public_key: 公钥字符串}, callback)

如果查找到帐号,则返回[],如果该公钥没有对应帐号,则报错。
相当于:

cleos get accounts 公钥

15- 获取主账号控制的其他帐号

eos.getControlledAccounts({ controlling_account: "eoshackathon"}, callback)

16- 获取transaction交易细节

该指令有bug,慎用!

eos.getTransaction({id: "xxxx"}, callback)

17- 转账交易

首先,在链接配置config中,keyProvider: [发送方私钥]
其次,可以设置options参数如下:

options = {
    authorization: '发送方帐号@active',
    broadcast: true,
    sign: true
}
方式1:
eos.transfer('发送方帐号', '接收方帐号', '0.3000 DEV','memo')

如果需要对返回值处理:

eos.transfer('发送方帐号', '接收方帐号', '0.3000 DEV','memo', callback)

如果有options参数,则:

eos.transfer('发送方帐号', '接收方帐号', '0.3000 DEV','memo', options, callback)
方式2:

使用对象:

eos.transfer({ from: '发送方帐号', to: '接收方帐号', quantity: '0.1000 DEV', memo: '备注', callback })

如果不想广播交易,可以使用以下简便指令:

eos.transfer('发送方帐号', '接收方帐号', '0.3000 DEV','memo', false) //在最后加上false,不广播
方式3:

使用eos.transaction,构造对象执行

eos.transaction(
    {
        // ...headers,
        actions: [
            {
                account: 'eosio.token',
                name: 'transfer',
                authorization: [{
                    actor: '发送方帐号',
                    permission: 'active'
                }],
                data: {
                    from: '发送方帐号',
                    to: '接收方帐号',
                    quantity: '0.3000 DEV',
                    memo: '备注'
                }
            }
        ]
    }
    // options -- example: {broadcast: false}
)

以上命令与以下cleos相同:

cleos push action eosio.token transfer '[ "发送方帐号", "接收方帐号",  "0.3000 DEV", "备注" ]' -p 发送方帐号

18- 新建帐号

creatoraccount = "testtesttest" //主账号
newaccount = "testtest1113" //新账号
newaccount_pubkey = "EOS5LUYdLZAd3uHF5XGAeE61aTeSXWqvqxBSUq3uhqYH7kY15Drjf" //新账号的公钥

//构建transaction对象
eos.transaction(tr => {
    //新建账号
    tr.newaccount({
        creator: creatoraccount,
        name: newaccount,
        owner: newaccount_pubkey,
        active: newaccount_pubkey
    })

    //为新账号充值RAM
    tr.buyrambytes({
        payer: creatoraccount,
        receiver: newaccount,
        bytes: 8192
    })

    //为新账号抵押CPU和NET资源
    tr.delegatebw({
        from: creatoraccount,
        receiver: newaccount,
        stake_net_quantity: '1.0000 DEV',
        stake_cpu_quantity: '1.0000 DEV',
        transfer: 0
    })
})

19- 购买RAM

creatoraccount = "testtesttest" //主账号
newaccount = "testtest1113" //新账号

eos.transaction(tr => {
    tr.buyrambytes({
        payer: creatoraccount,
        receiver: newaccount,
        bytes: 8192 
    })

或者

eos.transaction(tr => {
    tr.buyram({
        payer: creatoraccount,
        receiver: newaccount,
        quant: 8 //以k为单位的内存,8k=8192字节
    })

20- 出售RAM

eos.transaction(tr => {
    tr.sellram({
        account: 'testtesttest',
        bytes: 1024 //出售1k内存
    })
})

21- 竞拍账号名

eos.transaction(tr => {
    tr.bidname ({
        bidder: "testtesttest",
        newname: "竞拍的名字",
        bid: 价格
    })
})

22- 抵押CPU和NET

eos.transaction(tr => {
    tr.delegatebw({
        from: "testtesttest",
        receiver: "testtesttest", //testtesttest账户为自己抵押
        stake_net_quantity: "1.0000 DEV",
        stake_cpu_quantity: "1.0000 DEV",
        transfer: 0
    })
})

23- 取消抵押(赎回)CPU和NET

eos.transaction(tr => {
    tr.undelegatebw({
        from: "testtesttest",
        receiver: "testtesttest",
        unstake_net_quantity: "0.1000 DEV", //赎回0.1个DEV
        unstake_cpu_quantity: "0.1000 DEV"
    })
})

24- 智能合约部署

如果是加载wasm合约,不用使用binaryen,如果加载wast合约,需要安装并使用binaryen,如下:

npm install binaryen@39.0.0

并用以下方式导入到js

binaryen = require('binaryen')
eos = Eos({keyProvider, binaryen})
部署合约

以官方自带的hello合约为例

fs = require('fs')
wasm = fs.readFileSync(`contracts/hello/hello.wasm`) //这个文件在客户端上,而不是在服务器上
abi = fs.readFileSync(`contracts/hello/hello.abi`)

eos.setcode('contract_name', 0, 0, wasm) // contract_name 为合约名
eos.setabi('contract_name', JSON.parse(abi)) // @returns {Promise}

25- 智能合约的执行

方法一:
eos.contract("contract_name").then(hello => {  //hello随便起的变量名
    hello.hi('axay', {                         //hi是方法名, 'axay'是该hello合约hi方法的参数
        authorization: ['testtesttest']        //testtesttest是建立该合约的用户
    }).then(result => {
        console.log(result);
    });
});
方法二:
eos.transaction(
    {
        actions: [
            {
                account: 'contract_name',  //合约名
                name: 'hi',               //方法名,该方法在官方的hello合约中有
                authorization: [{
                    actor: 'testtesttest',
                    permission: 'active'
                }],
                data: {
                    user: 'axay'
                }
            }
        ]
    }
    // options -- example: {broadcast: false}
).then(result => console.log(result))

26- 通过eosjs发行一个代币

发行代币有两种方式,一种是通过cleos参考这里,但前提是必须要安装好EOS系统。
另一种方式是通过eosjs,无需在本机安装EOS系统。

注意:

此操作需要以eosio.token账户进行操作,因此需将eosio.token帐号的私钥导入到keyProvider数组中。但如果出于安全原因,不允许将eosio.token账户私钥加到程序中的话,则可以由发币的用户先部署eosio.token合约,然后再做接下去的操作。

第一步:创建代币

eos.transaction(
    {
        // ...headers,
        actions: [
            {
                account: 'eosio.token',       //合约名
                name: 'create',               //调用创建代币的方法
                authorization: [{
                    actor: 'eosio.token',     //必须是eosio.token
                    permission: 'active'
                }],
                data: {
                    issuer: 'testtesttest',   //代币发行方
                    maximum_supply: '10000.0000 AAA', //代币总量与名称
                    can_freeze: 0,
                    can_recall: 0,
                    can_whitelist: 0
                }
            }
        ]
    }
    // options -- example: {broadcast: false}
).then(result => console.log(result))

第二步:发行代币

eos.transaction(
    {
        // ...headers,
        actions: [
            {
                account: 'eosio.token',      //合约名
                name: 'issue',               //调用发行代币的方法
                authorization: [{
                    actor: 'testtesttest',   //必须是代币的发行方
                    permission: 'active'
                }],
                data: {
                    to: 'testtesttest',      //收到代币的帐号
                    quantity: '1000.0000 AAA',
                    memo: "testtesttest issue 1000 AAA"
                }
            }
        ]
    }
    // options -- example: {broadcast: false}
).then(result => console.log(result))

也可以将以上两步合在一起操作,如:

eos.transaction(
    {
        // ...headers,
        actions: [
            {
                account: 'eosio.token',  //合约
                name: 'create',               //方法
                authorization: [{
                    actor: 'eosio.token',
                    permission: 'active'
                }],
                data: {
                    issuer: 'testtesttest',
                    maximum_supply: '10000000.0000 GAT',
                    can_freeze: 0,
                    can_recall: 0,
                    can_whitelist: 0
                }
            },
            {
                account: 'eosio.token',  //合约
                name: 'issue',               //方法
                authorization: [{
                    actor: 'testtesttest',
                    permission: 'active'
                }],
                data: {
                    to: 'testtest1111',
                    quantity: '1000.0000 GAT',
                    memo: "testtesttest issue 1000 GAT to testtest1111"
                }
            }
        ]
    }
    // options -- example: {broadcast: false}
).then(result => console.log(result))

https://github.com/eoshackathon/eos_dapp_development_cn/edit/master/docs/eosjs_manual.md

EOS 智能合约最佳安全开发指南

EOS 智能合约最佳安全开发指南

这篇文档旨在为 EOS 智能合约开发人员提供一些智能合约的安全准则已知漏洞分析。我们邀请社区对该文档提出修改或完善建议,欢迎各种合并请求(Pull Request)。若有相关的文章或博客的发表,也请将其加入到参考文献中。

目录

安全准则

EOS 处于早期阶段并且有很强的实验性质。因此,随着新的 bug 和安全漏洞被发现,新的功能不断被开发出来,其面临的安全威胁也是不断变化的。这篇文章对于开发人员编写安全的智能合约来说只是个开始。

开发智能合约需要一个全新的工程思维,它不同于我们以往项目的开发。因为它犯错的代价是巨大的,很难像中心化类型的软件那样,打上补丁就可以弥补损失。就像直接给硬件编程或金融服务类软件开发,相比于 Web 开发和移动开发都有更大的挑战。因此,仅仅防范已知的漏洞是不够的,还需要学习新的开发理念:

  • 对可能的错误有所准备。任何有意义的智能合约或多或少都存在错误,因此你的代码必须能够正确的处理出现的 bug 和漏洞。需始终保证以下规则:
    • 当智能合约出现错误时,停止合约
    • 管理账户的资金风险,如限制(转账)速率、最大(转账)额度
    • 有效的途径来进行 bug 修复和功能提升
  • 谨慎发布智能合约。 尽量在正式发布智能合约之前发现并修复可能的 bug。
    • 对智能合约进行彻底的测试,并在任何新的攻击手法被发现后及时的测试(包括已经发布的合约)
    • 从 alpha 版本在麒麟测试网(CryptoKylin-Testnet)上发布开始便邀请专业安全审计机构进行审计,并提供漏洞赏金计划(Bug Bounty)
    • 阶段性发布,每个阶段都提供足够的测试
  • 保持智能合约的简洁。复杂会增加出错的风险。
    • 确保智能合约逻辑简洁
    • 确保合约和函数模块化
    • 使用已经被广泛使用的合约或工具(比如,不要自己写一个随机数生成器)
    • 条件允许的话,清晰明了比性能更重要
    • 只在你系统的去中心化部分使用区块链
  • 保持更新。通过公开资源来确保获取到最新的安全进展。
    • 在任何新的漏洞被发现时检查你的智能合约
    • 尽可能快的将使用到的库或者工具更新到最新
    • 使用最新的安全技术
  • 清楚区块链的特性。尽管你先前所拥有的编程经验同样适用于智能合约开发,但这里仍然有些陷阱你需要留意:
    • require_recipient(account_name name) 可触发通知,调用name合约中的同名函数,官方文档

已知漏洞

数值溢出

在进行算术运算时,未进行边界检查可能导致数值上下溢,引起智能合约用户资产受损。

漏洞示例

存在缺陷的代码:batchTransfer 批量转账

typedef struct acnts {
    account_name name0;
    account_name name1;
    account_name name2;
    account_name name3;
} account_names;

void transfer(symbol_name symbol, account_name from, account_names to, uint64_t balance)
{
    require_auth(from);
    account fromaccount;

    require_recipient(from);
    require_recipient(to.name0);
    require_recipient(to.name1);
    require_recipient(to.name2);
    require_recipient(to.name3);

    eosio_assert(is_balance_within_range(balance), "invalid balance");
    eosio_assert(balance > 0, "must transfer positive balance");

    uint64_t amount = balance * 4; //乘法溢出

    int itr = db_find_i64(_self, symbol, N(table), from);
    eosio_assert(itr >= 0, "Sub-- wrong name");
    db_get_i64(itr, &fromaccount, (account));
    eosio_assert(fromaccount.balance >= amount, "overdrawn balance");

    sub_balance(symbol, from, amount);

    add_balance(symbol, to.name0, balance);
    add_balance(symbol, to.name1, balance);
    add_balance(symbol, to.name2, balance);
    add_balance(symbol, to.name3, balance);
}

防御方法

尽可能使用 asset 结构体进行运算,而不是把 balance 提取出来进行运算。

真实案例

权限校验

在进行相关操作时,应严格判断函数入参和实际调用者是否一致,使用require_auth进行校验。

漏洞示例

存在缺陷的代码:transfer 转账

void token::transfer( account_name from,
                      account_name to,
                      asset        quantity,
                      string       memo )
{
    eosio_assert( from != to, "cannot transfer to self" );
    eosio_assert( is_account( to ), "to account does not exist");
    auto sym = quantity.symbol.name();
    stats statstable( _self, sym );
    const auto& st = statstable.get( sym );

    require_recipient( from );
    require_recipient( to );

    eosio_assert( quantity.is_valid(), "invalid quantity" );
    eosio_assert( quantity.amount > 0, "must transfer positive quantity" );
    eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
    eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" );

    auto payer = has_auth( to ) ? to : from;

    sub_balance( from, quantity );
    add_balance( to, quantity, payer );
}

防御方法

使用require_auth( from )校验资产转出账户与调用账户是否一致。

真实案例

暂无

apply 校验

在处理合约调用时,应确保每个 action 与 code 均满足关联要求。

漏洞示例

存在缺陷的代码:

// extend from EOSIO_ABI
#define EOSIO_ABI_EX( TYPE, MEMBERS ) \
extern "C" { \
   void apply( uint64_t receiver, uint64_t code, uint64_t action ) { \
      auto self = receiver; \
      if( action == N(onerror)) { \
         /* onerror is only valid if it is for the "eosio" code account and authorized by "eosio"'s "active permission */ \
         eosio_assert(code == N(eosio), "onerror action's are only valid from the \"eosio\" system account"); \
      } \
      if( code == self || code == N(eosio.token) || action == N(onerror) ) { \
         TYPE thiscontract( self ); \
         switch( action ) { \
            EOSIO_API( TYPE, MEMBERS ) \
         } \
         /* does not allow destructor of thiscontract to run: eosio_exit(0); */ \
      } \
   } \
}

EOSIO_ABI_EX(eosio::charity, (hi)(transfer))

防御方法

使用

if( ((code == self  && action != N(transfer) ) || (code == N(eosio.token) && action == N(transfer)) || action == N(onerror)) ) { }

绑定每个关键 action 与 code 是否满足要求,避免异常调用。

真实案例

参考文献

致谢

  • 麒麟工作组
  • eosiofans
  • 荆凯(EOS42)
  • 星魂
  • 岛娘
  • 赵余(EOSLaoMao)
  • 字符

EOS自动的延迟转账

transaction 里面有一个 delay_sec 的参数,默认是0,可以通过自定义实现延迟EOS转账。
具体代码可以查看 contracts/eosiolib/transaction.hpp
我们通过写一个新的合约,实现延时转账的 send 功能

void send(account_name from, account_name to, asset amount, string memo, uint64_t delay) {
    eosio::transaction t{};
    t.actions.emplace_back(
    eosio::permission_level(from, N(active)), // with `from@active` permission
    N(eosio.token), // You're sending this to `eosio.token`
    N(transfer),   // to their `transfer` action
    std::make_tuple(from, to, amount, memo));  // with the appropriate args
    t.delay_sec = delay; // Set the delay
    t.send(eosio::string_to_name(memo.c_str()), from); // Send the transaction with some ID derived from the memo
    }
};

最后需要记得对发送者账户进行权限设置,让该合约有权限进行转账操作。

$ cleos set account permission <sender-account> active '{"threshold": 1,"keys": [{"key": "<sender-pubkey>","weight": 1}],"accounts": [{"permission":{"actor":"<contract-account>","permission":"eosio.code"},"weight":1}]}' owner -p <sender-account>

参考:https://eosio.stackexchange.com/questions/1900/how-to-transfer-eos-after-a-particular-delay
转自:http://blog.eosdata.io/index.php/2018/08/16/ru-he-jin-xing-zi-dong-de-yan-chieos-zhuan-zhang/

EOS核心仲裁庭收费标准

EOS核心仲裁庭费用表

本费用表适用于在EOS核心仲裁庭(ECAF)的争议解决机制(RDR)之下进行的仲裁,详情请参见此处https://eoscorearbitration.io/home/governance/
本费用表将会不定期的修订。ECAF的费用将以EOS的形式收取。如果需要从法币转换为EOS,操作过程在本备忘录末尾的货币转换部分做了详细说明。
该收费制度分为两部分,如下:
1.不可退还的诉讼费:在提交案件时支付。
2.仲裁费用:在案件结案时支付,用于补偿仲裁员、案件管理员、仲裁庭工作人员、外部专家等在案件上花费的时间成本。

注:费用与仲裁员针对潜在的判决可能要求当事人作为担保缴纳的任何保证金是分开的。
诉讼费:
当提交仲裁申请时,申请人应支付不可退还的诉讼费,该费用取决于索赔金额,具体如下:

仲裁费用

根据RDR第5.9节https://eoscorearbitration.io/home/governance/ :当仲裁程序开始,仲裁员将在切实可行的范围内尽快的提交一份仲裁费用的估算。
该仲裁费用将固定使用在仲裁上并且将被支付到本法庭账户。
这样的花费可能包括:
1、仲裁员的报酬;
2、仲裁员的花费;
3、专家和翻译的成本;
4、其它与本法庭审理该案件相关的报酬和花费;
5、当事人引发的合理的法律费用和其它花费;
6、由于消极的行动或行为被仲裁员征收的罚金;
7、任何与临时或者紧急救济通知有关的费用;
8、任何与请求合并仲裁有关的费用;
仲裁费用应参照仲裁庭成员的工作量计算。费率将取决于案件的具体情况,包括其复杂性和仲裁员可能具有的任何特殊资质。
费用将按小时收取,如下文(数字以美元报价,但以EOS收取,见后文关于货币兑换的部分)。适用的费率将取决于经验水平和本人对问题的专业程度。

保证金

仲裁员可指示当事人按其认为适当的比例和时间提交两种类型的保证金:

1.仲裁费用的预付款。根据ECAF规则,此类由当事人预付的保证金可以由ECAF用来支付任何此类仲裁费用(包括ECAF自己的费用和开支)。
2.占争议总金额一定百分比的保证金,作为对潜在判决的担保。

如果一方当事人未能或者拒绝支付任何款项到仲裁员指示的仲裁费用的账号,仲裁员可指示另一方或多方代为支付以允许仲裁继续进行(基于任何针对仲裁费用的仲裁令或裁定)。在这种情况下,代为付款的一方可以要求仲裁员给出一个命令或裁决,以便将该金额作为违约方的一笔立即到期债务和应付账款,来进行收回。

一方当事人申请紧急救济时,除了支付不可退还的诉讼费之外,还应支付相当于750美元的EOS的保证金(见后文关于货币兑换的说明)作为紧急救济程序的预付费用。如果没有同时支付诉讼费和保证金,ECAF将不会以紧急救济程序进行处理。

临时付款

随着仲裁程序的进行,由ECAF和仲裁员批准,部分保证金可能会不时地被释放,以覆盖仲裁费用的任何部分。

如果在需要临时付款时没有或欠缺资金,付款通知可以被提交给当事人直接进行付款。

支付方式

ECAF只会要求您将资金转入以下两个账户之一:

  • ecafeewallet
  • ecafescrowww

警告:不要将资金转移到任何其他帐户!任何向其他EOS帐户或交易所帐户付款的请求都是欺诈性请求! ECAF不会对转入其它账户的资金承担责任。

诉讼费的收取

申请人将通过ECAF官方网址的诉讼提交页面提起一个诉讼:https://eoscorearbitration.io/file-a-claim/
ECAF的案例经理随后将审核该诉讼。一旦案件经理确信不需要其他补充信息,他们将联系申请人提交诉讼费并附上适当的备注到以下地址:
Ecafeewallet
一旦成功收到诉讼费,该案件将被标记为已被仲裁庭接受,并等待分配给具体的一个仲裁员。

保证金的收取

当仲裁员被分配到一个案件时,他们将对仲裁费用进行初步估计。 (该估计将在结案时最终确定。)
仲裁员可以随后指示案件管理员将本案件的这些费用通知当事人。仲裁员还将确定是否需要要求一笔保证金来覆盖部分仲裁费用以及作为争议金额的保证金。
保证金将由案件经理负责征收,并将存入ECAF的托管账户,同时附有将提供给当事人的备注。保证金必须只能发送到以下这个账户:
Ecafescrowww

货币兑换

金额必须以EOS的形式支付。
如果任何到期金额没有以EOS为单位报价,则应按保证金和/或裁定的付款通知发出之日前一天的兑换率进行兑换。
EOS转换为美元使用的利率引用自CoinMarketCap https://coinmarketcap.com/currencies/eos/historical-data/ 在指定日期的收盘价。
如果该金额以美元以外的法定货币表示,则该金额应首先使用引用自OandA https://www.oanda.com/lang/cns/currency/converter/ 的在指定日期的平均卖出价,来转换为美元。然后再将其转换为如上所述的EOS单位。

请注意: 本文由EMAC(EOS 华语治理社区)仲裁候选人Achilles原创翻译,保留该声明即可转载。
原文来源:https://steemit.com/ecaf/@ecaf/ecaf-s-fee-schedule